8.1 Dekomponering er alt
For klarhetens skyld, et bilde fra en god artikkel "Decoupling of Object-Oriented Systems", som illustrerer hovedpunktene som vil bli diskutert.
Synes du fortsatt at det er enkelt å designe en applikasjonsarkitektur?
8.2 Grensesnitt, implementeringsskjul
Hovedprinsippene for å redusere koblingen av systemet er prinsippene for OOP og prinsippet om innkapsling + abstraksjon + polymorfisme bak dem.
Det er hvorfor:
- Moduler skal være "svarte bokser" for hverandre (innkapsling) . Dette betyr at en modul ikke skal "klatre" inn i en annen modul og vite noe om dens interne struktur. Objekter i ett delsystem skal ikke ha direkte tilgang til objekter i et annet delsystem.
- Moduler/delsystemer skal kun samhandle med hverandre gjennom grensesnitt (det vil si abstraksjoner som ikke er avhengig av implementeringsdetaljer). Følgelig må hver modul ha et veldefinert grensesnitt eller grensesnitt for å samhandle med andre moduler.
Prinsippet om "black box" (innkapsling) lar oss vurdere strukturen til hvert delsystem uavhengig av andre delsystemer. Modulen, som er en "black box", kan relativt fritt endres. Problemer kan bare oppstå i krysset mellom forskjellige moduler (eller en modul og et miljø).
Og denne interaksjonen må beskrives i den mest generelle (abstrakte) formen, det vil si i form av et grensesnitt. I dette tilfellet vil koden fungere på samme måte med enhver implementering som er i samsvar med grensesnittkontrakten. Det er denne evnen til å jobbe med ulike implementeringer (moduler eller objekter) gjennom et enhetlig grensesnitt som kalles polymorfisme.
Det er derfor Servlet er et grensesnitt : nettbeholderen vet ikke noe om servlets, for det er noen objekter som implementerer Servlet-grensesnittet og det er det. Servlets vet også litt om strukturen til beholderen. Servlet-grensesnittet er den kontrakten, den standarden, den minste interaksjonen som er nødvendig for å få Java-webapplikasjoner til å ta over verden.
Polymorfisme er slett ikke overstyring av metoder, som noen ganger feilaktig antas, men først av alt, utskiftbarheten av moduler / objekter med samme grensesnitt eller "ett grensesnitt, mange implementeringer". For å implementere polymorfisme er arvemekanismen ikke nødvendig i det hele tatt. Dette er viktig å forstå fordi arv generelt bør unngås når det er mulig .
Takket være grensesnitt og polymorfisme oppnås nettopp muligheten til å modifisere og utvide koden uten å endre det som allerede er skrevet (Open-Closed Principle).
Så lenge interaksjonen mellom moduler er beskrevet utelukkende i form av grensesnitt og ikke er knyttet til spesifikke implementeringer, har du muligheten til å absolutt "smertefritt" for systemet erstatte en modul med en hvilken som helst annen som implementerer samme grensesnitt, samt legge til en ny og dermed utvide funksjonaliteten.
Det er som i LEGO-konstruktøren – grensesnittet standardiserer samhandlingen og fungerer som en slags kobling der enhver modul med passende kobling kan kobles til.
Fleksibiliteten til designeren er sikret ved at vi ganske enkelt kan erstatte en modul eller del med en annen med de samme koblingene (med samme grensesnitt), samt legge til så mange nye deler vi vil (samtidig, eksisterende deler er ikke endret eller endret på noen måte).
Grensesnitt lar deg bygge et enklere system, vurderer hvert delsystem som en helhet og ignorerer dets interne struktur. De lar moduler samhandle og vet samtidig ingenting om den interne strukturen til hverandre, og implementerer dermed prinsippet om minimal kunnskap, som er grunnlaget for løs kobling.
Jo mer generelle/abstrakte grensesnittene er definert og jo mindre begrensninger de legger på interaksjon, jo mer fleksibelt er systemet. Herfra følger faktisk enda et av prinsippene til SOLID - Interface Segregation Principle , som motsetter seg "tykke grensesnitt".
Han sier at store, klumpete grensesnitt bør brytes ned i mindre, mer spesifikke, slik at klienter til små grensesnitt (avhengig av moduler) kun vet om metodene de trenger å jobbe med.
Dette prinsippet er formulert som følger: "Kunder skal ikke være avhengig av metoder (vær oppmerksom på metoder) som de ikke bruker" eller "Mange spesialiserte grensesnitt er bedre enn ett universelt".
Det viser seg at svak tilkobling kun gis når interaksjonen og avhengighetene til moduler kun beskrives ved hjelp av grensesnitt, det vil si abstraksjoner, uten å bruke kunnskap om deres interne struktur og struktur. Og faktisk er innkapsling dermed implementert. I tillegg har vi muligheten til å utvide / endre oppførselen til systemet ved å legge til og bruke forskjellige implementeringer, det vil si på grunn av polymorfisme. Ja, vi kom igjen til OOP - Encapsulation, Abstraction, Polymorphism.
8.3 Fasade: modulgrensesnitt
Her vil en erfaren programmerer spørre: hvis designet ikke er på nivået av objekter som selv implementerer de tilsvarende grensesnittene, men på nivået av moduler, hva er da implementeringen av modulgrensesnittet?
Svar: når du snakker på språket til designmønstre, kan et spesielt objekt være ansvarlig for implementeringen av modulens grensesnitt - Fasade . Hvis du kaller metoder på et objekt som inneholder Gateway-suffikset (for eksempel MobileApiGateway), så er det mest sannsynlig en fasade.
En fasade er et grensesnittobjekt som akkumulerer et sett med operasjoner på høyt nivå for å jobbe med et bestemt delsystem, og skjuler dets interne struktur og sanne kompleksitet bak det . Gir beskyttelse mot endringer i delsystemimplementeringen. Fungerer som et enkelt inngangspunkt - "du sparker fasaden, og han vet hvem som må sparkes i dette undersystemet for å få det han trenger."
Du har nettopp blitt introdusert for et av de viktigste designmønstrene som lar deg bruke konseptet med grensesnitt når du designer moduler og dermed koble dem fra - "Facade".
I tillegg gjør «Facade» det mulig å jobbe med moduler på samme måte som med vanlige objekter og anvende alle de nyttige prinsippene og teknikkene som brukes i utformingen av klasser ved utforming av moduler.
Merk : Selv om de fleste programmerere forstår viktigheten av grensesnitt når de designer klasser (objekter), ser det ut til at mange oppdager ideen om å bruke grensesnitt på modulnivå også.
GO TO FULL VERSION