2.1 Adapter

Adapter (Adapter) er et strukturelt designmønster designet for å organisere bruken av funksjonene til et objekt som ikke er tilgjengelig for modifikasjon gjennom et spesiallaget grensesnitt.

Den offisielle definisjonen er litt vanskelig, men hvis du beskriver den med dine egne ord, er en adapter et designmønster som lar objekter med inkompatible grensesnitt fungere sammen .

adaptermønster

Brukes til å organisere bruken av funksjonene til et objekt som ikke er tilgjengelig for modifikasjon gjennom et spesiallaget grensesnitt. Det opprettes en ekstra klasse som har det nødvendige grensesnittet, og denne klassen kaller på sin side metodene til det ønskede objektet (som ikke har det nødvendige grensesnittet).

Viktig! Hvis du i koden møter suffikset Adapter for en klasse, har du all rett til å vurdere at denne klassen fungerer som en adapter og er knyttet til en gruppe klasser som fungerer i henhold til skjemaet beskrevet ovenfor.

Det brukes i tilfeller der systemet støtter de nødvendige dataene og atferden, men har et upassende grensesnitt. Den vanligste bruken av Adapter-mønsteret er når du vil lage en klasse som arver fra en ny eller eksisterende abstrakt klasse.

Styrker:

  • Overgangen til å bruke andre eksterne klasser krever ikke omarbeiding av selve systemet, det er nok å implementere en adapterklasse til.
  • Uavhengighet fra implementering av eksterne klasser (klasser fra biblioteker hvis kode vi ikke kan endre). Programmet ditt blir uavhengig av grensesnittet til eksterne klasser.

2.2 Dekoratører

Decorator er et strukturelt designmønster for dynamisk å feste tilleggsatferd til et objekt. Decorator-mønsteret gir et godt og fleksibelt alternativ til praksisen med underklassing for å utvide funksjonaliteten.

Dekorasjonsmønster

Brukes til å dynamisk koble tilleggsforpliktelser til et objekt.

Mange av dere vil spørre: hvordan kan du dynamisk (mens programmet kjører) legge til ny atferd til et objekt? En gjenstand kan settes sammen av stykker, det vil si små gjenstander. Husker du filterkjeder i servlets? Eller Stream API når du skrev en spørring ved hjelp av filter(), map(), list()?

IntStream.of(50, 60, 70, 80, 90).filter(x -> x < 90).map(x -> x + 10).limit(3).forEach(System.out::print);

Styrkene til dekorasjonsmønsteret:

  • Det er ikke nødvendig å lage underklasser for å utvide funksjonaliteten til et objekt.
  • Muligheten til å dynamisk koble ny funksjonalitet hvor som helst: før eller etter hovedfunksjonaliteten til ConcreteComponent-objektet.

2.3 Fullmakter

Proxy er et strukturelt designmønster som gir et objekt som kontrollerer tilgang til et annet objekt, avskjærer og går gjennom alle dets samtaler.

Stedfortreder (fullmektig)

Proxy-mønsteret gir et erstatningsobjekt i stedet for det virkelige objektet. Dette objektet kontrollerer tilgangen til det opprinnelige objektet. Brukt veldig ofte.

Husker du hvordan vi brukte Mockito-rammeverket og fanget opp et kall til et virkelig objekt ved å bruke Mockito.spy()-metoden eller @Spy-kommentaren? Det var da et spesielt proxy-objekt ble opprettet, som alle anrop til det opprinnelige objektet gikk gjennom.

Og så kunne vi administrere disse anropene ved å legge til regler i objektet. Det stemmer – det opprinnelige objektet endres ikke, og arbeidet med det blir mye mer fleksibelt. Det er spesielt nyttig når vi ikke kaller proxy-objektet fra koden vår, men sender det et sted. Dermed kontrollerer kommunikasjonen av to objekter uavhengig av oss.

