Vă mulțumim pentru susținere

Cum ați accesa proprietățile obiectului dintr-o metodă obiect?

Care este modul "purist" sau "corect" de a accesa proprietățile unui obiect dintr-o metodă obiect care nu este o metodă getter / setter?

Știu că din afara obiectului ar trebui să folosiți un getter / setter, dar din interior ar trebui să faceți:

Java:

String property = this.property;

PHP:

$property = $this->property;

sau ați face:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Iartă-mă dacă Java-ul meu este puțin, a trecut un an de când am programat în Java ...

EDIT:

Se pare că oamenii presupun că vorbesc doar despre variabile / proprietăți private sau protejate. Când am învățat OO, am fost învățat să folosesc getters / setters pentru fiecare proprietate, chiar dacă era publică (și de fapt mi ​​sa spus să nu fac niciodată nici o variabilă / proprietate publică). Deci, s-ar putea să încep de la o presupunere falsă de la plecare. Se pare că oamenii care răspund la această întrebare pot spune că ar trebui să aveți proprietăți publice și că aceștia nu au nevoie de getters și setters, ceea ce contravine ceea ce am învățat și despre ce vorbeam, deși poate că trebuie discutat ca bine. Acesta este probabil un subiect bun pentru o altă întrebare, deși ...

0
adăugat editat

17 răspunsuri

Depinde de modul în care se utilizează proprietatea. De exemplu, spuneți că aveți un obiect student care are proprietatea unui nume. Ați putea utiliza metoda Get pentru a extrage numele din baza de date, dacă nu a fost deja recuperată. În acest fel, reduceți apelurile inutile către baza de date.

Acum, să spunem că aveți un numărător întreg privat în obiectul dvs. care numără numărul de repetări a numelui. Poate doriți să nu utilizați metoda Get din interiorul obiectului deoarece ar produce un număr nevalabil.

0
adăugat
Dacă adăugați un fel de boolean pentru getter, cum ar fi: PHP: funcția publică getName ($ outsideCall = true) {if ($ outsideCall) {$ this-> incrementNameCalled (); } returnați $ this-> name; } și apoi din interiorul Obiectului însuși, dacă ați apelat la nume, ați putea să-l păstrați din incrementarea cu: PHP: $ name = $ this-> getName (false); Mă duc peste bord aici?
adăugat autor cmcculloh
Dacă obiectul Student este un obiect de activitate / domeniu, acum amestecați detaliile infrastructurii. În mod ideal, un obiect de domeniu / domeniu ar trebui să se refere numai la logica de afaceri / domeniu.
adăugat autor moffdub

Mă duc peste bord aici?

Poate;)

O altă abordare ar fi folosirea unei metode private / protejate pentru a face efectiv obtinerea (caching / db / etc), și un pachet public pentru el care crește numărul:

PHP:

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

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

și apoi din interiorul obiectului însuși:

PHP:

$name = $this->_getName();

În acest fel, puteți utiliza în continuare primul argument pentru altceva (de exemplu, trimiterea unui steag pentru a utiliza sau nu datele de pe cache).

0
adăugat

Personal, simt că este important să rămânem consecvent. Dacă aveți getters și setters, folosiți-le. Singura dată când voi accesa un câmp direct este atunci când accesorul are mult aeriene. S-ar putea să vă simțiți ca și cum vă balonați codul în mod inutil, dar cu siguranță vă poate salva o mulțime de dureri de cap în viitor. Exemplul clasic:

Mai târziu, puteți dori să schimbați modul în care funcționează acest câmp. Poate ar trebui să fie calculat pe-the-fly sau poate doriți să utilizați un alt tip pentru magazinul de susținere. Dacă accesați proprietățile direct, o astfel de modificare poate sparge un număr mare de coduri într-o singură buzunar.

0
adăugat

Acest lucru are un potențial de război religios, dar mi se pare că dacă folosiți un getter / setter, ar trebui să-l utilizați și pe plan intern - folosindu-se ambele va conduce la probleme de întreținere pe drum (de exemplu, cineva adaugă un cod unui setter care < em> necesită pentru a rula de fiecare dată când această proprietate este setată și proprietatea este setată intern fără ca apelatorul să fie apelat).

