Archief - [PROG] Gebruik van getters en setters

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

passero

Legacy Member
IK maak me zopas een bedenking over het gebruik van getters en setters binnen een OO taal.
IK heb altijd geleerd dat je die moet gebruiken om de variabelen af te schermen en om in die getters en setters logica te schrijven om uw data consistent te houden zoals controle of uw data binnen een bereik valt, of de data niet leeg is,...

Als ik een object maak, maak ik elke var automatisch private en schrijf ik er automatisch een getter en setter voor. Meestal doen die niets meer dan de waarde binnen het object opvullen of teruggeven. Weinig logica dus :)
Ik krijg dan soms de opmerking van mensen die mijn code lezen "waarom al die code, zet die toch gewoon public". Ik weiger dat altijd te doen want soms moet er dan wel logica inkomen en dan pas ik gewoon mijn methode aan en het is opgelost, heel weinig werk dus. Maar als je die var eerst public hebt gezet, dan moet je het gehele project overlopen en aanpassen waar nodig... niet echt handig.
Ook is het niet echt volgens de regels van OOP om variabelen public te zetten.

Ik merk ook dat grotere projecten of bekende projecten dit niet toepassen zoals het moet. Zo heb ik me de opmerking gemaakt bij de FCKEditor. ALs je daar een instantie van maakt en je wil het basePath instellen moet je gewoon:
$editor->basePath = ... doen ivp $editor->setBasePath($path) terwijl ik het logisch zou vinden om hier een setter te gebruiken omdat er toch een controle moet zijn of het path bestaat.

Ligt dat nu aan mij, dat ik teveel de regel wil toepassen of ligt het aan de andere mensen? :s

killgore

Legacy Member
Het ligt zeker niet aan u, in het grootste deel van de hl2 api (om iets anders groots op te noemen) werkt men ook met get/set en zelden met directe toegang (er zijn er wel enkele dacht ik).
Persoonlijk ga ik nooit een var public maken en zelfs maar protected als het echt nodig is :).
Maar je gaf (denk ik) een php voorbeeld, met alle respect, maar zelfs in de "geadvanceerdere" groep daarvan zitten nog steeds mensen die niet oop kunnen werken, voornamelijk omdat ze terugvallen op php4, waar data protection nog niet bestond ;) en anderen vallen dan weer terug op sommige gewoonweg ridicule oop toevoegingen van php zelf en nog anderen overdrijven in hun oop gebruik voor php omdat het cool & nieuw is.

Daarnaast: wat doet het ertoe of je "al" die code schrijft voor get en set? Alsof dat uren extra in beslag neemt, met de juiste macros laat je die automatisch & inline toevoegen.

passero

Legacy Member
aja das juist macro's :) Damn en ik schrijf die allemaal zelf :)
Wordt dringend tijd dat ik eens de doc raadpleeg van mijn IDE's :)

Ik gaf idd het voorbeeld van een PHP bib maar bij ons op het werk merk ik het ook. Daar werkten we vooral met asp.net en de acces layer is een gewone bibliotheek die we geschreven hebben ipv met properties te werken, wertken ze daar ook altijd met public.
Nu ja, de achtergrond kennende van de programmeurs liggen dan ook meestal bij procedurele talen en dan is het misschien begrijpelijk...

jodeman

Legacy Member
passero zei:
Ligt dat nu aan mij, dat ik teveel de regel wil toepassen of ligt het aan de andere mensen? :s

Het ligt aan de andere mensen ;). Data protection in een game is niet zo belangrijk maar het is een goede gewoonte.
In een bank kan het al wat meer schade aanrichten :).

killgore

Legacy Member
Persoonlijk vind ik dat niet begrijpelijk, ik heb eerst een hele tijd met C++ zonder oop (= +/- C, niet volledig!) liggen prutsen en lang onder php4, wat je ook amper als oop taal kan aanschouwen.
Toch code ik mijn oop code zoals het hoort.

Luiheid om iets nieuws aan te leren is niet begrijpelijk ;)!

En in een game is dataprotection van klasses juist wel uitermate belangerijk jodeman, een var public maken is juist een van de gevaarlijkste dingen die je kan doen en zal meer dan eens tot een bug leiden.
Stel jij maakt een vector hebt in je klasse en je maakt die public ipv een setter met logica. Je gaat er vanuit dat hier enkel "gewone" vectoren inkomen en dit zou ook zo moeten zijn.
Jij code je klasse zeer goed, maar normaliseert ergens.
En dan komt het probleem he, via 1 of andere procedure wordt per ongeluk een nul-vector ingelezen (bv een resource file waar dit ergens inzit die wordt ingelezen), jij zit te spelen, ineens divide-by-zero error.

