Decorator-designmønsteret ligner en vaffel

Dekoratormønsteret handler om at tilføje ekstra funktioner til et eksisterende objekt.

Lyder det som fransk?

Ingen problemer.

Vi vil vende tilbage til dette senere.

Lad os se på nogle vafler først!

Den geniale del om vafler er, at de starter almindeligt og enkelt. Fordi de er almindelige, smager næsten alt godt med dem

Nogle almindelige toppings til vafler er jordbær, blåbær, brombær, bananer, mandler og sirup.

Lad os prøve at oprette en samling af forskellige vaffelobjekter.

Der vil være StrawberryWaffle, BlueberryWaffle, BlackberryWaffle, BananaWaffle, AlmondWaffle og SirupWaffle.

Vent, vi kan have jordbær og blåbær på den samme vaffel. Dette giver os en StrawberryBlueberryWaffle.

Vi kan også have jordbær og brombær på den samme vaffel. Dette giver os en StrawberryBlackberryWaffle.

Ingen forbyder os at lægge tre påfyldninger på den samme vaffel. Dette giver os en StrawberryBlueberryBlackberryWaffle.

For at gøre tingene enkle, lad os overveje jordbær, blåbær og brombær som potentielt toppings. Der er otte forskellige kombinationer [1].

Betyder det, at vi er nødt til at skabe otte forskellige objekter til vores vaffelindsamling?

Hvis vi tilføjer bananer på vores potentielle toppings-liste, er der 16 forskellige kombinationer [2].

Det er indlysende, at tilføjelse af en enkelt topping på vores toppingsliste forårsager en eksplosion i vores vaffelindsamling.

Det er ikke muligt at oprette en anden vaffelklasse for hver mulig kombination af topfraktioner. Der skal være en bedre måde at gøre dette på.

Hvad hvis vi, når vi ønsker en StrawberryWaffle i stedet for at oprette en StrawberryWaffle, opretter en Waffle og tilføjer jordbær til den?

Hvad med StrawberryBlueberryWaffle da?

Vi kan oprette en vaffel, tilføje jordbær til den og tilføje blåbær til den!

Oprettelse af vaffelklasser

Lad os se på den almindelige vaffelklasse:

Du kan oprette en vaffel, servere den og spise den sådan:

Og her er StrawberryWaffle-klassen:

Bemærk, at vi passerer et vaffelobjekt inde i StrawberryWaffle-konstruktøren for at skabe en StrawberryWaffle.

StrawberryWaffle-klassen har:

  1. Den indleverede vaffel
  2. Jordbær som topping
  3. En serveringsmetode, der kalder den bestilte vaffels serveringsmetode. Derefter udskrives toppede med jordbær
  4. En spisemetode, der kalder den forbipasserede vaffels spisemetode og derefter udskriver og derefter spiser nogle jordbær

Du kan oprette en jordbærvaffel, servere den og spise den sådan:

Her er klassen BlueberryWaffle og BlackberryWaffle:

Og du kan bruge dem sådan:

Træk den fælles del ud

Når vi bemærker StrawberryWaffle-klassen, BlueberryWaffle-klassen og BlackberryWaffle-klassen er næsten identiske bortset fra deres topping, kan vi trække de fælles dele ud som en forældreklasse.

I WaffleDecorator er topping ikke længere en attribut for objektet. I stedet er det en metode, der kan tilsidesættes af en barneklasse.

Nu kan vi omskrive StrawberryWaffle, BlueberryWaffle og BlackberryWaffle for at arve WaffleDecorator for at få disse fælles funktionaliteter:

Og de skulle stadig arbejde på samme måde som før:

Her er de klasser, vi opretter:

Oprettelse af en BlueberryStrawberry-vaffel

Nu har vi Vaffel, StrawberryWaffle, BlueberryWaffle og BlackberryWaffle.

Det er tid til at nå det mål, vi oprindeligt satte os:

opret en vaffel, tilføj jordbær til den, og tilføj blåbær til den.

Ligesom dette:

Og vi kan:

Hvad sker der?!