Typer fullmakter etter formål:

  • Logging proxy : logger alle anrop til "Emnet" med deres parametere.
  • Ekstern proxy (ekstern proxy): gir kommunikasjon med "Emnet", som er i et annet adresseområde eller på en ekstern maskin. Den kan også være ansvarlig for å kode forespørselen og dens argumenter og sende den kodede forespørselen til det virkelige "emnet".
  • Virtuell proxy (virtuelle proxyer): sikrer at det virkelige "emnet" opprettes kun når det virkelig er nødvendig. Den kan også cache noe av informasjonen om det virkelige "emnet" for å forsinke opprettelsen.
  • Kopier-på-skriv : Gir en kopi av "emnet" når klienten utfører visse handlinger (et spesialtilfelle av "virtuell proxy").
  • Beskyttelsesfullmakter : Kan sjekke om den som ringer har de nødvendige tillatelsene til å sende forespørselen.
  • Caching proxy : Gir midlertidig lagring av beregningsresultater før de vises til flere klienter som kan dele resultatene.
  • Screening Proxy: Beskytter "Emnet" fra farlige klienter (eller omvendt).
  • Synchronization Proxy : utfører synkronisert tilgangskontroll til "Emnet" i et asynkront flertrådsmiljø.
  • "Smart" lenke (smart referanse proxy): utfører tilleggshandlinger når en lenke til "Emnet" opprettes, beregner for eksempel antall aktive lenker til "Emnet".

2.4 Bro

Bromønsteret er et strukturelt designmønster som brukes til å "separere abstraksjon og implementering slik at de kan endres uavhengig."

Bromønsteret bruker innkapsling, aggregering og kan bruke arv for å dele ansvar mellom klasser.

Bro

Når abstraksjon og implementering er atskilt, kan de endre seg uavhengig. Med andre ord, når det implementeres gjennom bromønsteret, vil endring av strukturen til grensesnittet ikke forstyrre endring av strukturen til implementeringen.

Betrakt en slik abstraksjon som en figur. Det finnes mange typer former, hver med sine egne egenskaper og metoder. Det er imidlertid noe som forener alle figurene. For eksempel må hver form kunne tegne seg selv, målestokk og så videre.

Samtidig kan tegnegrafikk variere avhengig av typen OS eller grafikkbibliotek. Former skal kunne tegne seg selv i ulike grafiske miljøer. Men det er upraktisk å implementere alle tegnemetodene i hver form, eller å endre formen hver gang tegnemetoden endres.

I dette tilfellet hjelper bromønsteret, slik at du kan lage nye klasser som vil implementere tegning i forskjellige grafiske miljøer. Ved å bruke denne tilnærmingen er det veldig enkelt å legge til både nye former og måter å tegne dem på.

Forbindelsen representert av pilen i diagrammene kan ha 2 betydninger: a) "en slags", i samsvar med Liskov-substitusjonsprinsippet, og b) en av de mulige implementeringene av abstraksjonen. Språk bruker vanligvis arv for å implementere både a) og b), som har en tendens til å blåse opp klassehierarkier.

Broen tjener nøyaktig til å løse dette problemet: objekter lages i par fra et objekt av en klasse av hierarki A og hierarki B, arv innenfor hierarkiet A har betydningen "variasjon" i henhold til Liskov, og for konseptet "implementering" av abstraksjon» brukes en kobling fra objekt A til dets sammenkoblede objekt B.

2.5 Fasade

Fasademønsteret er et strukturelt designmønster som skjuler kompleksiteten til et system ved å redusere alle mulige eksterne anrop til et enkelt objekt som delegerer dem til de aktuelle objektene i systemet.

Fasademal

Hvordan gi et enhetlig grensesnitt med et sett med forskjellige implementeringer eller grensesnitt, for eksempel til et undersystem, hvis sterk kobling til det undersystemet er uønsket, eller implementeringen av undersystemet kan endre seg?

Definer ett interaksjonspunkt med delsystemet - et fasadeobjekt som gir et felles grensesnitt med delsystemet, og tildel det ansvaret for å samhandle med dets komponenter. En fasade er et eksternt objekt som gir et enkelt inngangspunkt for delsystemtjenester.

Implementeringen av andre delsystemkomponenter er privat og ikke synlig for eksterne komponenter. Fasadeobjekt gir en implementering av GRASP-mønsteret Motstandsdyktig mot endringer når det gjelder beskyttelse mot endringer i implementeringen av delsystemet.

Viktig! Dette mønsteret brukes når vi ønsker å skjule en gruppe objekter fullstendig og sende all kommunikasjon med dem gjennom objektet vårt. Hvis du bare vil gi litt kontroll over kommunikasjonsprosessen til objekter og ikke nødvendigvis skjule dem, er det bedre å bruke proxy-mønsteret.