Je kon natuurlijk controle doen voor het normaliseren, nog beter echter was dit enkel via setter toegangkelijk maken waardoor de vector nooit een nul-vector kan zijn.

Vich

Legacy Member
passero zei:
[...]
Als ik een object maak, maak ik elke var automatisch private en schrijf ik er automatisch een getter en setter voor. Meestal doen die niets meer dan de waarde binnen het object opvullen of teruggeven. Weinig logica dus :)
Ik krijg dan soms de opmerking van mensen die mijn code lezen "waarom al die code, zet die toch gewoon public".
Waarom zou je voor elke var een getter en setter schrijven? Binnenin de klasse heb je die toch niet nodig? Waarom zou je extra werk doen voor iets wat je tóch niet nodig hebt?
Ik weiger dat altijd te doen want soms moet er dan wel logica inkomen en dan pas ik gewoon mijn methode aan en het is opgelost, heel weinig werk dus. Maar als je die var eerst public hebt gezet, dan moet je het gehele project overlopen en aanpassen waar nodig... niet echt handig.
Ook is het niet echt volgens de regels van OOP om variabelen public te zetten.
"Heel weinig werk dus" schrijf je ... ok, maar daar gaat wel aan vooraf dat je eerst álle variabelen een getter en setter geeft, dat is veel werk en meestal dus onnodig, omdat er meestal geen logica vereist is.
"Heel je project overlopen" is ook niet nodig, je kan gewoon "search and replace" doen over je project ;) En zowiezo is het enkel in de basisklasse en hooguit ook in zijn afgeleide klassen gebruikt, zoveel werk is dat niet. Natuurlijk kan je wel een setter/getter geven die enkel beschikbaar is voor de hoofdklassen en afgeleide klassen van zodra een member beschikbaar moet zijn voor afgeleide klassen. Dat wil natuurlijk niet zeggen dat je gewoon overal een getter en setter voor moet maken.

Een paar praktische redenen om dit niet te doen:
- geheugengebruik (alhoewel dit relatief gezien wel meevalt, kan het in grotere projecten wel een probleem zijn)
- wordt niet altijd ge-inlined, dus trager
- code wordt minder overzichtelijk(al die getters&setters kunnen heel wat extra regeltjes code geven in je klasse-declaratie)
- extra werk (tijd = geld)

Ik merk ook dat grotere projecten of bekende projecten dit niet toepassen zoals het moet. Zo heb ik me de opmerking gemaakt bij de FCKEditor. ALs je daar een instantie van maakt en je wil het basePath instellen moet je gewoon:
$editor->basePath = ... doen ivp $editor->setBasePath($path) terwijl ik het logisch zou vinden om hier een setter te gebruiken omdat er toch een controle moet zijn of het path bestaat.
Ik ga akkoord dat het beter is met een getter of setter, maar het feit dat dit niet gebeurt kan een goede reden hebben. Bijvoorbeeld als die klasse verwacht dat jij zélf controle uitvoert op het pad, omdat je dan platform-onafhankelijk een pad kan meegeven. Zo hoeft die klasse niet voor alle platformen een pad-controle uit te voeren.

killgore

Legacy Member
Ik denk dat hij nu wel getters en setters bedoelde voor variabelen die van buitenaf moeten kunnen aangesproken worden, intern via get en set werken zou idd maar wat ridicuul zijn :p.

Deguchi

Legacy Member
Vich zei:
"Heel je project overlopen" is ook niet nodig, je kan gewoon "search and replace" doen over je project ;)


Een paar praktische redenen om dit niet te doen:
- geheugengebruik (alhoewel dit relatief gezien wel meevalt, kan het in grotere projecten wel een probleem zijn)
- wordt niet altijd ge-inlined, dus trager
- code wordt minder overzichtelijk(al die getters&setters kunnen heel wat extra regeltjes code geven in je klasse-declaratie)
- extra werk (tijd = geld)

Search & replace werkt niet in elk geval ;) De getter/setter aanpassen wel.

Zoals hierboven al ergens werd gezegd. Laat het genereren door een macro. Dan is het (meestal) ook inline en neemt bijna geen extra tijd in beslag. En met sommige ide's is het mogelijk om bepaalde delen van de code te minimaliseren, waardoor de code toch weer leesbaar wordt ;)
Ik zou het gebruik van getters/setters dus zeker aanraden. Het bespaard u op termijn veel werk en mogelijke miserie! ;)

jodeman

Legacy Member
OOP is nu eenmaal gewoon uitwisselen van berichten via getters en setters tussen objecten, zal zo wel zijn redenen hebben zeker ;). En getters en setters schrijven is toch niet zoveel werk, in java eclipse ide is gewoon aanduiden welke setter of getter ge wil zetten.

