Udskiftning af direkte afhængigheder med beskeder

Nogle gange skal et modul bare give andre besked om, at der er sket nogle hændelser/ændringer i det, og det er lige meget, hvad der sker med denne information senere.

I dette tilfælde behøver modulerne slet ikke at "kende hinanden", det vil sige indeholde direkte links og interagere direkte, men det er nok bare at udveksle beskeder (beskeder) eller begivenheder (begivenheder).

Nogle gange ser det ud til, at modulkommunikation via beskeder er meget svagere end direkte afhængighed. Fordi metoderne ikke kaldes, er der ingen information om klasserne. Men dette er ikke andet end en illusion.

I stedet for metodenavne begynder logikken at blive bundet til meddelelsestyper, deres parametre og transmitterede data. Forbindelsen af ​​sådanne moduler er udtværet.

Det plejede at være sådan: vi kalder metoder - der er forbindelse, vi kalder ikke metoder - der er ingen forbindelse. Forestil dig nu, at modul A begyndte at sende lidt anderledes data i sine beskeder. Og samtidig vil alle moduler, der er afhængige af disse meddelelser, ikke fungere korrekt.

Antag, at autorisationsmodulet tidligere, når du tilføjede en ny bruger, sendte meddelelsen USER_ADDED, og ​​efter opdateringen begyndte den at sende denne meddelelse, når den forsøgte at registrere og desuden angive vellykket registrering eller ej i parametrene.

Derfor er det meget vigtigt at implementere beskedmekanismen meget kompetent. Der er forskellige skabeloner til dette.

Observatør. Det bruges i tilfælde af en-til-mange-afhængighed, når mange moduler afhænger af tilstanden af ​​en - den vigtigste. Det bruger mailing-mekanismen, hvilket betyder, at hovedmodulet simpelthen sender de samme beskeder til alle sine abonnenter, og de moduler, der er interesseret i denne information, implementerer "abonnent"-grænsefladen og abonnerer på postlisten.

Denne tilgang er meget udbredt i systemer med en brugergrænseflade, hvilket gør det muligt for kernen af ​​applikationen (modellen) at forblive uafhængig og samtidig informere dens tilknyttede grænseflader om, at noget er ændret og skal opdateres.

Her er beskedformatet standardiseret på styresystemniveau, hvis udviklere skal sørge for bagudkompatibilitet og god dokumentation.

Organiseringen af ​​interaktion gennem distribution af beskeder har en ekstra "bonus" - den valgfrie eksistens af "abonnenter" til "offentliggjorte" (det vil sige udsendte) beskeder. Et veldesignet system som dette gør det muligt at tilføje/fjerne moduler til enhver tid.

Beskeder bus

Du kan organisere udvekslingen af ​​beskeder og bruge Mediator- mønsteret til dette på en anden måde .

Det bruges, når der er en mange-til-mange afhængighed mellem moduler. Mediatoren fungerer som et mellemled i kommunikationen mellem moduler, fungerer som et kommunikationscenter og eliminerer behovet for, at moduler eksplicit henviser til hinanden.

Som et resultat heraf erstattes modulernes interaktion med hinanden ("alle med alle") af samspillet mellem moduler kun med en mellemmand ("én med alle"). Mediatoren siges at indkapsle interaktionen mellem flere moduler.

Beskeder bus

Dette er den såkaldte smarte mellemmand . Det er der, at udviklere oftest begynder at tilføje deres krykker, som påvirker individuelle modulers adfærd ved at tænde/slukke for modtagelse af bestemte beskeder.

Et typisk virkeligt eksempel er lufthavnstrafikkontrol. Alle beskeder fra fly går til flyvelederens kontroltårn i stedet for at blive sendt direkte mellem flyene. Og flyvelederen træffer allerede beslutninger om, hvilke fly der kan lette eller lande, og sender til gengæld beskeder til flyene.

Vigtig! Moduler kan sende hinanden ikke kun simple beskeder, men også kommandoobjekter. Sådan interaktion er beskrevet af kommandoskabelonen . Den nederste linje er at indkapsle en anmodning om at udføre en specifik handling som et separat objekt.

Faktisk indeholder dette objekt en enkelt execute()- metode , som så giver dig mulighed for at videregive denne handling til andre moduler til udførelse som en parameter og generelt udføre alle operationer med kommandoobjektet, der kan udføres på almindelige objekter.

Demeters lov

Demeterloven forbyder brugen af ​​implicitte afhængigheder: "Objekt A må ikke være i stand til at få direkte adgang til objekt C, hvis objekt A har adgang til objekt B og objekt B har adgang til objekt C."

Det betyder, at alle afhængigheder i koden skal være "eksplicitte" - klasser / moduler kan kun bruge "deres afhængigheder" i deres arbejde og bør ikke klatre igennem dem til andre. Et godt eksempel er en tre-lags arkitektur. Grænsefladelaget skal fungere med det logiske lag, men bør ikke interagere direkte med databaselaget.

Kort fortalt er dette princip også formuleret på denne måde: "Interager kun med umiddelbare venner, og ikke med venners venner." Dette opnår mindre sammenhæng i koden, samt større synlighed og gennemsigtighed af dens design.

Demeterloven implementerer det allerede nævnte ”princip om minimumsviden”, som er grundlaget for løs kobling og består i, at et objekt/modul skal kende så få detaljer som muligt om andre objekters/modulers opbygning og egenskaber. alt generelt, inklusive dets egne komponenter .

En analogi fra livet: Hvis du vil have hunden til at løbe, er det dumt at kommandere dens poter, det er bedre at give kommandoen til hunden, og hun vil selv håndtere sine poter.

Sammensætning i stedet for arv

Dette er et meget stort og interessant emne, og det fortjener i det mindste en separat forelæsning. Mange kopier blev brudt om dette emne på internettet, indtil en konsensus blev nået - vi bruger arv til et minimum, sammensætning - til det maksimale.

Pointen er, at arv faktisk giver den stærkeste sammenhæng mellem klasserne, så det bør undgås. Dette emne er godt dækket i Herb Sutters artikel " Foretrække sammensætning frem for arv ".

Når du begynder at lære designmønstre, vil du støde på en hel masse mønstre, der styrer skabelsen af ​​et objekt eller dets interne struktur. Jeg kan i øvrigt råde til i denne sammenhæng at være opmærksom på Delegate/Delegate mønsteret og Component mønsteret, som kom fra spil .

Vi vil tale mere om mønstre lidt senere.