Vra

Wat is die "puristiese" of "korrekte" manier om toegang te verkry tot 'n voorwerp se eienskappe van binne 'n objekmetode wat nie 'n getter/setter-metode is nie?

Ek weet dat jy van buite die voorwerp 'n getter/setter moet gebruik, maar van binne sal jy net doen:

Java:

String property = this.property;

PHP:

$property = $this->property;

of sou jy doen:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Vergewe my as my Java 'n bietjie af is, dit is 'n jaar sedert ek in Java geprogrammeer het...

EDIT:

Dit blyk dat mense aanneem ek praat slegs van private of beskermde veranderlikes/eienskappe.Toe ek OO geleer het, is ek geleer om getters/setters vir elke enkele eiendom te gebruik, selfs al was dit publiek (en eintlik is ek aangesê om nooit enige veranderlike/eiendom openbaar te maak nie).So, ek begin dalk van 'n valse aanname van die begin af.Dit blyk dat mense wat hierdie vraag beantwoord dalk sê dat jy openbare eiendomme moet hê en dat dit nie getters en setters nodig het nie, wat in stryd is met wat ek geleer is, en waarvan ek gepraat het, alhoewel dit miskien bespreek moet word as wel.Dit is seker 'n goeie onderwerp vir 'n ander vraag...

Was dit nuttig?

Oplossing

Dit het godsdienstige oorlogspotensiaal, maar dit lyk vir my dat as jy 'n getter/setter gebruik, jy dit ook intern moet gebruik - die gebruik van beide sal lei tot instandhoudingsprobleme langs die pad (bv.iemand voeg kode by 'n opsteller wat behoeftes om te loop elke keer as daardie eienskap gestel word, en die eienskap word intern gestel sonder dat daardie opsteller geroep word).

Ander wenke

Persoonlik voel ek dat dit belangrik is om konsekwent te bly.As jy getters en setters het, gebruik dit.Die enigste keer dat ek direk toegang tot 'n veld sal kry, is wanneer die toebehore baie oorhoofse koste het.Dit mag dalk voel asof jy jou kode onnodig opblaas, maar dit kan beslis 'n hele klomp hoofpyn in die toekoms bespaar.Die klassieke voorbeeld:

Later sal jy dalk begeer om die manier waarop daardie veld werk te verander.Miskien moet dit dadelik bereken word of dalk wil jy 'n ander tipe vir die rugsteunwinkel gebruik.As jy direk toegang verkry tot eiendomme, kan so 'n verandering 'n verskriklike klomp kode in een swell foop breek.

Ek is redelik verbaas oor hoe eenparig die sentiment dit is getters en setters is fyn en goed.Ek stel die brandende artikel deur Allen Holub voor "Getters En Setters Is Evil".Toegegee, die titel is vir skokwaarde, maar die skrywer maak geldige punte.

In wese, as jy het getters en setters vir elke privaat veld maak jy daardie velde so goed soos publiek.Jy sal baie moeilik wees om die tipe van 'n private veld sonder rimpel-effekte te verander na elke klas wat dit noem getter.

Bowendien, vanuit 'n streng OO-oogpunt, behoort voorwerpe te reageer op boodskappe (metodes) wat ooreenstem met hul (hopelik) enkele verantwoordelikheid.Die oorgrote meerderheid van getters en setters maak nie sin vir hul samestellende voorwerpe nie;Pen.dispenseInkOnto(Surface) maak vir my meer sin as Pen.getColor().

Getters en opstellers moedig ook gebruikers van die klas aan om die voorwerp vir sommige data te vra, 'n berekening uit te voer en dan 'n ander waarde in die voorwerp in te stel, beter bekend as prosedurele programmering.Jy sal beter gedien word om bloot vir die voorwerp te sê om te doen wat jy in die eerste plek gaan;ook bekend as die Inligtingsdeskundige idioom.