@killgore : true, maar een game dat crasht is net iets minder erg dan een bankrekening dat leeggehaald wordt he :). Dat bedoelde ik.

den Acid Burn

Legacy Member
een van de belangrijkste pijlers van OOP is encapsulation.
als ge alles gewoon maar public maakt gaat ge radicaal in tegen dit principe van encapsulation.

het is dus een goed idee om zoveel mogeljk private te maken en via getters en setters te werken.

passero

Legacy Member
Ik bedoelde inderdaad de variabelen die anderen public maken :)
Variabelen die enkel intern gebruikt worden binnen de eigen klasse, daar schrijf ik natuurlijk geen getter en setter voor.

@Vinch tijd = geld...

Daar zijn heel veel bazen te kortzichtig over als het op OO aankomt.
Een nieuw project moet snel snel geleverd worden, minder tijd drukt de prijs dus is goed MAAR als je meer tijd neemt in een deftige sturctuur en deftig ontwerp en later moet er een module bijkomen dan pas haal je heel veel profeit uit het meerwerk van in het begin en blijkbaar vergeten de mensen dit snel... wat ik dus heel spijtig vind. Hoeveel uren dat ik al niet ben verloren door code die copy paste is gedaan en hier en daar een beetje aangepast. Met een beetje deftige OO zou dit op 5 min opgelost zijn om iets aan te passen of bij te schrijven.

Ik vind het heel jammer dat we in het begin geen tijd krijgen voor een deftige analyse of ontwerp omdat ze zogezegd denken dat dit niets opbrengt. Maar eigenlijk in de toekomst zal het wel opbrengen.

killgore

Legacy Member
jodeman zei:
@killgore : true, maar een game dat crasht is net iets minder erg dan een bankrekening dat leeggehaald wordt he :). Dat bedoelde ik.
Mja, data protection op die manier heeft minder te maken met wat jij als vb geeft ;).
Data protection van klasse-variabelen wijst op de stabiliteit van je code, niet noodzakelijk op de kwetsbaarheid van je code, natuurlijk speelt het daar ook een rol in, het vb. dat ik hierboven gaf ivm vectors die uitgelezen worden uit resource files kan analoog gebruikt worden in viri, bekijk de fameuze image-viri maar eens.
Het is echter in de eerste plaats van belang voor de stabiliteit van je code en het algemene begrip van code opdelen in allerlei kleine sub-problemen waarvoor juist OOP gemaakt is (omdat projecten te groot werden om te onderhouden).
Als jij weet dat er met een variabele iets mis is en enkel die klasse kan eraan dan weet je dat je enkel die klasse moet debuggen en eventueel moet gaan kijken naar foute evaluaties. Is dat echter een public -> hf.

edit: vind het wel grappig over die "geen tijd voor analyse". Bij alle info die ik krijg voor computerwetenschappen staat er dat een computerwetenschapper in de eerste plaats een softwareONTWERPER is (dus analytisch), het programmeren is iets bijkomstig :p.

Tyfius

Legacy Member
Dat zijn verkoopspraatjes.
Waar ik mijn stage gedaan heb, hebben ze voor bepaalde projecten ook een aantal analysen gemaakt, compleet volgens de UML2.0 regels. Maar de klant wil zijn product morgen en niet overmorgen, dus de rap rap schets is sneller en even duidelijk voor de mensen die eraan werken.

jodeman

Legacy Member
lol, je geeft zelf het voorbeeld dat half life 2 vooral met public variabelen is geprogrammeerd. Als ik nu publieke variabelen oproep dan kan ik toch nog altijd checken of een vector leeg is of niet en geen error krijgen. Kzeg niet dat dat goed is maar ge kunt dat toch opvangen. In een game is dat niet belangerijk als ge het ergens anders opvangt.
Data protection is wel dat uw data van uw object correct is en dat niet elk ander object dat zomaar kan aanpassen. De methodes kunt ge toch op elke manier dat ge wilt implementeren. Een vector kijken of dat die leeg is is coderen, een juiste waarde in een variabele is juiste data hebben in uw object.

Vich

Legacy Member
Deguchi zei:
Search & replace werkt niet in elk geval ;) De getter/setter aanpassen wel.

Zoals hierboven al ergens werd gezegd. Laat het genereren door een macro.
Je kan dat niet door 1 macro laten genereren, simpelweg omdat getters van objecten niet altijd hetzelfde zijn als getters voor basistypes. Je wil bvb soms een getter naar een pointer, soms naar constante pointer, soms references en soms het hele object. Een getter voor álles is gewoon 1 grote design flaw van het programma. Wat doe je bijvoorbeeld als je dan een getter naar constante pointer public wil maken en een getter naar een gewone pointer private?

