Ola mensen,

Stel we hebben deze class:

<?php
class Foo {

private $data = array();

public function getData {
return $this->data;
}

public function has($key) {
return array_key_exists($key, $this->data);
}

}
?>

Nu gaat het om de functie has();

In het bovenstaande voorbeeld spreekt deze functie rechtstreeks de private property $data aan.

Nu weet ik dat sommigen (waaronder Wouter) het zo op zouden lossen:

<?php
class Foo {

private $data;

public function getData {
return $this->data;
}

public function has($key) {
return array_key_exists($key, $this->getData());
}

}
?>

Wouter werkt met een heel strict "GET" beleid zoals hij zelf zegt. Alleen de "get()" methods mogen private properties aanspreken. Nu vraag ik me af of daar een reden voor is?

En hoe doen de anderen, buiten Wouter, dit? Gebruiken jullie ook overal een "get()" functie voor, of mag iedere method in een class de private properties aanspreken?

Wat zijn voordelen, wat zijn nadelen?

Wat ik zelf kan bedenken:
- alles via een get() method
voordeel: je weet zeker dat alleen de get() method de private property kan uitlezen
nadelen: 1) je roept telkens onnodig een extra method aan 2) meerdere functies worden afhankelijk van de get() method. Als de get() method wordt gewijzigd (bijv. qua naam) dan werken de method die van de get() method afhankelijk zijn niet meer. Ik zou denken dat daardoor je systeem "kwetsbaarder" wordt.
- rechtstreeks een private property aanspreken
nadeel: ook niet-get() methods kunnen private properties aanspreken (maar is dat erg?)
voordelen: er hoeven geen extra get() methods te worden aangeroepen (beter voor performance) en iedere functie die een private property moet uitlezen werkt op zichzelf en is dus niet afhankelijk van een get() method.

Ik ben benieuwd naar hoe jullie het doen en naar jullie argumenten.
Ik denk dat ik het ook zoals Wouter zou doen.. een private property direct aanroepen zou ik sowieso niet doen omdat dit gewoon niet netjes oogt naar mijn mening.

En hoezo zou je de naam van de get() methode zomaar veranderen? ik bedoel je hebt het toch wel uitgedacht voor dat je deze gaat bouwen... ik denk dat het systeem juist kwetsbaarder wordt als zomaar jan en alleman erbij kan.
"ik denk dat het systeem juist kwetsbaarder wordt als zomaar jan en alleman erbij kan."

Dit kan dus juist niet, want alleen methods in dezelfde class kunnen bij een private property, dus niet jan en alleman.

Mij lijkt het juist dat je systeem kwetsbaarder wordt als je (onnodige) verantwoordelijkheden tussen functies creëert, waardoor die functies altijd afhankelijk zijn van een andere functie.

Dank voor je reactie en ben benieuwd of meer mensen hier een mening over hebben.
Maar wat doe je nou als je vanuit een andere klasse de variabele nodig hebt? dan kan je er natuurlijk niet bij.. Ik heb laatst op school een hele mooie term geleerd wat hier mee o.a. te maken heeft namelijk Encapsulation. in gewoon Nederlands zou je dit uitleggen als

"Je kan hiermee d.m.v. een regel code informatie uit een andere klasse halen maar deze niet bewerken/veranderen."

En wanneer je i.p.v. de getters en setters besluit om de property direct aan te roepen breek je deze principe.

een voorbeeldje van encapsulation ff snel van internet geplukt:

<?php

class App {
private static $_user;

public function User( ) {
if( $this->_user == null ) {
$this->_user = new User();
}
return $this->_user;
}

}

class User {
private $_name;

public function __construct() {
$this->_name = "Visitor";
}

public function GetName() {
return $this->_name;
}
}

$app = new App();

echo $app->User()->GetName();

