Dacă sunteți în dezvoltarea de software, noi tehnici, limbi și concepte pop-up tot timpul. Cu toții ne simțim acele îndoieli din când în când: "Pot să țin pasul cu schimbările și să rămân competitiv?" Ia-ți o clipă, și deduce o linie din filmul meu preferat, Casablanca: "Lucrurile fundamentale se aplică, odată cu trecerea timpului".
Tutorial publicatLa fiecare câteva săptămâni, revizuim câteva postări preferate ale cititorului nostru de-a lungul istoriei site-ului. Acest tutorial a fost publicat pentru prima dată în aprilie 2012.
Ce este adevărat pentru dragoste, este adevărat pentru cod.
Ce este adevărat pentru dragoste, este adevărat pentru cod. Lucrurile fundamentale se vor aplica întotdeauna. Dacă aveți o înțelegere a ideilor care stau la baza dezvoltării software-ului, vă veți adapta rapid la noile tehnici. În acest tutorial, vom discuta trei principii de bază și le vom amesteca cu multe altele. Acestea oferă o modalitate puternică de gestionare a complexității software-ului. Voi împărtăși câteva dintre opiniile și gândurile mele personale, care, sperăm, se vor dovedi utile atunci când este vorba de aplicarea lor în proiecte de cod și proiecte din lumea reală.
O strategie de bază pentru reducerea complexității la unitățile managibile este împărțirea unui sistem în bucăți.
Acest principiu este atât de important pentru a înțelege, încât nu o voi scrie de două ori! Este denumit în mod obișnuit prin acronimul DRY și a venit în carte Programatorul pragmatic, de Andy Hunt și Dave Thomas, dar conceptul, în sine, a fost cunoscut de mult timp. Se referă la cele mai mici părți ale software-ului dvs..
Când construiți un proiect de software mare, veți fi, de obicei, copleșiți de complexitatea generală. Oamenii nu sunt buni în gestionarea complexității; ei sunt buni la găsirea de soluții creative pentru probleme cu un anumit domeniu de aplicare. O strategie de bază pentru reducerea complexității unităților managibile este împărțirea unui sistem în părți mai accesibile. La început, poate doriți să vă împărțiți sistemul în componente, în care fiecare componentă reprezintă propriul subsistem care conține tot ceea ce este necesar pentru a realiza o anumită funcționalitate.
De exemplu, dacă construiți un sistem de gestionare a conținutului, partea care este responsabilă de gestionarea utilizatorilor va fi o componentă. Această componentă poate fi împărțită în subcomponente suplimentare, cum ar fi gestionarea rolului, și poate comunica cu alte componente, cum ar fi componenta de securitate.
Pe măsură ce împărțiți sistemele în componente și, în plus, componentele în subcomponente, veți ajunge la un nivel în care complexitatea este redusă la o singură responsabilitate. Aceste responsabilități pot fi implementate într-o clasă (presupunem că construim o aplicație orientată pe obiecte). Clase
conțin metode și proprietăți. Metodele implementează algoritmi. Algoritmi și - în funcție de cât de obsedați vrem să obținem - subcapitolele
algoritmii calculează sau conțin cele mai mici bucăți care vă construiesc logica de afaceri.
Principiul DRY afirmă că aceste mici cunoștințe pot să apară exact o singură dată în întregul dvs. sistem.
Ei trebuie să aibă o singură reprezentare în interiorul ei.
Fiecare element de cunoaștere trebuie să aibă o reprezentare unică, lipsită de ambiguitate și autoritate într-un sistem.
Observați diferența dintre cunoștințe, si este reprezentare. Dacă implementăm conexiunea de baze de date în CMS, vom avea un fragment de cod care va initaliza driverul bazei de date, va transmite acreditările și va salva o referință la conexiune într-o variabilă. Fragmentul de cod face parte din cunoaștere, este vorba despre cum se realizează ceva. Variabila cu referire la conexiune reprezintă reprezentarea acestei cunoștințe - și aceasta poate fi folosită de alte părți. Dacă se modifică datele de bază ale bazei de date, va trebui să schimbăm fragmentul - nu reprezentarea acestuia.
Într-o aplicație perfectă, fiecare bucată mică de logică de afaceri își încapsulează cunoștințele într-o reprezentare, și anume o proprietate variabilă sau de clasă.
Această variabilă însăși este încapsulată într-o clasă care poate fi descrisă ca o reprezentare a unei responsabilități. Clasa este încapsulată într-o componentă care poate fi descrisă ca o reprezentare a funcționalității.
Acest lucru poate fi continuat până când ajungem la nivelul superior al proiectului nostru software - adică un teanc de reprezentări cu complexitate în creștere. Acest mod de a privi complexitatea software-ului se numește arhitectură modulară, iar DRY este o parte importantă a acestuia.
Arhitectura de software se referă la gestionarea complexității.DRY este o filozofie care împachetează logica în reprezentări.
Există multe modalități de a obține DRYness. Hunt și Thomas au sugerat (printre altele) generarea de coduri și transformarea datelor. Dar, în esență, DRY este o filozofie care împachetează logica în reprezentări.
Deoarece fiecare parte a aplicației dvs. poate fi văzută ca reprezentare, fiecare parte prezintă fragmente specifice ale logicii dvs. de bază: gestionarea utilizatorilor expune accesul utilizatorilor înregistrați ai CMS, clasa utilizator reprezintă un singur utilizator și își expune proprietățile (cum ar fi numele de utilizator) . Reactivează proprietățile, prin reprezentarea bazei de date.
DRY și arhitectura modulară necesită o planificare bună. Pentru a obține o ierarhie de reprezentare de jos în sus, împărțiți aplicația într-o ierarhie a unor părți mai mici separate logic și permiteți-i să comunice una cu cealaltă. Dacă trebuie să gestionați proiecte mai mari, organizarea lor în componente și utilizarea DRY în cadrul componentelor este o idee bună. Încercați să aplicați următoarele reguli:
Driverul bazei de date este un exemplu simplificat, deoarece există mai multe straturi implicate în lumea reală (cum ar fi un anumit nivel de abstractizare a bazei de date) și există mult mai multe lucruri pe care le puteți face pentru a încapsula logica - în special scufundări în modelele de design. Dar chiar dacă tocmai ați început să codificați, trebuie să aveți în vedere un singur lucru:
Când vă aflați în scris cod care este similar sau egal cu ceva pe care l-ați scris înainte, faceți o clipă să vă gândiți la ceea ce faceți și să nu vă repetați.
În lumea reală, aplicațiile care sunt 100% DRY sunt greu, dacă nu chiar imposibil, de realizat. Cu toate acestea, aplicațiile care nu sunt acceptate într-o măsură inacceptabilă - și, prin urmare, greu de întreținut - sunt destul de comune. Prin urmare, nu este surprinzător să afli că mai mult de 50% din toate proiectele software eșuează - dacă te uiți la cod.
Mulți oameni tind să creadă că codul rău este produs de coderi răi. Din experiența mea, aceasta este o excepție. Cel mai adesea, codul rău este produs de managerii de cont rău și o confruntare generală greșită a procesului de management în companii.
Codul rău este rar produs de coderii răi.
Uscarea se realizează printr-o bună planificare.
De exemplu, spuneți că sunteți angajat ca consultant tehnic de către o companie care are probleme cu calitatea și întreținerea codului. Examinați sursa și vedeți hacks și duplicarea codului - codul nu este uscat. Acesta este un simptom al calității codului rău, nu este motivul. Dacă vă uitați la sistemul de control al versiunilor - aka istoricul codului - sunt șanse să găsiți hack-uri care au fost introduse în momente apropiate de termenele limită și de reperele. Acordați-vă timp să examinați ce modificări sunt făcute și probabil că veți fi confruntat cu o modificare a cerințelor.
După cum sa menționat mai sus, uscarea se realizează printr-o bună planificare. Modificările forțate, într-un termen greu, obligă dezvoltatorii să implementeze soluții murdare. Odată ce codul este compromis, principiul DRY este probabil să fie sacrificat complet la schimbările ulterioare.
Există un motiv pentru care cele mai de succes corporații din domeniul IT au fost înființate de oameni cu o înțelegere tehnică foarte bună - sau chiar coderi: Bill Gates, Mark Zuckerberg, Steve Wozniak, Steve Jobs, Larry Page, Serghei Brin și Larry Ellison știu știa) ce eforturi sunt necesare pentru a pune în aplicare ceva. În schimb, multe companii tind să stabilească cerințele pentru inginerie în mâinile managerilor de cont, iar partea conceptuală în mâinile consultanților de afaceri ... oameni care nu au implementat niciodată nimic.
Prin urmare, multe concepte tehnice funcționează numai în Powerpoint, Photoshop și pe ecranele cu ecran lat de 27 ". Aceasta poate fi o abordare reușită în zilele mai mult sau mai puțin site-uri statice, dar nu este astăzi - cu aplicații interactive pe mai multe dispozitive. Deoarece coderii sunt ultimii din linie, aceștia trebuie să aplice remedierile rapide privind erorile din concept. Dacă acest lucru este însoțit de un manager de cont, care nu poate sta în fața unui client care îi place să facă ultimul minut schimbările, planurile sunt aruncate în gunoi și se implementează ceva rapid și murdar. Codul devine nesigur.
Acest exemplu este un pic extrem (totuși, am asistat la astfel de scenarii), dar demonstrează că DRY este un concept teoretic, care este provocat de diferite părți din lumea reală. Dacă lucrați într-o companie care vă forțează să lucrați în acest mod, puteți sugera anumite modificări ale procesului (precum introducerea expertizei tehnice într-o etapă anterioară a proiectelor tehnice).
Dacă aveți o abordare hands-off, continuați să citiți! Nu o să ai nevoie de ea principiul va veni la salvare.
Cea mai simplă explicație tinde să fie cea corectă.
La sfârșitul secolului al XIX-lea, fizicienii s-au străduit să explice cât de mult interacționează gravitația, magnetismul și optica, când vine vorba de distanțe mari - cum ar fi distanțele din sistemul nostru solar. Așadar, a fost postulat un aether cu numele mediu. Sa spus că lumina călătorește prin acest mediu și că este responsabilă de efecte care nu pot fi explicate altfel. De-a lungul anilor, teoria a fost extinsă cu presupuneri care au ajustat postulatul aeter la rezultatele experimentelor. Unele ipoteze au fost arbitrare, unele au introdus alte probleme, iar întreaga teorie a fost destul de complexă.
Un angajat al biroului elvețian de brevete, Albert Einstein, a sugerat să scape de întreaga teorie a eterului atunci când a introdus o idee simplă, dar revoluționară: Toată ciudățenia în calcularea cu distanțe mari ar dispărea dacă am accepta că timpul nu este o constantă; este relativă. Acest incredibil de gândit în afara casetei pentru a ajunge la cea mai simplă explicație cu cele mai puține ipoteze de a selecta între scenarii concurente este denumit Razorul lui Ockhams.
Există concepte similare în multe domenii. În dezvoltarea de software (și alții), îl numim KISS. Există multe variante pentru acest acronim, dar toate înseamnă că trebuie să depuneți eforturi pentru cel mai simplu mod de a face ceva.
Progrese substanțiale în istoria omenirii au fost realizate de gânditori laterali.Protocol de transfer de hipertext este considerat un exemplu perfect pentru o soluție simplă: proiectată pentru a transfera documente bazate pe hipertext, este coloana vertebrală a aplicațiilor extrem de interactive și desktop-esque din zilele noastre. Poate că trebuie să găsim soluții pentru limitări în protocol și poate că trebuie să o înlocuim într-o bună zi. Totuși, status quo-ul este: bazat pe câteva metode de solicitare (cum ar fi GET și POST), codurile de stare și argumentele textului simplu, HTTP sa dovedit a fi flexibil și robust. Acesta este motivul pentru care HTTP a fost în mod repetat împins de limită de către dezvoltatorii web - și este încă în picioare.
Considerăm că această abordare este de la sine înțeles, însă istoria dezvoltării și standardizării software-ului este plină de soluții prea complexe și semi-coapte. Există chiar și un cuvânt special creat pentru asta: bloatware. Software-ul ca acesta este, de asemenea, descris ca fiind DOD, mort la sosire. Am o teorie care este foarte asemănătoare cu teoria mea despre codul unDRY, când vine vorba despre bloatware ... Cu toate acestea, succesul internetului poate fi descris ca un succes al unor soluții simple, dar eficiente.
Deci, ce este necesar pentru a ajunge la cea mai simplă soluție posibilă? Totul se limitează la mentenabilitatea și înțelegerea în dezvoltarea de software. Prin urmare, KISS intră în faza ingineriei cerințelor. Când vă gândiți cum să transformați cerințele clientului în componentele implementabile, încercați să identificați următoarele părți:
Există mulți oameni implicați în procesul conceptual, care nu dispun de expertiza tehnică pentru a face o analiză fiabilă cost-beneficiu
Am lucrat odată la un proiect în care clientul dorea să importe foi de calcul Excel în software-ul de management al echipajului. A fost o potrivire clară. Excel este un software proprietar cu un format complex de documente. Formatul este complex, pentru că este bogat în caracteristici: puteți adăuga grafice și alte elemente la acesta - caracteristici care nu au fost necesare de către client. El era pur și simplu interesat de numere. Astfel, implementarea importului Excel ar necesita implementarea unei multitudini de funcționalități inutile. În plus, există mai multe versiuni de versiuni Excel, iar Microsoft declanșează o altă lansare în fiecare an. Acest lucru ar fi fost greu de menținut, iar costurile suplimentare vor apărea în viitor.
Am ajuns să implementăm importul unei valori separate prin virgulă. Acest lucru a fost făcut cu câteva rânduri de cod. Gestionarea datelor a fost foarte mică (comparați o foaie de calcul Excel cu echivalentul CSV) și soluția a fost menținută și protejată în viitor. Excel a fost gata să exporte CSV oricum (precum și alte programe pe care clientul ar putea să le folosească în viitor). Deoarece soluția era și la prețuri reduse, a fost o aplicare bună a principiului KISS.
Pentru a rezuma: încercați să gândiți în afara casetei dacă o sarcină pare complicată pentru dvs. Dacă cineva vă explică cerințele sale și credeți că va fi greu și complex de implementat, aveți dreptate aproape în orice situație. În timp ce unele lucruri sunt doar atât - greu de pus în aplicare - soluții complicate sunt destul de obișnuite. Acesta este cazul deoarece există mulți oameni implicați în procesul conceptual, care nu dispun de expertiza tehnică pentru a face o analiză fiabilă a raportului cost-beneficiu. Prin urmare, ei nu văd problema. Verificați dublu cerințele dacă sunt într-adevăr eliminate în esența pe care clientul are nevoie. Luați timp pentru a discuta aspectele critice și pentru a explica de ce alte soluții ar putea fi mai potrivite.
Codificarea vizează construirea de lucruri.
Când a fost lansat Google+, Mark Zuckerberg - fondatorul Facebook - a fost unul dintre primii care a creat un cont în rețeaua socială care urmărea să-și scape propriul. El a adăugat doar o singură linie la Despre mine secțiunea: "Construiesc lucruri". Cred sincer că aceasta este o propoziție strălucită, deoarece descrie esența pură a codării în câteva cuvinte simple. De ce ați decis să deveniți coder? Entuziasm pentru soluții tehnice? Frumusețea eficienței? Indiferent de răspunsul dvs., este posibil să nu fie "construirea site-ului corporate 1.000.001th cu funcționalitate standard". Cu toate acestea, majoritatea dintre noi fac bani în acest fel. Indiferent unde lucrați, probabil veți fi confruntați cu sarcini plictisitoare și repetitive din când în când.
80% din timpul petrecut pentru un proiect software este investit în 20% din funcționalitate.
Nu o să ai nevoie de ea (YAGNI) se ocupă de aceste sarcini. În esență, se traduce: Dacă nu este în concept, nu este în cod. De exemplu, este o practică obișnuită de a abona accesul la baza de date într-un strat care gestionează diferențele dintre diferiți drivere, cum ar fi MySQL, PostgreSQL și Oracle. Dacă lucrați la un site corporativ care este găzduit într-un stivuitor LAMP, într-o gazdă comună, cât de probabil este că vor schimba baza de date? Amintiți-vă că conceptul a fost scris cu bugetul în minte.
Dacă nu există niciun buget pentru abstractizarea bazei de date, nu există o abstractizare a bazei de date. Dacă se produce evenimentul puțin probabil al unei modificări a bazei de date, este un lucru firesc să încărcați pentru cererea de modificare.
S-ar putea să fi observat diferența dintre Nu o să ai nevoie de ea și USCAT-arhitecturi modulare comandate: aceasta din urmă reduce complexitatea prin împărțirea unui proiect în componente controlabile, în timp ce prima reduce complexitatea prin reducerea numărului de componente. YAGNI este similar cu SĂRUT principiu, deoarece se străduiește pentru o soluție simplă. Cu toate acestea, KISS se străduiește să găsească o soluție simplă încercând să implementeze ceva cât mai ușor posibil; YAGNI se străduiește pentru simplitate prin faptul că nu o implementează deloc!
Theodore Sturgeon, un autor american sci-fi, a declarat legea: "90% din totul este rahat". Aceasta este o abordare foarte radicală și nu prea utilă în proiectele din lumea reală. Dar rețineți că "prostiile" pot fi foarte consumatoare de timp. O regulă bună este că aproximativ 80% din timpul petrecut pentru un proiect software este investit în 20% din funcționalitate. Gândiți-vă la propriile dvs. proiecte! De fiecare dată când fac, sunt surprins de acuratețea regulii 80:20.
80% din timpul petrecut pe un proiect software este investit în 20% din funcționalitate.Dacă sunteți într-o companie care este notorie pentru termene limită și concepte imprecise, aceasta este o strategie puternică. Nu veți fi răsplătit pentru implementarea unui strat de abstractizare a bazei de date. Șansele sunt că șeful tău nu știe ce este chiar un strat de abstractizare a bazei de date.
În timp ce acest concept poate suna simplu, poate fi dificil să se deosebească piesele care nu sunt necesare. De exemplu, dacă vă simțiți confortabil cu o bibliotecă sau cu un cadru care utilizează abstractizarea bazei de date, nu veți economisi mult timp să o eliminați. Conceptul cheie este un alt mod de a privi software-ul: suntem pregătiți să scriem software-ul care să nu fie însoțit de viitor și să fie întreținut. Aceasta înseamnă că suntem instruiți să gândim înainte. Ce schimbări pot apărea în viitor? Acest lucru este esențial pentru proiecte mai mari, dar pentru cele mai mici. Nu gândiți în viitor! Dacă un site web corporativ mic face schimbări fundamentale, poate fi necesar să înceapă de la zero. Aceasta nu este o problemă semnificativă în comparație cu bugetul global.
Când vă pregătiți lista de sarcini pentru un proiect, luați în considerare următoarele gânduri:
Să mergem puțin în detaliu! Am oferit deja un exemplu pentru primul element din listă: nu împachetați un driver de bază de date în jurul unui strat de abstractizare a bazei de date. Fii suspect de tot ceea ce adaugă complexitatea stiva software-ului tău. Observați că abstractizarea este adesea furnizată de biblioteci terțe părți. De exemplu, în funcție de limbajul de programare, stratul de persistență, cum ar fi Hibernate (Java), Doctrină (PHP) sau Active Record (Ruby), vine cu abstractizarea bazei de date și cartografiere obiect-relațională. Fiecare bibliotecă adaugă complexitate. Trebuie menținut. Trebuie să se aplice actualizările, corecțiile și corecțiile de securitate.
Punem în aplicare caracteristici de zi cu zi, deoarece le anticipăm să fie utile. Prin urmare, ne gândim înainte și implementăm prea mult. De exemplu, mulți clienți doresc să aibă un site mobil. Mobile este un termen de înțelegere largă; nu este o decizie de proiectare. Este un caz de utilizare! Persoanele care folosesc un site mobil sunt, de asemenea, mobile. Aceasta înseamnă că aceștia ar putea dori să acceseze alte informații sau funcționalități decât un utilizator care vizitează site-ul plasat pe desktop. Gândiți-vă la un site cinematografic: utilizatorii din autobuz vor dori probabil să acceseze timpul de începere a filmelor viitoare, nu trailerul de 50 MB.
Conceptele negative pot fi deseori identificate prin lipsa unor cerințe nefuncționale.
Cu un buget adecvat, veți efectua o analiză dedicată a cerințelor pentru dispozitive mobile. Fără această analiză, veți furniza pur și simplu aceleași informații ca și pe site-ul desktop. Acest lucru va fi bine pentru multe situații! Deoarece browserele mobile sunt foarte inteligente în ajustarea site-urilor desktop la afișarea acestora, o abordare radicală YAGNI ar putea fi să nu scrie deloc un site mobil!
Cerințele non-funcționale nu descriu comportamentul unui software, ci descriu proprietăți suplimentare care pot fi folosite pentru a evalua calitatea software-ului. Deoarece descrierea calității software presupune cunoștințe despre software, conceptele proaste pot fi deseori identificate prin lipsa unor cerințe nefuncționale. Mentenabilitatea, nivelul de documentare și ușurința integrării sunt exemple pentru cerințele nefuncționale. Cerințele nefuncționale ar trebui să fie măsurabile. prin urmare, "Pagina ar trebui să se încarce rapid." este prea inconcret, "Pagina trebuie încărcată în maximum două secunde în timpul unui test de performanță mediu." este foarte concret și măsurabil. Dacă doriți să aplicați principiul YAGNI, presupuneți cerințe moderate non-funcționale dacă nu sunt menționate în concept (sau dacă sunt menționate, dar inconcrete). Dacă scrieți cerințele nefuncționale, fii realist: o corporație mică cu vizite de 20-50 de pagini pe zi nu necesită trei zile de performanță de optimizare - deoarece pagina trebuie încărcată suficient de repede, deoarece serverul nu este ocupat. În cazul în care corporația poate crește numărul de vizite zilnice, un server mai bun sau un pachet de găzduire nu ar trebui să fie prea scump.
Nu în ultimul rând, amintiți-vă regula 80:20 de la degetul mare!
Nu în ultimul rând, amintiți-vă de regula 80:20 de la degetul mare! Trebuie să identificăm părțile consumatoare de timp. Dacă o parte este absolut necesară, trebuie să o implementați. Întrebarea ar trebui să fie: cum îl veți implementa? Trebuie să fie ultimul cadru cu o comunitate mică? Trebuie să treceți la versiunea doar lansată a unei biblioteci dacă documentația nu este actualizată? Dacă utilizați noul CMS, când nu sunt disponibile toate extensiile? Cât de multă cercetare va fi necesară pentru a face acest lucru? "Așa am făcut întotdeauna." nu este o abordare captivantă, dar va face treaba fără surprize.
Este important să înțelegeți că toate acestea nu înseamnă că puteți începe să scrieți coduri murdare cu hack-uri de-a lungul drumului! Scrieți o aplicație ușoară, nu una dezordonată! in orice caz, Nu o să ai nevoie de ea este o abordare practică. Dacă ar cauza multe linii de cod pentru a reduce câteva linii de cod duplicate, eu personal cred că vă puteți referi eforturile la buget și unele unDRYness este ok. Este o aplicație mică. Prin urmare, complexitatea de întreținere adăugată este acceptabilă. Suntem în lumea reală.
Să ne întoarcem la gândul inital: ne place să construim lucruri. Când Beethoven a scris Variațiile Diabelli, a fost contract de muncă. Nu cred că a făcut compromisuri cu privire la buget. El a mers în plus, pentru că nu dorea să scrie muzică medie; el a vrut să scrie o compoziție perfectă.
Cu siguranță nu înseamnă că suntem cu toții geniali și că strălucirea noastră ar trebui să strălucească în fiecare linie de cod, dar îmi place să mă gândesc la arhitectura software ca și compoziții. Sunt un dezvoltator pasionat, pentru că vreau să construiesc compoziții perfecte și vreau să fiu mândru de lucrurile pe care le construiesc.
Dacă doriți să fiți un dezvoltator experimentat și experimentat, trebuie să-l stăpâniți Nu o să ai nevoie de ea principiu. Dacă vrei să-ți păstrezi pasiunea, trebuie să te lupți din când în când.
Principiile software sunt o modalitate de a privi software-ul. Pentru mine, un principiu bun ar trebui să se bazeze pe un concept simplu, dar ar trebui să evolueze într-o construcție complexă de idei atunci când se confruntă cu alte tehnici și filosofii. Care sunt principiile dvs. software preferate?