Deguchi zei:
Dan is het (meestal) ook inline en neemt bijna geen extra tijd in beslag. En met sommige ide's is het mogelijk om bepaalde delen van de code te minimaliseren, waardoor de code toch weer leesbaar wordt ;)
"Meestal" is niet altijd en in sommige gevallen wil je gewoon géén extra bytecode uit die compiler(als je bvb met een beperkt geheugen zit zoals bij de PSP).
En dat minimaliseren is meestal per member, dus dan mag je even - ik zeg maar wat - tientallen members gaan minimaliseren :s

Deguchi zei:
Ik zou het gebruik van getters/setters dus zeker aanraden. Het bespaard u op termijn veel werk en mogelijke miserie! ;)
Tuurlijk zijn getters en setters nodig, maar overdrijven is een kunst hee ;) Je wil niet voor álles een getter en setter.

passero zei:
Ik bedoelde inderdaad de variabelen die anderen public maken :)
Variabelen die enkel intern gebruikt worden binnen de eigen klasse, daar schrijf ik natuurlijk geen getter en setter voor.
Huh? Nu zeg je iets helemaal anders...
Daarnet schreef je:
passero zei:
Als ik een object maak, maak ik elke var automatisch private en schrijf ik er automatisch een getter en setter voor.
Hier zeg je toch duidelijk dat je voor private members getters en setters maakt? Dáár ging ik op in, niet op public getters/setters zodat andere objecten toegang daartoe kunnen krijgen.

passero zei:
@Vinch tijd = geld...

Daar zijn heel veel bazen te kortzichtig over als het op OO aankomt.
Een nieuw project moet snel snel geleverd worden, minder tijd drukt de prijs dus is goed MAAR als je meer tijd neemt in een deftige sturctuur en deftig ontwerp en later moet er een module bijkomen dan pas haal je heel veel profeit uit het meerwerk van in het begin en blijkbaar vergeten de mensen dit snel... wat ik dus heel spijtig vind. Hoeveel uren dat ik al niet ben verloren door code die copy paste is gedaan en hier en daar een beetje aangepast. Met een beetje deftige OO zou dit op 5 min opgelost zijn om iets aan te passen of bij te schrijven.
Een goed ontwerp&structuur betekent niet per se "alles een getter en een setter geven", maar overwegen waar het wel en waar het niet nodig is.

nickman

Legacy Member
Het grote voordeel dat je hebt als je wel getters en setters gebruikt is dat je veel meer controle hebt over de mogelijke waardes die in je variabelen moeten komen.
Stel nu, je hebt ergens een hoek nodig, en je wil dat die atijd tussen 0° en 359° ligt. Hoe ga je dit controleren als je gewoon die variabele public maakt? dan kan je daar inzetten wat je maar wil?

Als je daarentege met een set procedure werkt, dan kan je daarin gaan controleren, ligt de waarde die ik mee krijg wel degelijk tussen 0 en 359?
Als dit zo is, geen probleem.
Is dit echter niet zo, dan heb je twee mogelijkheden:
- Je laat den input "negeren" maar geeft een foutmelding terug
- Je past de input aan door +/- 360° te doen tot je in je gewenste bereik zit
deze opties zullen dan ook weer applicatie afhankelijk zijn.

Probeer deze dingen maar eens te verzekeren als je die variabele publiek maakt...

.Acku.

Legacy Member
Public variabelen (verwar niet met constanten) bestaan gewoon niet binnen OO. That's that.

killgore

Legacy Member
.Acku. zei:
Public variabelen (verwar niet met constanten) bestaan gewoon niet binnen OO. That's that.
jij bedoelt met constanten final statics?

Tis maar dat dit in bv. c++ en java constanten beetje verschillend zijn :p.

edit: final vergeten :p

den Acid Burn

Legacy Member
constanten en final statics?
leg eens uit.

zoals ik het begrijp zijn constanten vars die niet meer van waarde kunnen veranderd worden, ze hebben dus een vaste waarde (aangeduid met final modifier in java)

met static kunt ge ergens aan zonder dat er een instance van een class moet zijn.
bv public static void main()
deze method kunt ge uitvoeren zonder dat er een instance van de class bestaat.

ik ben wel vooral opgeleid in java en van c++ ken ik veel te weinig :(

killgore

Legacy Member
Code:
class myConstants
{
    public static final int constanteInt =5;
    public static final char constanteChar = 'c';
}

oproepen met
myConstants.constanteInt;

:unsure: ?

in c++ maak je een variabele constant door het keyword 'const' :p.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan