Intent

  • Az objektumok fa struktúrákba történő összeállítása egész parthierarchiák ábrázolásához. Az összetett lehetővé teszi, hogy az ügyfelek egységesen kezeljék az egyes objektumokat és az objektumok kompozícióit.
  • Rekurzív kompozíció
  • “A könyvtárak bejegyzéseket tartalmaznak, amelyek mindegyike lehet egy könyvtár.”
  • 1-ből sok “van egy” felfelé a “van egy” hierarchiában

Probléma

Az alkalmazásnak “primitív” és “összetett” objektumok hierarchikus gyűjteményét kell kezelnie. A primitív objektumok feldolgozását egyféleképpen kezelik, az összetett objektumok feldolgozását pedig másképp.Nem kívánatos, hogy minden objektum “típusát” le kelljen kérdezni, mielőtt megpróbáljuk feldolgozni.

Diszkusszió

Definiáljunk egy absztrakt alaposztályt (Component), amely meghatározza azt a viselkedést, amelyet egységesen kell gyakorolni minden primitív és összetett objektumra. Alosztályozzuk a Primitív és a Kompozit osztályokat a Komponens osztályból. Minden Composite objektum csak a Component absztrakt típushoz “kapcsolja” magát, mivel kezeli a “gyermekeit”.

Használja ezt a mintát minden olyan esetben, amikor “kompozitok vannak, amelyek komponenseket tartalmaznak, amelyek mindegyike lehet kompozit”.

A gyermekkezelési módszereket általában a Composite osztályban kell definiálni. Sajnos a primitívek és a kompozitok egységes kezelésére irányuló törekvés megköveteli, hogy ezeket a módszereket az absztrakt komponens osztályba helyezzük át. A “biztonság” kontra “átláthatóság” kérdések megvitatását lásd az alábbi “Vélemények” szakaszban.

Szerkezet

Kompozitok, amelyek Komponenseket tartalmaznak, amelyek mindegyike lehet egyKompozit.

Menük, amelyek menüelemeket tartalmaznak, amelyek mindegyike lehet egy menü.

Soroszlopos GUI elrendezéskezelők, amelyek widgeteket tartalmaznak, amelyek mindegyike lehet egy soroszlopos GUI elrendezéskezelő.

Fájlokat tartalmazó könyvtárak, amelyek mindegyike lehet egy könyvtár.

Elemeket tartalmazó konténerek, amelyek mindegyike lehet egy konténer.

Példa

A kompozit az objektumokat fa struktúrákba állítja össze, és lehetővé teszi az ügyfelek számára az egyes objektumok és kompozíciók egységes kezelését. Bár aPélda absztrakt, az aritmetikai kifejezések Composites. Egy aritmetikai kifejezés egy operandusból, egy operátorból (+ – * /),és egy másik operandusból áll. Az operandus lehet szám vagy egy másik aritmetikai kifejezés. Így a 2 + 3 és a (2 + 3) + (4 * 6) mindkettő érvényes kifejezés.

Check list

  1. Gondolj arra, hogy a problémád az “egész részek “hierarchikus kapcsolatok ábrázolásáról szól.
  2. Figyelj a heurisztikára: “Konténerek, amelyek konténereket tartalmaznak,amelyek mindegyike lehet konténer”. Például: “Összeállítások, amelyek komponenseket tartalmaznak, amelyek mindegyike lehet egy összeállítás.” Ossza fel a tartomány fogalmait konténerosztályokra és konténerosztályokra.
  3. Készítsen egy “legkisebb közös nevező” interfészt, amely felcserélhetővé teszi a konténereket és a konténereket. Meg kell határoznia azt a viselkedést, amelyet egységesen kell gyakorolni az összes konténer- és konténerobjektumon.
  4. Minden konténer- és konténerosztály “is a” kapcsolatot deklarál az interfészhez.
  5. Minden konténerosztály egy-több “has a” kapcsolatot deklarál az interfészhez.
  6. A konténerosztályok kihasználják a polimorfizmust, hogy delegálják a konténerobjektumaikat.
  7. A gyermekkezelési módszereket általában az összetett osztályban kell definiálni. Sajnos a Leaf és Composite objektumok egységes kezelésére való törekvés megkövetelheti, hogy ezeket a módszereket az absztrakt Component osztályba emeljük át. Lásd a Gang ofFourban a “biztonság” és az “átláthatóság” közötti kompromisszumok megvitatását.

