Obiect Calistenie pentru clase de slăbire Bitul de vorbire
Un blog despre programare, în principal PHP, și poate alte lucruri

Proiect întreținut de franiglesias Găzduit pe paginile GitHub - Tema de mattgraham
de Fran Iglesias
În acest articol vă prezentăm un exercițiu care poate fi folosit pentru a câștiga fluență în scrierea unor clase mai compacte, cu metode mai expresive și ușor de înțeles.
Exercițiile de Calistenie a obiectelor ne pot ajuta să automatizăm practicile care ne permit să abordăm cele mai bune principii de proiectare. Într-un fel, constă în a învăța să detectăm anumite tipare eronate în cod și să le transformăm astfel încât să avansăm în obiectivul de a îmbunătăți calitatea codului.
Ideea acestor exerciții este de a impune restricții artificiale pentru a forța răspunsuri care ne obligă să gândim dincolo de soluțiile convenționale.
În acest articol vom aplica aceste restricții:
- Nivel unic de indentare
- Nu folosi altceva
- Păstrați unitățile mici
Restricțiile
Nivel unic de indentare
Indentarea este un model de organizare a codului care ne ajută să identificăm cu ușurință blocuri de instrucțiuni care formează ramuri sau căi în fluxul software, precum și blocuri de instrucțiuni conexe. În limbi precum Python, indentarea are un sens și, prin urmare, este inevitabilă. Cu toate acestea, în PHP și multe alte limbi, indentarea este o convenție utilă. Am putea scrie programe fără indentare și ar funcționa la fel, doar că ar fi mai greu de citit.
Indentarea este tipică pentru structurile de control, cum ar fi if/then:
Și poate avea mai multe niveluri:
Provocarea, de data aceasta, va fi reducerea unu nivelurile de indentare în fiecare metodă a unei clase.
În esență, acest lucru ne obligă să luăm în considerare ce face fiecare bloc de cod și să îl extragem în propria sa metodă, explicând ce face în numele lor.
Nu folosi altceva
Structura if/then/else poate fi confuză din mai multe motive. Una dintre ele este tocmai utilizarea inutilă a else, mai ales atunci când piciorul de atunci implică o ieșire din buclă sau metoda principală.
Am introdus această restricție deoarece este destul de legată de cea anterioară.
Păstrați unitățile mici
În articolul citat la început vorbim despre entități, dar, gândindu-mă bine, am preferat să pun unități pentru a mă referi atât la clase, cât și la metode. În cele din urmă, este vorba despre fiecare unitate, indiferent de rezoluția pe care o gestionăm, să fie cât mai mică și mai ușor de gestionat.
Acest lucru duce la o anumită contradicție. De exemplu, o clasă poate ocupa mai puține linii cu o singură metodă mare decât dacă o împărțim în câteva mai mici bazate pe principii precum reducerea nivelurilor de indentare. Evident, acestea sunt decizii care implică compromisuri. Echilibrul constă în menținerea lizibilității și inteligibilității clasei și a metodelor sale.
Instruire
Cu ceva timp în urmă, practicam scrierea algoritmilor clasici și a structurilor de date folosind TDD și, deși sunt clase relativ mici, au unele structuri care ar putea fi îmbunătățite prin aplicarea restricțiilor propuse, așa că haideți să vedem câteva exemple și cum le putem evolua.
Ca o notă de interes, să spun că voi face majoritatea refactorilor cu instrumentele furnizate de IDE (PHPStorm).
Să începem cu BubbleSort, cel mai simplu și mai intuitiv algoritm de sortare, deși nu este foarte eficient pentru multe elemente:
Apropo, testul este acesta și se face cu phpspec:
În acest caz avem trei niveluri de indentare iar restricția este că fiecare metodă poate avea una singură cel mult. Pentru a face acest lucru, vom extrage imbricarea pentru propria metodă cu ajutorul IDE, asigurându-ne că testele continuă să treacă:
Testul trece, așa că nu am spart nimic. Putem vedea câteva detalii care ar putea fi îmbunătățite în această extracție:
- Parametrul $ length nu este necesar deoarece, din moment ce îl putem obține cu ușurință din $ source, deci îl vom omite.
- Am fi putut folosi o structură foreach în loc de for .
- Este posibil să treceți elementul matricei în locul indexului său.
Acesta este un punct interesant: faptul de a extrage metoda ne provoacă câteva reflecții asupra deciziilor noastre anterioare și posibile îmbunătățiri ale codului. Deci, înainte de a continua, vom aplica câteva.
În acest moment, trecerea elementului și nu a indexului nu pare viabilă, dar am obținut unele îmbunătățiri, deoarece acum nu este necesar să calculăm în mod explicit lungimea sursei $, ceea ce înseamnă o linie mai puțin și suntem mai expliciți în reprezentarea ideea că traversăm matricea. Continuăm să menținem un singur nivel de indentare, care are, de asemenea, doar o singură linie.
Acum avem două niveluri de indentare în interiorul metodei compareEveryElementWithCurrent, deci să le tratăm în același mod: extragerea la o metodă.
Ei bine, există câteva lucruri interesante pe aici:
- Avem doar un nivel de indentare la fiecare nivel.
- În numele metodei facem o referință la un element curent, deci ar fi bine să-l exprimăm în cod schimbând numele variabilei $ i în $ currentIndex sau similar, astfel încât referința să fie explicită.
- Am putea aplica același tratament de conversie a for în foreach și salvăm variabila $ length .