0
adăugat
@ Euphoria83 Poate că, dar asta nu exclude să se întâmple.
adăugat autor Greg Hurlman
nu face nimic altceva într-un setter altul decât stabilirea valorii proprietății un exemplu de utilizare greșită în Java.
adăugat autor euphoria83

Se pare că implementarea implicită a proprietăților C # 3.0 este luată pentru dvs.; trebuie să setați proprietatea folosind setătorul de proprietăți (eventual privat).

Eu personal folosesc numai membrul privat în spatele lui atunci când nu faci acest lucru ar determina ca obiectul să cadă într-o stare mai puțin dorită, cum ar fi atunci când se inițiază sau când se implică încărcarea cache / leneș.

0
adăugat

După cum se menționează în unele dintre comentariile: Uneori ar trebui, câteodată nu ar trebui. Marea parte a variabilelor private este că puteți să vedeți toate locurile pe care le folosiți când schimbați ceva. Dacă getterul / setterul îți face ceva de care ai nevoie, folosește-l. Dacă nu contează, decideți.

Cazul opus ar putea fi că, dacă utilizați getter / setter și cineva schimbă getter / setter ei trebuie să analizeze toate locurile getter și setter este utilizat intern pentru a vedea dacă popotelor ceva.

0
adăugat

Pot să greșesc deoarece sunt autodidact, dar NU folosesc niciodată proprietăți publice în clasele mele Java, sunt întotdeauna private sau protejate, astfel încât codul exterior trebuie să aibă acces de către getters / setters. Este mai bine pentru întreținere / modificări. Și pentru codul din interiorul clasei ... Dacă metoda getter este trivială, folosesc proprietatea direct, dar folosesc întotdeauna metodele setter, pentru că aș putea adăuga cu ușurință codul la evenimentele de incendiu dacă doresc.

0
adăugat

Dacă "purist" înseamnă "cea mai mare încapsulare", atunci declar că toate câmpurile mele sunt private și apoi utilizează acest câmp din interiorul clasei însăși, dar toate celelalte clase, inclusiv subclasele, permit accesul la instanță folosind getters.

0
adăugat

Depinde. Este mai mult o problemă de stil decât orice altceva, și nu există nici o regulă greu.

0
adăugat

If I won't edit the property I'll use a get_property() public method unless it's a special occasion such as a MySQLi object inside another object in which case I'll just public the property and refer to it as $obj->object_property.

Inside the object it's always $this->property for me.

0
adăugat

aș spune că este mai bine să utilizezi metodele accesorilor chiar și în interiorul obiectului. Iată punctele care îmi vin în minte imediat:

1) Ar trebui făcută în interesul menținerii coerenței cu accesările făcute în afara obiectului.

2) În unele cazuri, aceste metode accesoriale ar putea face mai mult decât accesarea câmpului; ar putea face unele prelucrări suplimentare (rare însă). Dacă acesta este cazul, accesând direct câmpul, veți pierde această procesare suplimentară, iar programul dvs. ar putea să nu funcționeze dacă această procesare trebuie întotdeauna efectuată în timpul acestor accesări

0
adăugat

Sunt destul de surprins de cât de unanim este sentimentul că getters și setterii sunt bine și bine. Îți sugerez articolul incendiar al lui Allen Holub "Getters and Setters Are Evil“. Acordat, titlul este pentru valoarea de șoc, dar autorul face puncte valide.

În esență, dacă aveți getters și setters pentru fiecare domeniu privat, faceți acele câmpuri la fel de bine ca publicul. Ați fi foarte presat să schimbați tipul unui câmp privat fără efecte de rupere la fiecare clasă care apelează getter .

Mai mult decât atât, dintr-un punct de vedere strict al OO, obiectele ar trebui să răspundă la mesaje (metode) care corespund responsabilității lor (sperăm). Marea majoritate a getters și setters nu au sens pentru obiectele lor constitutive; Pen.dispenseInkOnto (Surface) Pen.getColor () .