Összefogási szabályok

  • A Composite és a Decorator szerkezeti ábrái hasonlóak, ami azt tükrözi, hogy mindkettő rekurzív kompozícióra támaszkodik az objektumok korlátlan számú szervezéséhez.
  • A Composite az Iteratorral járható át. A látogató műveletet alkalmazhat egy kompozit felett. A kompozit használhat Chain ofResponsibility-t, hogy a komponensek a globális tulajdonságokhoz a szülőjükön keresztül férhessenek hozzá. Használhatna Decorator-t is, hogy felülírja ezeket a tulajdonságokat a kompozíció részein. Használhat Observer-t, hogy egy objektumstruktúrát egy másikhoz kössön, és State-t, hogy egy komponens megváltoztassa a viselkedését, ahogy az állapota változik.
  • A kompozit lehetővé teszi, hogy egy Mediátort kisebb darabokból állítson össze rekurzív kompozícióval.
  • A Decorator célja, hogy felelősségeket adjon hozzá az objektumokhoz alosztályozás nélkül. A kompozit nem a díszítésre, hanem a reprezentációra összpontosít. Ezek a szándékok különbözőek, de kiegészítik egymást.Következésképpen a Composite-ot és a Decorator-t gyakran együtt használják.
  • A Flyweight-et gyakran kombinálják a Composite-tal, hogy közös levélcsomópontokat valósítsanak meg.

Opinions

A Composite minta lényege, hogy a Composite atomi módon kezelhető, akárcsak egy levél. Ha egyIterátor protokollt akarsz biztosítani, rendben, de szerintem ez kívül esik magán a mintán. A minta középpontjában az áll, hogy az ügyfél képes műveleteket végezni egy objektumon anélkül, hogy tudnia kellene, hogy sok objektum van benne.

Az objektumok heterogén gyűjteményének atomi (vagy transzparens) kezelésére való képesség megköveteli, hogy a “gyermekkezelés” interfész a kompozit osztályhierarchia gyökerénél (az absztrakt komponens osztály) legyen definiálva. Ez a választás azonban a biztonság rovására megy, mert az ügyfelek megpróbálhatnak értelmetlen dolgokat tenni, például objektumokat hozzáadni és eltávolítani a levélobjektumokból. Másrészt, ha “biztonságra tervezünk”, akkor agyermekkezelő interfészt a Composite osztályban deklaráljuk, és elveszítjük az átláthatóságot, mert a levelek és a Composites most különböző interfészekkel rendelkeznek.

A Composite minta Smalltalk implementációi általában nem a Component interfészben, hanem a Composite interfészben tartalmazzák a komponensek kezelésére szolgáló interfészt. A C++ implementációk általában a Component interfészbe helyezik. Ez egy rendkívül érdekes tény, amin gyakran elgondolkodom. Fel tudok ajánlani elméleteket a magyarázatára, de senki sem tudja biztosan, hogy miért igaz.

A komponensosztályaim nem tudják, hogy léteznek kompozitok. Nem nyújtanak segítséget a kompozitok navigálásához, sem a kompozitok tartalmának megváltoztatásához. Ez azért van, mert szeretném, ha az alaposztály(és minden származéka) újrafelhasználható lenne olyan kontextusokban, amelyek nem igénylik a kompozitokat. Ha egy alaposztály mutatója adott, és feltétlenül tudnom kell, hogy az egy kompozit-e vagy sem, akkor a dynamic_cast segítségével fogom ezt kideríteni. Azokban az esetekben, amikor a dynamic_cast túl drága, egy Visitor-t fogok használni.

Közös panasz: “Ha a Composite interfészt lefelé tolom aComposite osztályba, hogyan fogok felsorolni (azaz bejárni) egy komplex struktúrát?” A válaszom az, hogy amikor olyan viselkedéseim vannak, amelyek a Composite mintában bemutatotthoz hasonló hierarchiákat alkalmaznak, tipikusan Visitor-t használok, így a felsorolás nem jelent problémát – a Visitorknow minden esetben pontosan tudja, hogy milyen objektummal van dolga. AVisitornak nem kell minden objektumnak enumerációs interfészt biztosítania.

A Composite nem kényszerít arra, hogy minden Componentet Composite-ként kezeljünk. Csak azt mondja, hogy minden olyan műveletet, amit “egységesen” akarsz kezelni, a Component osztályba helyezd. Ha az add, remove és hasonlóműveleteket nem lehet, vagy nem szabad egységesen kezelni, akkor ne tedd őket a Component alaposztályba. Ne feledje egyébként, hogy az egyes minták szerkezeti diagramja nem határozza meg a mintát; csupán azt ábrázolja, hogy tapasztalataink szerint mi az általános megvalósítása. Csak azért, mert a Composite szerkezeti diagramja a gyermekkezelési műveleteket a Component alaposztályban mutatja, nem jelenti azt, hogy a minta minden megvalósításának ugyanezt kell tennie.

Támogassa ingyenes weboldalunkat és legyen Öné az eKönyv!

  • 22 tervezési minta és 8 alapelv mélyreható magyarázata
  • 406 jól strukturált, könnyen olvasható, szakzsargontól mentes oldal
  • 228 világos és hasznos illusztráció és diagram
  • Egy archívum kódpéldákkal 4 nyelven
  • Minden eszköz támogatott: EPUB/MOBI/PDF formátumokban

További információk…

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.