Getters en setters is egter noodsaaklike euwels op die grens van lae - UI, volharding, ensovoorts.Beperkte toegang tot 'n klas se internals, soos C++ se vriend sleutelwoord, Java se pakket beskermde toegang, .NET se interne toegang, en die Vriend Klas Patroon kan jou help om die sigbaarheid van te verminder getters en stelers aan slegs diegene wat hulle nodig het.

Dit hang af van hoe die eiendom gebruik word.Byvoorbeeld, sê jy het 'n student-objek wat 'n naam-eienskap het.Jy kan jou Get-metode gebruik om die naam uit die databasis te haal, as dit nog nie herwin is nie.Op hierdie manier verminder jy onnodige oproepe na die databasis.

Kom ons sê nou jy het 'n private heelgetalteller in jou voorwerp wat die aantal kere tel wat die naam genoem is.Jy sal dalk nie die Get-metode van binne die voorwerp wil gebruik nie, want dit sal 'n ongeldige telling produseer.

PHP bied 'n magdom maniere om dit te hanteer, insluitend magiese metodes __get en __set, maar ek verkies eksplisiete getters en setters.Hier is hoekom:

  1. Bekragtiging kan in opstellers geplaas word (en getters vir die saak)
  2. Intellisense werk met eksplisiete metodes
  3. Geen twyfel of 'n eiendom leesalleen, slegs skryf of lees-skryf is nie
  4. Die herwinning van virtuele eienskappe (dws berekende waardes) lyk dieselfde as gewone eienskappe
  5. Jy kan maklik 'n objek-eienskap instel wat nooit eintlik oral gedefinieer word nie, wat dan ongedokumenteer word

Gaan ek net oorboord hier?

Miskien ;)

Nog 'n benadering sou wees om 'n privaat/beskermde metode te gebruik om werklik die kry (caching/db/ens) te doen, en 'n publieke omhulsel daarvoor wat die telling verhoog:

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

en dan van binne die voorwerp self:

PHP:

$name = $this->_getName();

Op hierdie manier kan jy steeds daardie eerste argument vir iets anders gebruik (soos om 'n vlag te stuur vir of jy dalk gekasdata hier moet gebruik of nie).

Ek moet die punt hier mis, hoekom sal jy 'n getter binne 'n voorwerp gebruik om toegang tot 'n eienskap van daardie voorwerp te verkry?

Om dit tot sy gevolgtrekking te neem, moet die getter 'n getter noem, wat 'n getter moet noem.

So ek sou sê binne 'n objekmetode toegang tot 'n eienskap direk, veral aangesien die oproep van 'n ander metode in daardie objek (wat in elk geval net direk toegang tot die eiendom verkry en dit dan terugstuur) net 'n sinnelose, verkwistende oefening is (of het ek die vraag verkeerd verstaan ).

As jy met "puristies" bedoel "mees encapsulation", dan verklaar ek tipies al my velde as privaat en gebruik dan this.field van binne die klas self, maar alle ander klasse, insluitend subklasse, kry toegang tot instansiestatus deur die getters te gebruik.

Ek sou sê dit is beter om die toegangsmetodes selfs binne die voorwerp te gebruik.Hier is die punte wat dadelik by my opkom:

1) Dit moet gedoen word in die belang van die handhawing van konsekwentheid met toegang wat buite die voorwerp gemaak word.

2) In sommige gevalle kan hierdie toegangsmetodes meer doen as net toegang tot die veld;hulle kan 'n bietjie bykomende verwerking doen (dit is egter skaars).As dit die geval is, sal jy die bykomende verwerking misloop en jou program kan skeefloop deur direk toegang tot die veld te kry as hierdie verwerking altyd tydens daardie toegang gedoen moet word

Die puristiese OO-manier is om beide te vermy en die te volg Wet van Demeter deur die gebruik van die Vertel Moenie Vra nie benadering.

In plaas daarvan om die waarde van die voorwerp se eiendom te kry, wat hegte paartjies die twee klas, gebruik die objek as 'n parameter bv.

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

