8.1 Descompunerea este totul

Pentru claritate, o poză dintr-un articol bun „Decupling of Object-Oriented Systems”, ilustrând principalele puncte care vor fi discutate.

Descompunere

Încă mai credeți că proiectarea unei arhitecturi de aplicație este ușoară?

8.2 Interfețe, ascunderea implementării

Principalele principii de reducere a cuplării sistemului sunt principiile OOP și principiul Încapsulare + Abstracție + Polimorfism din spatele lor.

Acesta este motivul pentru care:

  • Modulele ar trebui să fie „cutii negre” unul pentru celălalt (încapsulare) . Aceasta înseamnă că un modul nu ar trebui să „urce” într-un alt modul și să știe nimic despre structura sa internă. Obiectele dintr-un subsistem nu ar trebui să acceseze direct obiectele dintr-un alt subsistem.
  • Modulele/subsistemele ar trebui să interacționeze între ele doar prin interfețe (adică abstracții care nu depind de detaliile implementării). În consecință, fiecare modul trebuie să aibă o interfață sau interfețe bine definite pentru a interacționa cu alte module.

Principiul „cutiei negre” (încapsulare) ne permite să luăm în considerare structura fiecărui subsistem independent de celelalte subsisteme. Modulul, care este o „cutie neagră”, poate fi schimbat relativ liber. Problemele pot apărea doar la joncțiunea diferitelor module (sau a unui modul și a unui mediu).

Și această interacțiune trebuie descrisă în cea mai generală formă (abstractă), adică sub forma unei interfețe. În acest caz, codul va funcționa la fel cu orice implementare care respectă contractul de interfață. Aceasta este capacitatea de a lucra cu diferite implementări (module sau obiecte) printr-o interfață unificată care se numește polimorfism.

De aceea Servlet este o interfață : containerul web nu știe nimic despre servlet-uri, pentru el acestea sunt câteva obiecte care implementează interfața Servlet și atât. Servlet-urile știu, de asemenea, puțin despre structura containerului. Interfața Servlet este acel contract, acel standard, acea interacțiune minimă care este necesară pentru ca aplicațiile web Java să cuprindă lumea.

Polimorfismul nu este deloc suprasolicitarea metodelor, așa cum se crede uneori greșit, ci, în primul rând, interschimbabilitatea modulelor/obiectelor cu aceeași interfață sau „o interfață, multe implementări”. Pentru a implementa polimorfismul, mecanismul de moștenire nu este deloc necesar. Acest lucru este important de înțeles deoarece moștenirea în general ar trebui evitată ori de câte ori este posibil .

Datorită interfețelor și polimorfismului, se realizează tocmai capacitatea de a modifica și extinde codul fără a schimba ceea ce este deja scris (Principiul Deschis-Închis).

Atâta timp cât interacțiunea modulelor este descrisă exclusiv sub formă de interfețe și nu este legată de implementări specifice, aveți posibilitatea de a înlocui absolut „nedureros” pentru sistem un modul cu oricare altul care implementează aceeași interfață, precum și adăugați unul nou și extindeți astfel funcționalitatea.

Este ca în constructorul LEGO - interfața standardizează interacțiunea și servește ca un fel de conector în care poate fi conectat orice modul cu un conector adecvat.

Flexibilitatea proiectantului este asigurată de faptul că putem înlocui pur și simplu un modul sau o piesă cu alta cu aceiași conectori (cu aceeași interfață), precum și să adăugăm câte piese noi dorim (în același timp, existente piesele nu sunt modificate sau modificate în niciun fel).

Interfețele vă permit să construiți un sistem mai simplu, luând în considerare fiecare subsistem ca întreg și ignorând structura lui internă. Ele permit modulelor să interacționeze și, în același timp, nu știu nimic despre structura internă a celuilalt, implementând astfel pe deplin principiul cunoștințelor minime, care stă la baza cuplării libere.

Cu cât interfețele sunt definite mai generale/abstracte și cu cât impun mai puține restricții asupra interacțiunii, cu atât sistemul este mai flexibil. De aici, urmează încă unul dintre principiile SOLID - Principiul segregației interfeței , care se opune „interfețelor groase”.

El spune că interfețele mari și voluminoase ar trebui împărțite în unele mai mici, mai specifice, astfel încât clienții interfețelor mici (module în funcție) să cunoască doar metodele cu care trebuie să lucreze.

Acest principiu este formulat după cum urmează: „Clienții nu trebuie să depindă de metode (să fie conștienți de metode) pe care nu le folosesc” sau „Multe interfețe specializate sunt mai bune decât una universală”.

Se pare că conectivitatea slabă este asigurată numai atunci când interacțiunea și dependențele modulelor sunt descrise numai cu ajutorul interfețelor, adică abstracțiuni, fără a folosi cunoștințele despre structura și structura lor internă.Și, de fapt, încapsularea este astfel implementată. În plus, avem capacitatea de a extinde / schimba comportamentul sistemului prin adăugarea și utilizarea diferitelor implementări, adică datorită polimorfismului. Da, am ajuns din nou la OOP - Encapsulation, Abstraction, Polymorphism.

8.3 Fațadă: interfață modul

Aici un programator cu experiență va întreba: dacă designul nu este la nivelul obiectelor care implementează ele însele interfețele corespunzătoare, ci la nivelul modulelor, atunci care este implementarea interfeței modulului?

Răspuns: vorbind în limbajul modelelor de design, atunci un obiect special poate fi responsabil pentru implementarea interfeței modulului - Fațadă . Dacă apelați metode pe un obiect care conține sufixul Gateway (de exemplu, MobileApiGateway), atunci cel mai probabil este o fațadă.

O fațadă este un obiect de interfață care acumulează un set de operațiuni de nivel înalt pentru lucrul cu un anumit subsistem, ascunzându-i structura internă și adevărata complexitate în spatele acestuia . Oferă protecție împotriva modificărilor în implementarea subsistemului. Servește ca un singur punct de intrare - „dai cu piciorul în fațadă și el știe cine trebuie să fie lovit în acest subsistem pentru a obține ceea ce are nevoie”.

Tocmai ați fost introdus în unul dintre cele mai importante modele de design care vă permite să utilizați conceptul de interfețe atunci când proiectați module și, prin urmare, să le decuplați - „Fațadă”.

În plus, „Fațada” face posibilă lucrarea cu module în același mod ca și cu obiectele obișnuite și aplicarea tuturor principiilor și tehnicilor utile care sunt utilizate în proiectarea claselor la proiectarea modulelor.

Fațadă: interfață modul

Notă : Deși majoritatea programatorilor înțeleg importanța interfețelor atunci când proiectează clase (obiecte), se pare că mulți descoperă ideea de a folosi interfețe și la nivel de modul.