Elementul 2 Luați în considerare un constructor atunci când vă confruntați cu mulți parametri de constructor Crearea și distrugerea Java

Acest capitol este din carte

Acest capitol este din carte

Acest capitol este din cartea 

Elementul 2: luați în considerare un constructor atunci când vă confruntați cu mulți parametri ai constructorului

Fabricile și constructorii statici împărtășesc o limitare: nu se ridică bine la un număr mare de parametri opționali. Luați în considerare cazul unei clase care reprezintă eticheta Fapte nutriționale care apare pe alimentele ambalate. Aceste etichete conțin câteva câmpuri obligatorii - dimensiunea porției, porții pe recipient și calorii pe porție - și peste douăzeci de câmpuri opționale - grăsimi totale, grăsimi saturate, grăsimi trans, colesterol, sodiu și așa mai departe. Majoritatea produselor au valori diferite de zero doar pentru câteva dintre aceste câmpuri opționale.

când

Ce fel de constructori sau fabrici statice ar trebui să scrieți pentru o astfel de clasă? În mod tradițional, programatorii au folosit modelul constructor telescopic, în care furnizați un constructor cu numai parametrii necesari, un altul cu un singur parametru opțional, un al treilea cu doi parametri opționali și așa mai departe, culminând cu un constructor cu toți parametrii opționali. Iată cum arată în practică. Din motive de scurtă durată, sunt afișate doar patru câmpuri opționale:

Când doriți să creați o instanță, utilizați constructorul cu cea mai scurtă listă de parametri care conține toți parametrii pe care doriți să îi setați:

În mod obișnuit, această invocare a constructorului va necesita mulți parametri pe care nu doriți să îi setați, dar oricum sunteți forțați să le transmiteți o valoare. În acest caz, am trecut o valoare 0 pentru grăsime. Cu „doar” șase parametri, acest lucru poate să nu pară atât de rău, dar scapă rapid din mână pe măsură ce numărul parametrilor crește.

În scurt, modelul constructor telescopic funcționează, dar este greu să scrieți codul clientului atunci când există mulți parametri și este mai greu să-l citiți. Cititorul se lasă întrebat ce înseamnă toate aceste valori și trebuie să numere cu atenție parametrii pentru a afla. Secvențele lungi de parametri tipări identici pot provoca erori subtile. Dacă clientul inversează accidental doi astfel de parametri, compilatorul nu se va plânge, dar programul se va comporta greșit în timpul rulării (articolul 40).

O a doua alternativă când vă confruntați cu mulți parametri de constructor este modelul JavaBeans, în care apelați un constructor fără parametri pentru a crea obiectul și apoi apelați metodele setter pentru a seta fiecare parametru necesar și fiecare parametru opțional de interes:

Acest model nu are niciunul dintre dezavantajele modelului constructor telescopic. Este ușor, dacă este puțin cam vorbitor, să creați instanțe și să citiți ușor codul rezultat:

Din păcate, modelul JavaBeans are dezavantaje serioase. Deoarece construcția este împărțită pe mai multe apeluri, un JavaBean poate fi într-o stare incoerentă parțial prin construcția sa. Clasa nu are opțiunea de a impune consistența doar prin verificarea validității parametrilor constructorului. Încercarea de a utiliza un obiect atunci când este într-o stare inconsistentă poate provoca eșecuri care sunt departe de codul care conține eroarea, deci dificil de depanat. Un dezavantaj conex este că modelul JavaBeans exclude posibilitatea de a face o clasă imuabilă (Punctul 15) și necesită un efort suplimentar din partea programatorului pentru a asigura siguranța firului.

Este posibil să se reducă aceste dezavantaje prin „înghețarea” manuală a obiectului atunci când construcția sa este completă și nu se permite utilizarea acestuia până când este înghețat, dar această variantă este dificilă și rareori folosită în practică. Mai mult, poate provoca erori în timp de execuție, deoarece compilatorul nu se poate asigura că programatorul apelează metoda de înghețare a unui obiect înainte de ao utiliza.

Din fericire, există o a treia alternativă care combină siguranța modelului constructor telescopic cu lizibilitatea modelului JavaBeans. Este o formă a modelului Builder [Gamma95, p. 97]. În loc să facă obiectul dorit direct, clientul apelează un constructor (sau fabrică statică) cu toți parametrii necesari și obține un obiect constructor. Apoi clientul apelează metode de tip setter pe obiectul constructor pentru a seta fiecare parametru opțional de interes. În cele din urmă, clientul apelează o metodă de construire fără parametri pentru a genera obiectul, care este imuabil. Constructorul este o clasă de membru static (articolul 22) al clasei pe care o construiește. Iată cum arată în practică: