Înlocuirea dependențelor directe cu mesagerie

Uneori, un modul trebuie doar să notifice pe alții că au avut loc unele evenimente/modificări în el și nu contează ce se întâmplă mai târziu cu aceste informații.

În acest caz, modulele nu trebuie deloc să „știe unul despre celălalt”, adică să conțină legături directe și să interacționeze direct, dar este suficient doar să schimbi mesaje (mesaje) sau evenimente (evenimente).

Uneori se pare că modul de comunicare prin mesagerie este mult mai slabă decât dependența directă. Într-adevăr, deoarece metodele nu sunt apelate, nu există informații despre clase. Dar aceasta nu este altceva decât o iluzie.

În loc de numele metodelor, logica începe să fie legată de tipurile de mesaje, parametrii acestora și datele transmise. Conectivitatea unor astfel de module este pătată.

Odinioară era așa: chemam metode - există conectivitate, nu apelăm metode - nu există conectivitate. Acum imaginați-vă că modulul A a început să trimită date ușor diferite în mesajele sale. Și, în același timp, toate modulele dependente de aceste mesaje nu vor funcționa corect.

Să presupunem, mai devreme, la adăugarea unui nou utilizator, modulul de autorizare a trimis mesajul USER_ADDED, iar după actualizare, a început să trimită acest mesaj atunci când încerca să se înregistreze și să indice suplimentar înregistrarea reușită sau nu în parametri.

Prin urmare, este foarte important să implementați mecanismul de mesaje în mod foarte competent. Există diverse șabloane pentru asta.

Observator. Este folosit în cazul dependenței unu-la-mulți, când multe module depind de starea unuia - a celui principal. Utilizează mecanismul de mailing, ceea ce înseamnă că modulul principal pur și simplu trimite aceleași mesaje tuturor abonaților săi, iar modulele interesate de aceste informații implementează interfața „abonat” și se abonează la lista de corespondență.

Această abordare este utilizată pe scară largă în sistemele cu o interfață cu utilizatorul, permițând nucleului aplicației (modelului) să rămână independent, informând în același timp interfețele asociate că ceva s-a schimbat și trebuie actualizat.

Aici formatul mesajului este standardizat la nivel de sistem de operare, ai cărui dezvoltatori trebuie să aibă grijă de compatibilitatea cu versiunea anterioară și de o documentare bună.

Organizarea interacțiunii prin distribuirea mesajelor are un „bonus” suplimentar - existența opțională a „abonaților” la mesajele „publicate” (adică trimise). Un sistem bine conceput ca acesta permite adăugarea/eliminarea modulelor în orice moment.

Autobuz de mesagerie

Puteți organiza schimbul de mesaje și puteți utiliza modelul Mediator pentru aceasta într-un mod diferit .

Este folosit atunci când există o dependență de la mulți la mulți dintre module. Mediatorul acționează ca un intermediar în comunicarea dintre module, acționând ca un centru de comunicare și eliminând necesitatea ca modulele să se refere în mod explicit unul la celălalt.

Ca urmare, interacțiunea modulelor între ele („toți cu toți”) este înlocuită de interacțiunea modulelor doar cu un intermediar („unu cu toți”). Se spune că mediatorul încapsulează interacțiunea dintre mai multe module.

Autobuz de mesagerie

Acesta este așa-numitul intermediar inteligent . Acolo dezvoltatorii încep cel mai adesea să-și adauge cârjele, care influențează comportamentul modulelor individuale prin activarea/dezactivarea primirii anumitor mesaje.

Un exemplu tipic din viața reală este controlul traficului aeroportuar. Toate mesajele de la aeronave merg la turnul de control al controlorului în loc să fie trimise direct între aeronave. Și controlorul ia deja decizii cu privire la avioanele care pot decolare sau ateriza și, la rândul său, trimite mesaje către avioane.

Important! Modulele se pot trimite reciproc nu numai mesaje simple, ci și obiecte de comandă. O astfel de interacțiune este descrisă de șablonul de comandă . Linia de jos este să încapsuleze o solicitare de a efectua o anumită acțiune ca obiect separat.

De fapt, acest obiect conține o singură metodă execute() , care vă permite apoi să treceți această acțiune altor module pentru execuție ca parametru și, în general, să efectuați orice operații cu obiectul de comandă care pot fi efectuate pe obiecte obișnuite.

Legea lui Demeter

Legea lui Demeter interzice utilizarea dependențelor implicite: „Obiectul A nu trebuie să poată accesa direct obiectul C dacă obiectul A are acces la obiectul B și obiectul B are acces la obiectul C”.

Aceasta înseamnă că toate dependențele din cod trebuie să fie „explicite” - clasele/modulele pot folosi doar „dependențele lor” în munca lor și nu ar trebui să treacă prin ele la alții. Un bun exemplu este o arhitectură cu trei niveluri. Stratul de interfață ar trebui să funcționeze cu stratul logic, dar nu ar trebui să interacționeze direct cu stratul bazei de date.

Pe scurt, acest principiu este și el formulat în acest fel: „Interacționează numai cu prietenii imediati, și nu cu prietenii prietenilor”. Acest lucru realizează mai puțină coerență a codului, precum și o mai mare vizibilitate și transparență a designului său.

Legea lui Demeter implementează deja menționat „principiul cunoștințelor minime”, care stă la baza cuplării libere și constă în faptul că un obiect/modul trebuie să cunoască cât mai puține detalii despre structura și proprietățile altor obiecte/module și orice în general, inclusiv propriile componente .

O analogie din viață: dacă vrei ca câinele să alerge, este o prostie să-i comanzi labele, este mai bine să-i dai comanda câinelui, iar ea se va ocupa singură de labele.

Compoziția în loc de moștenire

Acesta este un subiect foarte amplu și interesant și merită cel puțin o prelegere separată. Pe internet s-au spart multe exemplare pe această temă până s-a ajuns la un consens - folosim moștenirea la minim, compoziția - la maximum.

Ideea este că moștenirea oferă de fapt cea mai puternică conexiune între clase, așa că ar trebui evitată. Acest subiect este bine acoperit în articolul lui Herb Sutter „ Preferați compoziția față de moștenire ”.

Când începeți să învățați modele de design, veți întâlni o mulțime de modele care guvernează crearea unui obiect sau a structurii sale interne. Apropo, vă pot sfătui în acest context să acordați atenție modelului Delegat/Delegat și modelului Component , care a venit din jocuri .

Vom vorbi mai multe despre modele puțin mai târziu.

undefined
3
Опрос
Software architecture, client-server architecture, MVC,  14 уровень,  9 лекция
недоступен
Software architecture, client-server architecture, MVC
Software architecture, client-server architecture, MVC