Getters și setters încurajează, de asemenea, utilizatorii clasei să ceară obiect pentru unele date, să efectueze un calcul și apoi să stabilească o altă valoare în obiect, mai bine cunoscut sub numele de programare procedurală. Ar fi mai bine să-i spui obiectului de a face ceea ce trebuia să faci în primul rând; cunoscut sub numele de idiom Expert de informații .

Getters și setters, cu toate acestea, sunt rele rele la limita straturilor - UI, persistența și așa mai departe. Acces restricționat la intervalele clasei, cum ar fi cuvântul cheie prieten al C ++, accesul protejat în pachetul Java, accesul intern al .NET și Modelul prietenului vă poate ajuta să reduceți vizibilitatea getters și să setați numai cei care au nevoie de ele.

0
adăugat

Modul pur OO este acela de a evita ambele și de a respecta Legea Demeterului folosind Spuneți "Nu întrebați" .

În loc de a obține valoarea proprietății obiectului, care cuplurile strânse cele două clase, utilizați obiectul ca parametru de ex

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

Acolo unde proprietatea era un tip nativ, de ex. int, utilizați o metodă de acces, denumiți-o pentru domeniul problemei, nu domeniul de programare.

  doSomethingWithProperty( this.daysPerWeek() ) ;

Acestea vă vor permite să mențineți încapsularea și orice post-condiții sau invarianți dependenți. De asemenea, puteți utiliza metoda setter pentru a menține orice condiții prealabile sau invarianți dependenți, însă nu intrați în capcana numirii acestora, reveniți la principiul de la Hollywood pentru a numi atunci când utilizați idiomul.

0
adăugat

am gasit folosind setters / getters a facut codul meu mai usor de citit. Îmi place de asemenea controlul pe care îl oferă când alte clase utilizează metodele și dacă modific datele pe care proprietatea le va stoca.

0
adăugat

Câmpuri private cu proprietăți publice sau protejate. Accesul la valori trebuie să treacă prin proprietăți și să fie copiat la o variabilă locală dacă acestea vor fi utilizate mai mult decât o dată într-o metodă. Dacă și NUMAI dacă aveți restul aplicației dvs. atât de complet optimizat, scos în mișcare și altfel optimizat în cazul în care accesarea valorilor prin trecerea prin proprietățile lor asociere a devenit o strangulare (și asta nu se va întâmpla niciodată, garantez) dacă ar trebui chiar să începeți să considerăm că permiteți altceva decât proprietăților să atingă direct variabilele de susținere.

Dezvoltatorii .NET pot utiliza proprietăți automate pentru a impune acest lucru, deoarece nu puteți vedea chiar variabilele de suport la momentul designului.

0
adăugat

PHP oferă o multitudine de moduri de a rezolva această problemă, inclusiv metode magice __ get și __ set , dar prefer explicit getters și setters. Iata de ce:

  1. Validarea poate fi plasată în settoarele (și în cazul celor care le iau)
  2. Intellisense funcționează cu metode explicite
  3. Nu există nicio întrebare dacă o proprietate este citită, scrieți-o sau citiți-scrie
  4. Returul proprietăților virtuale (adică valorile calculate) arată la fel ca proprietățile obișnuite
  5. Puteți seta cu ușurință o proprietate obiect care nu este niciodată definită în niciun loc, care apoi merge fără documente
0
adăugat

Cred că am lipsit de aici, de ce ați folosi un getter în interiorul unui obiect pentru a accesa o proprietate a acelui obiect?

Luând acest lucru la încheierea lui, getter-ul ar trebui să numească un getter, care ar trebui să numească un getter.

Așadar, aș spune că într-o metodă obiect accesați direct o proprietate, în special văzând că apelați o altă metodă în acel obiect (care va accesa direct proprietatea oricum, apoi o va întoarce) este doar un exercițiu inutil, risipitor (sau am înțeles greșit întrebarea ).

0
adăugat
Am fost condus de aceeasi nevoie pe care trebuia sa o comentezi ... Plus a raspuns nu a fost inchis;)
adăugat autor Egg Vans