?>
Maar dat begrijp ik wel Reshad. Ik zeg ook niet dat je de get functie moet weggooien? Die heb je nodig om van buiten de class een property aan te spreken. Maar ik bedoel in de class zelf! Als een functie in de class zelf een property nodig heeft, dan zou ik die direct aanspreken, maar Wouter zou hiervoor de get() functie in diezelfde class gebruiken. Snap je?
Ik moet zeggen dat ik binnen een class niet zo strict ben als Wouter, maar op zich de gedachte erachter wel ondersteun. De reden om altijd alleen maar private properties te hebben is dat je op die manier de implementatie van een functionaliteit binnen een class open laat. Omdat de properties van buiten niet direct kunnen worden aangeroepen, ben je vrij om op enig moment bepaalde wijzigingen door te voeren. Je kan properties weghalen, toevoegen, opsplitsen, extra checks toevoegen etc. Omdat alle get en set operaties via getters en setters lopen zal dit nooit problemen opleveren voor andere classes.

Nu, dezelfde gedachtegang kan je doorvoeren naar de situatie binnen een class. Als al je methodes binnen de class ook alleen maar via getters en setters werken, dan hoef je je dus ook nooit zorgen te maken over wat er binnen de class gebeurt. Verander je de properties, dan hoef je alleen de getter en setter aan te passen en je weet weer zeker dat alles zonder problemen zal werken.
Erwin thanks voor je reactie. Ik ben het volkomen met je eens dat je alleen maar private properties moet gebruiken. Dus in jouw 1e alinea kan ik me volledig vinden.

Wat betreft jouw 2e alinea. Ik ben het er wederom mee eens dat alleen set() functies een private property mogen setten/wijzigen. Alleen vraag ik me af of het slim is dat overige functies die een private property willen uitlezen dit per se via de get() method moeten doen. Wat jij zegt, dat als je een property wijzigt je alleen de get functie hoeft te wijzigen klopt. Dat kan een voordeel zijn. De andere kant van het verhaal is dat alle overige functies afhankelijk worden van de get functie en er bovendien telkens een extra functie aanroep moet plaatsvinden. Weegt dit wel op tegen het voordeel vraag ik me af? Dat is dus een beetje waar ik over zit te twijfelen...
Het punt wat je voorlegt is precies waar het om gaat. In mijn ogen zou de vraag kunnen zijn: welk code blok wil je autonoom kunnen laten werken in een OOP omgeving? Is dat een class, of is dat een function?
Ik heb voor mezelf bepaald dat een class autonoom moet zijn. Elke class is verantwoordelijk voor zijn eigen handel en wandel en moet ervoor zorgen dat input correct is en output correct is. Binnen de class echter mogen er wat mij betreft afhankelijkheden zijn en mag er wat makkelijk worden omgegaan met properties en data.

Het is dus een keuze, performance kan je daarin mee laten wegen.
Ozzie ik denk dat dit heel erg afhangt van hoe je zelf het liefst werkt. Ik denk ook dat het enige voordeel dat je eruit kan halen is dat als er iets veranderd je dit maar op 1 plek hoeft aan te passen. Het telkens aanroepen van een extra functie gaat je applicatie ook niet trager maken.

Ik zou dus gewoon doen wat jijzelf het prettigste vind werken, maar wel rekening houden dat je met de get() tijd kunt besparen als je iets moet wijzigen in de properties.
Goed verhaal Erwin, en duidelijk uitgelegd. Zet mij ook weer even aan het denken.
Ben toch even benieuwd dan... zomaar een voorbeeldje. Wat zou jouw voorkeur hebben? De 1e of de 2e versie. En waarom?

<?php
class Foo {

private $data = array();

public function getData() {
return $this->data;
}

public function has($key) {
return array_key_exists($key, $this->data);
}

public function getKeys() {
return array_keys($this->data);
}

public function count() {
return count($this->data);
}

}
?>

of

<?php
class Foo {

private $data = array();

public function getData() {
return $this->data;
}

public function has($key) {
return array_key_exists($key, $this->getData());
}

public function getKeys() {
return array_keys($this->getData());
}

public function count() {
return count($this->getData());
}

}
?>

[size=xsmall]Toevoeging op 12/02/2013 09:36:14:[/size]

@Rick: thanks voor je reactie!
Ik zou de eerste doen. Omdat volgens mijn keuze de afhankelijkheid binnen de class geen probleem is. Daarbij neem ik dus voor lief dat het aanpassen van het property (mocht ik dat ooit willen doen) mij extra werk op zal leveren zoals Rick ook zegt. Dat weet ik, maar dat accepteer ik.

Reageren