verantwoordelijkheid get
Ola mensen,
Stel we hebben deze class:
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:
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.
Stel we hebben deze class:
Code (php)
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:
Code (php)
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.
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.
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:
"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:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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();
?>
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.
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...
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.
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.
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?
of
Toevoeging op 12/02/2013 09:36:14:
@Rick: thanks voor je reactie!
Ben toch even benieuwd dan... zomaar een voorbeeldje. Wat zou jouw voorkeur hebben? De 1e of de 2e versie. En waarom?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
of
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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());
}
}
?>
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());
}
}
?>
Toevoeging op 12/02/2013 09:36:14:
@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.
Ah oké, maar dit lijkt een beetje in tegenstelling te zijn met wat je eerder zei toch?
Erwin H op 12/02/2013 09:09:19:
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.
Nee, het ene is een feit, het andere is een keuze. Ik heb in mijn eerdere post ook dit gezegd:
Zoals de grote php guru Cruyff ooit al eens zei: "Elk voordeel heb z'n nadeel".
Erwin H op 12/02/2013 09:09:19:
Ik moet zeggen dat ik binnen een class niet zo strict ben als Wouter
Zoals de grote php guru Cruyff ooit al eens zei: "Elk voordeel heb z'n nadeel".
Haha, oké... thanks voor het meedenken. Heb weer even wat om over na te denken ;)
Dan moet ik ook nog maar even reageren, al verwoord Erwin mijn verhaal al voor het grootste deel (hoe kan het ook anders, hij is de gene die me hier over heeft laten nadenken).
Ik vind dit (het feit dat je systeem "kwetsbaarder") een beetje een non-argument. Je kan zeggen dat ze afhankelijk worden van de get method, maar je kan ook zeggen dat ze afhankelijk worden van de property en dat als je die een andere naam geeft, dan werken alle functies die afhankelijk zijn van die property ook niet meer. Het systeem is dus even kwetsbaar.
Ik zou zelfs, heel stiekem, durven te beweren dat mijn methode juist een stapje minder kwetsbaar is. Stel we hebben een User klasse:
Nu gebruikt Henk ons User systeem voor een restaurant, om simpel te checken of iemand alcohol mag drinken of niet:
Nu zijn we wat maandjes verder en dan kom je erachter dat het helemaal niet slim is om de leeftijd van iemand op te slaan, maar dat het slimmer is om de geboortedatum op te slaan. Dus we passen de User klasse aan.
Nu zit Henk met een probleem, zijn code werkt niet meer. In het geval van het direct aanroepen van de properties zal je nu met een probleem zitten. Met getters niet: Wat jij doet is een backwards comptability break voorkomen door de getter te behouden:
Nu zou het script van Henk niet gestoord worden, terwijl de $age property wel is verdwenen van de User klasse. Nog beter zou het zijn om dan in deze getter een deprecation te loggen, zodat Henk door krijgt dat hij een verouderde functie gebruikt. Hij zal dan zijn script gaan aanpassen en in een versie na de gene waarin je de $age hebt veranderd in $birthday zal je de hele getAge functie kunnen verwijderen.
Dit wordt heel veel gedaan in grote open-source projecten. Je kan nooit alles in 1 keer goed scripten, maar het is wel de bedoeling dat je dat zo goed mogelijk doet. Anders kun je andere mensen met problemen van jou complete rewrite van je project. Mocht je alsnog wat dingen veranderen, dan kun je met getters en setters even een tijdelijke oplossing maken zodat je later alles veilig kunt veranderen.
Ozzie PHP:
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.
Ik vind dit (het feit dat je systeem "kwetsbaarder") een beetje een non-argument. Je kan zeggen dat ze afhankelijk worden van de get method, maar je kan ook zeggen dat ze afhankelijk worden van de property en dat als je die een andere naam geeft, dan werken alle functies die afhankelijk zijn van die property ook niet meer. Het systeem is dus even kwetsbaar.
Ik zou zelfs, heel stiekem, durven te beweren dat mijn methode juist een stapje minder kwetsbaar is. Stel we hebben een User klasse:
Code (php)
Nu gebruikt Henk ons User systeem voor een restaurant, om simpel te checken of iemand alcohol mag drinken of niet:
Code (php)
Nu zijn we wat maandjes verder en dan kom je erachter dat het helemaal niet slim is om de leeftijd van iemand op te slaan, maar dat het slimmer is om de geboortedatum op te slaan. Dus we passen de User klasse aan.
Nu zit Henk met een probleem, zijn code werkt niet meer. In het geval van het direct aanroepen van de properties zal je nu met een probleem zitten. Met getters niet: Wat jij doet is een backwards comptability break voorkomen door de getter te behouden:
Code (php)
Nu zou het script van Henk niet gestoord worden, terwijl de $age property wel is verdwenen van de User klasse. Nog beter zou het zijn om dan in deze getter een deprecation te loggen, zodat Henk door krijgt dat hij een verouderde functie gebruikt. Hij zal dan zijn script gaan aanpassen en in een versie na de gene waarin je de $age hebt veranderd in $birthday zal je de hele getAge functie kunnen verwijderen.
Dit wordt heel veel gedaan in grote open-source projecten. Je kan nooit alles in 1 keer goed scripten, maar het is wel de bedoeling dat je dat zo goed mogelijk doet. Anders kun je andere mensen met problemen van jou complete rewrite van je project. Mocht je alsnog wat dingen veranderen, dan kun je met getters en setters even een tijdelijke oplossing maken zodat je later alles veilig kunt veranderen.
Gewijzigd op 12/02/2013 17:26:23 door Wouter J
Thanks Wouter daar zit ook weer wat in. En wat je zegt over de afhankelijkheid van properties vs methods... tja, da's ook wel weer waar. Misschien ga ik dan toch ook maar over op het gebruik van get() functies binnen de class :-/
Pffff, die keuzes ook altijd ;)
Pffff, die keuzes ook altijd ;)