Lad os se nærmere på, hvordan vi skabte blueberry_strawberry_waffle:

Først oprettede vi en plain_waffle med Waffle: plain_waffle = Waffle.new

Derefter skabte vi strawberry_waffle ved at føre plain_waffle ind i StrawberryWaffle-konstruktøren. strawberry_waffle = StrawberryWaffle.new (plain_waffle)

Det er værd at bemærke, at når vi opretter strawberry_waffle, holder vi den indleverede plain_waffle som en forekomstvariabel af strawberry_waffle:

Som vi kan se, er strawberry_waffle.waffle og plain_waffle det samme objekt:

På dette tidspunkt, når vi kalder strawberry_waffle.serve. Vi kalder først almindeligt_waffle.serve og derefter trykt toppet med jordbær.

For strawberry_waffle.eat kalder vi først almindeligt_waffle.eat, udskriv derefter og spiser derefter nogle jordbær.

Vi opretter blueberry_strawberry_waffle ved at videregive strawberry_waffle til BlueberryWaffle-konstruktøren. blueberry_strawberry_waffle = BlueberryStrawberryWaffle.new (strawberry_waffle)

Når vi opretter blueberry_strawberry_waffle, holder vi den indleverede strawberry_waffle som en forekomstvariabel af blueberry_strawberry_waffle:

Når vi kalder blueberry_strawberry_waffle.serve, kalder vi først strawberry_waffle.serve. Som kalder almindeligt_waffle.serve tryk derefter toppet med jordbær. Tryk derefter toppet med blåbær.

Når vi kalder blueberry_strawberry_waffle.eat, kalder vi først strawberry_waffle.eat. Hvilket kalder almindelig vaffel .eat udskrives derefter og spiser derefter jordbær. Udskriv derefter og spis derefter nogle blåbær.

Nøglen til magien:

strawberry_waffle er bygget ovenpå almindelig_waffle. Og blueberry_strawberry_waffle er bygget oven på strawberry_waffle.

Nøglen til at kunne bygge vafler oven på hinanden er at alle vafler skal adlyde den samme grænseflade.

Alle vafler har en serveringsmetode og en spisemetode.

Derfor er vi inden for StrawberryWaffle / BlueberryWaffle / BlackberryWaffleclasses sikre på, at den videregående vaffel har en serveringsmetode og en spisemetode.

Og vi kan udnytte serveringsmetoden og spisemetoden fra den indleverede vaffel, når vi definerer en ny serveringsmetode og en ny spisemetode.

En WaffleDecorator er ligeglad med den slags vaffel. Det kan være en almindelig vaffel, en jordbærvaffel eller en fremmedvaffel.

Det eneste, der betyder noget, er, at en WaffleDecorator tager en vaffel og returnerer en forbedret vaffel. Vaflen, den tager, og vaflen, den returnerer, adlyder den samme grænseflade.

Da alle dekoratører, der tager og returnerer vafler, adlyder den samme grænseflade, kan resultatet af en dekoratør overføres til en anden dekoratør.

Ligesom dette:

eller dette:

Nu med Vaffel, StrawberryWaffle, BlueberryWaffle og BlackberryWaffle kan vi skabe alle otte forskellige vafler.

Det er så let at tilføje banan på vores topliste som:

Du lærte lige dekoratormønsteret!

Her er dens definition:

Dekoratør lægger yderligere ansvar til et objekt dynamisk.

Takeaways:

  1. Dekoratormønsteret handler om let at tilføje yderligere funktioner til et eksisterende objekt.
  2. Objektet, der skal dekoreres (det, der sendes til alle dekoratører), og genstande, der returneres fra dekoratører, skal adlyde den samme grænseflade.

Tak for at have læst! Jeg håber du nyder artiklen.

Jeg udgiver ugentligt til sihui.io.

Tilmeld dig, så du ikke går glip af den næste artikel fra serien.

Næste gang kigger vi på…

]

[2] C (4, 0) + C (4, 1) + C (4, 2) + C (4, 3) + C (4, 4) = 16