Waar die eiendom 'n inheemse tipe was, bv.int, gebruik 'n toegangsmetode, noem dit vir probleemdomein nie die programmeringsdomein nie.

  doSomethingWithProperty( this.daysPerWeek() ) ;

Dit sal jou toelaat om inkapseling en enige post-toestande of afhanklike invariante te handhaaf.Jy kan ook die opsteller-metode gebruik om enige voor-voorwaardes of afhanklike invariante te handhaaf, maar moenie in die strik trap om hulle opstellers te noem nie, gaan terug na die Hollywood-beginsel vir naamgewing wanneer jy die idioom gebruik.

Ek het gevind dat die gebruik van setters/getters my kode makliker maak om te lees.Ek hou ook van die beheer wat dit gee wanneer ander klasse die metodes gebruik en as ek die data verander, sal die eiendom stoor.

Privaat velde met publieke of beskermde eiendomme.Toegang tot die waardes moet deur die eienskappe gaan en na 'n plaaslike veranderlike gekopieer word as hulle meer as een keer in 'n metode gebruik sal word.As en SLEGS as jy die res van jou toepassing so heeltemal aangepas, uitgeruk en andersins geoptimaliseer het tot waar toegang tot waardes deur hul verwante eienskappe 'n bottelnek geword het (en dit sal nooit OOIT gebeur nie, ek waarborg) sou jy selfs begin om te oorweeg om enigiets anders as die eiendomme direk aan hul agtergrondveranderlikes te laat raak.

.NET-ontwikkelaars kan outomatiese eienskappe gebruik om dit af te dwing, aangesien jy nie eens die agtergrondveranderlikes tydens ontwerptyd kan sien nie.

As ek nie die eiendom wil wysig nie, sal ek a get_property() openbare metode, tensy dit 'n spesiale geleentheid is soos 'n MySQLi-voorwerp binne 'n ander voorwerp, in welke geval ek net die eiendom sal openbaar en daarna verwys as $obj->object_property.

Binne die voorwerp is dit altyd vir my $hier->eiendom.

Dit hang af.Dit is meer 'n stylkwessie as enigiets anders, en daar is geen harde reël nie.

Ek kan verkeerd wees omdat ek outodidakt is, maar ek gebruik NOOIT publieke eiendomme in my Java-klasse nie, hulle is altyd privaat of beskerm, sodat buite-kode toegang moet verkry deur getters/setters.Dit is beter vir instandhouding / wysigingsdoeleindes.En vir binneklaskode ...As getter-metode triviaal is, gebruik ek die eiendom direk, maar ek gebruik altyd die setter-metodes, want ek kan maklik kode by brandgebeurtenisse voeg as ek wil.

Wel, dit blyk met C# 3.0 eiendomme se verstek implementering, die besluit is vir jou geneem;jy MOET die eiendom opstel deur die (moontlik private) eiendomsinsteller te gebruik.

Ek persoonlik gebruik slegs die privaat lid-agter wanneer dit nie gedoen word nie, sou veroorsaak dat die voorwerp in 'n minder as wenslike toestand val, soos wanneer dit geïnisieer word of wanneer kas/lui laai betrokke is.

Ek hou van die antwoord deur cmcculloh, maar dit lyk of die mees korrekte antwoord is deur Greg Hurlman.Gebruik die hele tyd getter/setters as jy dit van die begin af begin gebruik het en/of gewoond is om daarmee te werk.

Tersyde, ek vind persoonlik dat die gebruik van getter/setters die kode makliker maak om te lees en om later te ontfout.

Soos in sommige van die opmerkings gesê:Soms moet jy, soms moet jy nie.Die groot deel van private veranderlikes is dat jy al die plekke kan sien wat hulle gebruik word wanneer jy iets verander.As jou getter/setter iets doen wat jy nodig het, gebruik dit.As dit nie saak maak nie, besluit jy.

Die teenoorgestelde geval kan gemaak word dat as jy die getter/setter gebruik en iemand verander die getter/setter hulle al die plekke moet analiseer waar die getter en setter intern gebruik word om te sien of dit iets mors.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top