„Tervezési minták (Sznikák)” változatai közötti eltérés

A VIK Wikiből
Ugrás a navigációhoz Ugrás a kereséshez
a
 
(17 közbenső módosítás, amit 2 másik szerkesztő végzett, nincs mutatva)
1. sor: 1. sor:
 
{{RightTOC}}
 
{{RightTOC}}
Néhány fontosabb, gyakrabban használt tervezési minta:
+
== Főbb kategóriák ==
 
=== Creational ===
 
=== Creational ===
 
* '''Factory method''': a leszármazottra bízza az objektum létrehozását
 
* '''Factory method''': a leszármazottra bízza az objektum létrehozását
20. sor: 20. sor:
 
* '''Command'''
 
* '''Command'''
  
----
+
== Részletes leírás ==
  
== Factory method ==
+
=== Factory method ===
 
'''Célja:''' A Factory Method lehetővé teszi, hogy az új példány létrehozását a leszármazott osztályra bízzuk. Szokás virtuális konstruktornak is nevezni.
 
'''Célja:''' A Factory Method lehetővé teszi, hogy az új példány létrehozását a leszármazott osztályra bízzuk. Szokás virtuális konstruktornak is nevezni.
 +
 
'''Példa:''' Framework, ami egyszerre több dokumentum kezelését támogatja (mint pl. a Visual Studio)
 
'''Példa:''' Framework, ami egyszerre több dokumentum kezelését támogatja (mint pl. a Visual Studio)
 +
 
'''Használjuk, ha'''
 
'''Használjuk, ha'''
 
* Egy osztály nem látja előre annak az objektumnak az osztályát, amit létre kell hoznia
 
* Egy osztály nem látja előre annak az objektumnak az osztályát, amit létre kell hoznia
 
* Ha egy osztály azt szeretné, hogy leszármazottai határozzák meg azt az objektumot, amit létre kell hoznia
 
* Ha egy osztály azt szeretné, hogy leszármazottai határozzák meg azt az objektumot, amit létre kell hoznia
== Abstract factory ==
+
 
 +
=== Abstract factory ===
 
'''Példa:''' Ablakos rendszerek, GUI vezérlőelemek (ablak, nyomógomb, kiválasztógomb, stb.)
 
'''Példa:''' Ablakos rendszerek, GUI vezérlőelemek (ablak, nyomógomb, kiválasztógomb, stb.)
 +
 
'''Használjuk, amikor'''
 
'''Használjuk, amikor'''
 
* a rendszernek függetlennek kell lennie az általa létrehozott dolgoktól ("termék" objektumok, pl. felhasználói felület elemek)
 
* a rendszernek függetlennek kell lennie az általa létrehozott dolgoktól ("termék" objektumok, pl. felhasználói felület elemek)
 
* a rendszernek több termékcsaláddal kell együttműködnie
 
* a rendszernek több termékcsaláddal kell együttműködnie
 
* a rendszernek szorosan összetartozó "termék" objektumok adott családjával kell dolgoznia, és ezt akarjuk kényszeríteni a rendszerben
 
* a rendszernek szorosan összetartozó "termék" objektumok adott családjával kell dolgoznia, és ezt akarjuk kényszeríteni a rendszerben
 +
 
'''Előnyök'''
 
'''Előnyök'''
 
* Elszigeteli a konkrét osztályokat
 
* Elszigeteli a konkrét osztályokat
 
* A termékcsaládokat könnyű kicserélni
 
* A termékcsaládokat könnyű kicserélni
 
* Elősegíti a termékek közötti konzisztenciát
 
* Elősegíti a termékek közötti konzisztenciát
 +
 
'''Hátrányok'''
 
'''Hátrányok'''
 
* Nehéz új termék hozzáadása. Ekkor az Abstract Factory egész hierarchiáját módosítani kell, mert az interfész rögzíti a létrehozható termékeket
 
* Nehéz új termék hozzáadása. Ekkor az Abstract Factory egész hierarchiáját módosítani kell, mert az interfész rögzíti a létrehozható termékeket
 
* Megjegyzés: ezt bizonyos esetekben ki lehet kerülni
 
* Megjegyzés: ezt bizonyos esetekben ki lehet kerülni
== Singleton ==
+
 
 +
=== Singleton ===
 
'''Célja:''' Biztosítja, hogy egy osztályból csak egy példányt lehessen létrehozni, és ehhez az egy példányhoz globális hozzáférést biztosít.
 
'''Célja:''' Biztosítja, hogy egy osztályból csak egy példányt lehessen létrehozni, és ehhez az egy példányhoz globális hozzáférést biztosít.
 +
 
'''Megoldás:'''
 
'''Megoldás:'''
 
* Legyen az osztály felelőssége, hogy csak egy példányt lehessen belőle létrehozni
 
* Legyen az osztály felelőssége, hogy csak egy példányt lehessen belőle létrehozni
54. sor: 62. sor:
 
** globális hozzáférés a példányhoz
 
** globális hozzáférés a példányhoz
 
A Singleton konstruktora protected láthatóságú! Ez garantálja, hogy csak a statikus Instance metódushíváson keresztül lehessen példányt létrehozni.
 
A Singleton konstruktora protected láthatóságú! Ez garantálja, hogy csak a statikus Instance metódushíváson keresztül lehessen példányt létrehozni.
 +
 
'''Kód (C#):'''  
 
'''Kód (C#):'''  
public class Singleton{
+
public class Singleton{
 
+
 
   private static Singleton instance = null;
 
   private static Singleton instance = null;
 
+
 
   public static Singleton Instance{
 
   public static Singleton Instance{
 
       get{
 
       get{
66. sor: 75. sor:
 
       }
 
       }
 
   }
 
   }
 
+
 
   protected Singleton() { }
 
   protected Singleton() { }
 
   public void Print() {...}
 
   public void Print() {...}
 
+
 
   }
 
   }
 
Használata:
 
Használata:
 
   Singleton s1 = Singleton.Instance;
 
   Singleton s1 = Singleton.Instance;
 
   Singleton.Instance.Print()
 
   Singleton.Instance.Print()
== Prototype ==
+
=== Prototype ===
 
'''Célja:''' a prototípus alapján új objektumpéldányok készítése
 
'''Célja:''' a prototípus alapján új objektumpéldányok készítése
 +
 
'''Példa:''' Grafikus keretrendszerre építve kottaszerkesztő alkalmazás elkészítése
 
'''Példa:''' Grafikus keretrendszerre építve kottaszerkesztő alkalmazás elkészítése
 +
 
'''Használjuk, ha'''
 
'''Használjuk, ha'''
 
* egy rendszernek függetlennek kell lennie a létrehozandó objektumok típusától
 
* egy rendszernek függetlennek kell lennie a létrehozandó objektumok típusától
86. sor: 97. sor:
 
Igazi, publikus, mély másolatot végző klónozáshoz implementálható az ICloneable interfész:
 
Igazi, publikus, mély másolatot végző klónozáshoz implementálható az ICloneable interfész:
 
* Object Clone() művelet (deep copy)
 
* Object Clone() művelet (deep copy)
 +
 
'''Előnyök'''
 
'''Előnyök'''
 
* objektumok hozzáadása és elvétele futási időben
 
* objektumok hozzáadása és elvétele futási időben
 
* új, változó struktúrájú objektumok létrehozása
 
* új, változó struktúrájú objektumok létrehozása
 
* redukált származtatás, kevesebb alosztály
 
* redukált származtatás, kevesebb alosztály
 +
 
'''Hátrányok'''
 
'''Hátrányok'''
 
* Minden egyes prototípusnak implementálnia kell a Clone() függvényt, ami igen bonyolult lehet
 
* Minden egyes prototípusnak implementálnia kell a Clone() függvényt, ami igen bonyolult lehet
== Adapter ==
+
 
 +
=== Adapter ===
 
'''Cél:''' Egy osztály interfészét olyan interfésszé konvertálja, amit a kliens vár. Lehetővé teszi olyan osztályok együttműködését, melyek egyébként az inkompatibilis interfészeik miatt nem tudnának együttműködni.
 
'''Cél:''' Egy osztály interfészét olyan interfésszé konvertálja, amit a kliens vár. Lehetővé teszi olyan osztályok együttműködését, melyek egyébként az inkompatibilis interfészeik miatt nem tudnának együttműködni.
 +
 
'''Példa:''' Grafikus editor
 
'''Példa:''' Grafikus editor
 
Objektum kompozícióval, delegálással oldja meg az adaptálást
 
Objektum kompozícióval, delegálással oldja meg az adaptálást
 +
 
'''Szereplők: '''
 
'''Szereplők: '''
 
* mint a Class Adapter-nél
 
* mint a Class Adapter-nél
101. sor: 117. sor:
 
* az adapter delegálja a művelet végrehajtását az Adaptee-ra
 
* az adapter delegálja a művelet végrehajtását az Adaptee-ra
 
* agy adapter képes több Adaptee-t is magában foglalni, beleértve azok alosztályait is
 
* agy adapter képes több Adaptee-t is magában foglalni, beleértve azok alosztályait is
 +
 
'''Használjuk, ha '''
 
'''Használjuk, ha '''
 
* egy olyan osztályt szeretnénk használni, amelynek interfésze nem megfelelő Adapter
 
* egy olyan osztályt szeretnénk használni, amelynek interfésze nem megfelelő Adapter
 
* egy újrafelhasználható osztályt szeretnénk készíteni, amely együttműködik előre nem látható vagy független szerkezetű osztályokkal (pluggable adapters)
 
* egy újrafelhasználható osztályt szeretnénk készíteni, amely együttműködik előre nem látható vagy független szerkezetű osztályokkal (pluggable adapters)
== Bridge ==
+
=== Bridge ===
'''Cél:''' Különválasztja az absztrakciót (interfészt) az implementációtól, hogy egymástól függetlenül lehessen �ket változtatni
+
'''Cél:''' Különválasztja az absztrakciót (interfészt) az implementációtól, hogy egymástól függetlenül lehessen őket változtatni
 +
 
 
'''Példa:''' hordozható ablakozós rendszer XWindow és Presentation Manager alá
 
'''Példa:''' hordozható ablakozós rendszer XWindow és Presentation Manager alá
 +
 
'''Előnyei'''  
 
'''Előnyei'''  
 
* az absztrakció és az implementáció különválasztása
 
* az absztrakció és az implementáció különválasztása
113. sor: 132. sor:
 
* az implementációs hierarchia külön lefordított komponensbe tehető, így ha ez ritkán változik, nagy projektek esetén nagymértékben gyorsítható a fordítás/buildelés ideje
 
* az implementációs hierarchia külön lefordított komponensbe tehető, így ha ez ritkán változik, nagy projektek esetén nagymértékben gyorsítható a fordítás/buildelés ideje
 
* ugyanaz az implementációs objektum, több helyen is felhasználható
 
* ugyanaz az implementációs objektum, több helyen is felhasználható
== Composite ==
+
 
 +
=== Composite ===
 
'''Célja:''' Rész-egész viszonyban álló objektumokat fastruktúrába rendezi. A kliensek számára lehetővé teszi, hogy az egyszerű és kompozit objektumokat egységesen kezelje.
 
'''Célja:''' Rész-egész viszonyban álló objektumokat fastruktúrába rendezi. A kliensek számára lehetővé teszi, hogy az egyszerű és kompozit objektumokat egységesen kezelje.
 +
 
'''Példa:''' Olyan grafikus alkalmazás, amely lehetővé teszi összetett grafikus objektumok létrehozását
 
'''Példa:''' Olyan grafikus alkalmazás, amely lehetővé teszi összetett grafikus objektumok létrehozását
 +
 
'''Használjuk, ha '''
 
'''Használjuk, ha '''
 
* objektumok rész-egész viszonyát szeretnénk kezelni
 
* objektumok rész-egész viszonyát szeretnénk kezelni
A kliensek számára el akarjuk rejteni, hogy egy objektum egyedi objektum vagy kompozit objektum: bizonyos szempontból egységesen szeretnénk kezelni őket.
+
* a kliensek számára el akarjuk rejteni, hogy egy objektum egyedi objektum vagy kompozit objektum: bizonyos szempontból egységesen szeretnénk kezelni őket.
Decorator
+
 
Célja: Objektumok funkciójának dinamikus kiterjesztése. Rugalmas alternatívája a leszármaztatásnak.
+
=== Decorator ===
Példa: Adott egy GUI keretrendszer (pl. Windows Forms-Decorator Formshoz, AWT-hez hasonló). Az ablakokokhoz, vezérlőelemekhez hozzá szeretnénk rendelni keretet (Border), görgetősávot (Scrollbar), Animációt (Animation), Árnyékot,... Ezeket tetszőleges kombinációban szeretnénk az osztályokhoz rendelni. Tegyük fel hogy beépítve NEM támogatja a keretrendszer!
+
'''Célja:''' Objektumok funkciójának dinamikus kiterjesztése. Rugalmas alternatívája a leszármaztatásnak.
Használjuk, ha  
+
 
Dinamikusan szeretnénk funkcionalitást/viselkedést hozzárendelni az egyes objektumokhoz
+
'''Példa:''' Adott egy GUI keretrendszer (pl. Windows Forms-Decorator Formshoz, AWT-hez hasonló). Az ablakokokhoz, vezérlőelemekhez hozzá szeretnénk rendelni keretet (Border), görgetősávot (Scrollbar), Animációt (Animation), Árnyékot,... Ezeket tetszőleges kombinációban szeretnénk az osztályokhoz rendelni. Tegyük fel hogy beépítve NEM támogatja a keretrendszer!
A funkcionalitást a kliens számára átlátszó módon szeretnénk az objektumhoz rendelni
+
 
Amikor a származtatás nem praktikus
+
'''Használjuk, ha '''
Előnyök:
+
* dinamikusan szeretnénk funkcionalitást/viselkedést hozzárendelni az egyes objektumokhoz
Sokkal rugalmasabb, mint a statikus öröklődés
+
* a funkcionalitást a kliens számára átlátszó módon szeretnénk az objektumhoz rendelni
Több testreszabható osztály határozza meg a tulajdonságokat
+
* amikor a származtatás nem praktikus
Hátrányok:
+
 
Némiképp bonyolultabb, mint az egyszerű öröklés (több osztály szerepel)
+
'''Előnyök '''
A decorator és a dekorált komponens interfésze ugyan azonos, de maga az osztály nem ugyanaz. Ha reflexióval építünk a konkrét típusra, akkor a dekorátor alkalmazása problémát okozhat.
+
* sokkal rugalmasabb, mint a statikus öröklődés
Facade
+
* több testreszabható osztály határozza meg a tulajdonságokat
Célja: Egységes interfészt definiál egy alrendszer interfészeinek halmazához. Magasabb szint� interfészt definiál, amin keresztül könnyebb az alrendszer használata.
+
 
Példa: Compiler; Többrétegű (többnyire üzleti) alkalmazások
+
'''Hátrányok '''
Használjuk, ha  
+
* némiképp bonyolultabb, mint az egyszerű öröklés (több osztály szerepel)
Egyszerű interfészt szeretnénk biztosítani egy komplex rendszer felé
+
* a decorator és a dekorált komponens interfésze ugyan azonos, de maga az osztály nem ugyanaz. Ha reflexióval építünk a konkrét típusra, akkor a dekorátor alkalmazása problémát okozhat.
Számos függ�ség van a kliens és az alrendszerek osztályai között. Ilyenkor ha létrehozva egy Facade-ot elősegítve az alrendszer függetlenségét és a hordozhatóságot
+
 
Layers (rétegelés) esetén
+
=== Facade ===
Megjegyzés:
+
'''Célja:''' Egységes interfészt definiál egy alrendszer interfészeinek halmazához. Magasabb szintű interfészt definiál, amin keresztül könnyebb az alrendszer használata.
Külön döntés, hogy engedünk-e hozzáférést az alrendszerek osztályaihoz
+
 
Elvileg nem akadályozza meg, hogy a kliensek felhasználják az alrendszerek osztályait, ha arra is szükségük van
+
'''Példa:''' Compiler; Többrétegű (többnyire üzleti) alkalmazások
Proxy
+
 
Célja: Objektum helyett egy helyettesít� objektumot használ, ami szabályozza az objektumhoz való hozzáférést
+
'''Használjuk, ha '''
Példa: Szövegszerkesztő (sok nagy méretű kép megjelenítésével)
+
* egyszerű interfészt szeretnénk biztosítani egy komplex rendszer felé
Struktúra:
+
* számos függőség van a kliens és az alrendszerek osztályai között. Ilyenkor ha létrehozva egy Facade-ot elősegítve az alrendszer függetlenségét és a hordozhatóságot
Subject: közös interfészt biztosít a Subject és a Proxy számára (ezáltal tud a minta működni)
+
* Layers (rétegelés) esetén
Realsubject: a valódi objektum, amit a proxy elrejt
+
 
Proxy: helyettesít� objektum. Tartalmaz egy referenciát a tényleges objektumra, hogy el tudja azt érni. Szabályozza a hozzáférést a tényleges objektumhoz, feladata lehet a tényleges objektum létrehozása és törlése is.
+
'''Megjegyzés '''
Típusok:
+
* külön döntés, hogy engedünk-e hozzáférést az alrendszerek osztályaihoz
Távoli Proxy: Távoli objektumok lokális megjelenítése átlátszó módon. A kliens nem is érzékeli, hogy a tényleges objektum egy másik címtartományban, vagy egy másik gépen van
+
* elvileg nem akadályozza meg, hogy a kliensek felhasználják az alrendszerek osztályait, ha arra is szükségük van
Virtuális Proxy: Nagy erőforrás igényű objektumok igény szerinti létrehozása (pl. kép)
+
 
Védelmi Proxy: A hozzáférést szabályozza különböz� jogok esetén
+
=== Proxy ===
Smart Pointer: Egy pointer egységbezárása, hogy bizonyos esetekben automatikus műveleteket hajtson végre (pl.:lockolás)
+
'''Célja:''' Objektum helyett egy helyettesítő objektumot használ, ami szabályozza az objektumhoz való hozzáférést
Template method
+
 
Cél: Egy műveleten belül algoritmus vázat definiál, és ennek néhány lépésének implementálását a leszármazott osztályra bízza.
+
'''Példa:''' Szövegszerkesztő (sok nagy méretű kép megjelenítésével)
Példa: Framework-ben dokumentum megnyitása
+
 
Előny:
+
'''Struktúra'''
Lehetővé teszi, hogy az algoritmus invariáns részeit egy helyen definiáljuk, és a változó részeket a leszármazott osztályban adjuk meg. Így megoldható a kódduplikálás elkerülése: a hierarchiában a közös kódrészeket a szülő osztályban egy helyen adjuk meg (template method), ami a különböző viselkedést megvalósító egyéb műveleteket hívja meg. Ezeket a "különböző viselkedést megvalósító egyéb műveleteket" a leszármazott osztályban felül kell/lehet definiálni.
+
* Subject: közös interfészt biztosít a Subject és a Proxy számára (ezáltal tud a minta működni)
 +
* Realsubject: a valódi objektum, amit a proxy elrejt
 +
* Proxy: helyettesítő objektum. Tartalmaz egy referenciát a tényleges objektumra, hogy el tudja azt érni. Szabályozza a hozzáférést a tényleges objektumhoz, feladata lehet a tényleges objektum létrehozása és törlése is.
 +
 
 +
'''Típusok '''
 +
* Távoli Proxy: Távoli objektumok lokális megjelenítése átlátszó módon. A kliens nem is érzékeli, hogy a tényleges objektum egy másik címtartományban, vagy egy másik gépen van
 +
* Virtuális Proxy: Nagy erőforrás igényű objektumok igény szerinti létrehozása (pl. kép)
 +
* Védelmi Proxy: A hozzáférést szabályozza különböző jogok esetén
 +
* Smart Pointer: Egy pointer egységbezárása, hogy bizonyos esetekben automatikus műveleteket hajtson végre (pl.:lockolás)
 +
 
 +
=== Template method ===
 +
'''Cél:''' Egy műveleten belül algoritmus vázat definiál, és ennek néhány lépésének implementálását a leszármazott osztályra bízza.
 +
 
 +
'''Példa:''' Framework-ben dokumentum megnyitása
 +
 
 +
'''Előny '''
 +
* lehetővé teszi, hogy az algoritmus invariáns részeit egy helyen definiáljuk, és a változó részeket a leszármazott osztályban adjuk meg. Így megoldható a kódduplikálás elkerülése: a hierarchiában a közös kódrészeket a szülő osztályban egy helyen adjuk meg (template method), ami a különböző viselkedést megvalósító egyéb műveleteket hívja meg. Ezeket a "különböző viselkedést megvalósító egyéb műveleteket" a leszármazott osztályban felül kell/lehet definiálni.
 
Lehetővé teszi ún. hook függvények definiálását: ezek kiterjesztési pontok a kódban.
 
Lehetővé teszi ún. hook függvények definiálását: ezek kiterjesztési pontok a kódban.
Command/Action
+
 
Cél: Egy kérés objektumként való egységbezárása. Ez lehetővé teszi a kliens különböző kérésekkel való felparaméterezését, a kérések sorba állítását, naplózását és visszavonását (undo)
+
=== Command/Action ===
 +
'''Cél:''' Egy kérés objektumként való egységbezárása. Ez lehetővé teszi a kliens különböző kérésekkel való felparaméterezését, a kérések sorba állítását, naplózását és visszavonását (undo)
 
Nagyon rendszerfüggő (C++, .NET, stb.) a koncepció és az implementáció is
 
Nagyon rendszerfüggő (C++, .NET, stb.) a koncepció és az implementáció is
Példa: felhasználói parancsok
+
 
Használjuk, ha  
+
'''Példa:''' felhasználói parancsok
Ha strukturált programban callback függvényt használnánk, OO programban használjunk commandot helyette.
+
 
Szeretnénk a kéréseket különböző időben kiszolgálni. Ilyenkor várakozási sort használunk, a command-ban tároljuk a paramétereket, majd akár különböző folyamatokból/szálakból is feldolgozhatjuk őket.
+
'''Használjuk, ha '''
Visszavonás támogatására – eltároljuk az előző állapotot a command-ban
+
* a strukturált programban callback függvényt használnánk, OO programban használjunk commandot helyette.
Előny:
+
* szeretnénk a kéréseket különböző időben kiszolgálni. Ilyenkor várakozási sort használunk, a command-ban tároljuk a paramétereket, majd akár különböző folyamatokból/szálakból is feldolgozhatjuk őket.
Elválasztja a parancsot kiadó objektumot attól, amelyik tudja, hogyan kell lekezelni
+
* visszavonás támogatására – eltároljuk az előző állapotot a command-ban
Kiterjeszthetővé teszi a Command specializálásával a parancs kezelését
+
 
Összetett parancsok támogatása
+
'''Előny '''
Egy parancs több GUI elemhez is hozzárendelhető: tipikusan menüelem és toolbar gomb
+
* elválasztja a parancsot kiadó objektumot attól, amelyik tudja, hogyan kell lekezelni
Könnyű hozzáadni új parancsokat, mert ehhez egyetlen létező osztályt sem kell változtatni.
+
* kiterjeszthetővé teszi a Command specializálásával a parancs kezelését
Memento
+
* összetett parancsok támogatása
Cél: Az egységbezárás megsértése nélkül a külvilág számára elérhetővé tenni az objektum bels� állapotát. Így az objektum állapota később visszaállítható.
+
* egy parancs több GUI elemhez is hozzárendelhető: tipikusan menüelem és toolbar gomb
Példa: Visszavonás (undo) funkció a Dokumentumban
+
* könnyű hozzáadni új parancsokat, mert ehhez egyetlen létező osztályt sem kell változtatni.
Struktúra:
+
 
Originator: az állapotát kell tudni visszaállítani.
+
=== Memento ===
A CreateMemento() elment (pontosabban visszaadja a state állapotot egy Memento objektum formájában)
+
'''Cél:''' Az egységbezárás megsértése nélkül a külvilág számára elérhetővé tenni az objektum belső állapotát. Így az objektum állapota később visszaállítható.
A SetMemento() visszaállít, (pontosabban beállítja a state állapotot a paraméterben megkapott Memento objektum alapján)
+
 
Memento: az Originator állapotát tárolja és elméletileg csak az Originator számára biztosít hozzáférést az állapothoz (state). Pl. C++-ban a friend alkalmazásával oldható ez meg.
+
'''Példa: '''Visszavonás (undo) funkció a Dokumentumban
CareTaker: nyilvántartja a Mementokat
+
 
Használjuk, ha  
+
'''Struktúra '''
Egy objektum (rész)állapotát kés�bb vissza kell állítani és egy közvetlen interfész az objektum állapotához használná az implementációs részleteket, vagyis megsértené az objektum egységbezárását
+
* Originator: az állapotát kell tudni visszaállítani.
Előnyök:
+
** A CreateMemento() elment (pontosabban visszaadja a state állapotot egy Memento objektum formájában)
Megőrzi az egységbezárás határait
+
** A SetMemento() visszaállít, (pontosabban beállítja a state állapotot a paraméterben megkapott Memento objektum alapján)
Egyszerűsíti az Originatort
+
* Memento: az Originator állapotát tárolja és elméletileg csak az Originator számára biztosít hozzáférést az állapothoz (state). Pl. C++-ban a friend alkalmazásával oldható ez meg.
Hátrányok:
+
* CareTaker: nyilvántartja a Mementokat
Memento használata sokszor erőforrásigényes
+
 
Nem mindig jósolható meg a Caretaker által lefoglalt hely, és ez sok is lehet
+
'''Használjuk, ha '''
Observer
+
* egy objektum (rész)állapotát később vissza kell állítani és egy közvetlen interfész az objektum állapotához használná az implementációs részleteket, vagyis megsértené az objektum egységbezárását
Cél: Hogyan tudják objektumok értesíteni egymást állapotuk megváltozásáról anélkül, hogy függőség lenne a konkrét osztályaiktól
+
 
Példa: MVC vagy Document-View architektúra - A felhasználó megváltoztatja az egyik nézeten az adatokat, hogyan frissítsük a többit?
+
'''Előnyök '''
Előnyök:
+
* megőrzi az egységbezárás határait
A modell kódjában csak egy IView lista van, így a modell független az egyes IView-t implementáló osztályoktól. A modell újrafelhasználható!
+
* egyszerűsíti az Originatort
Egy egyszerű mechanizmust kaptunk arra, hogy az összes view konzisztens nézetét mutassa az adatoknak.
+
 
A rendszer könnyen kiterjeszthető új view osztályokkal. Sem a modellt, sem a többi view osztályt nem kell ehhez módosítani.
+
'''Hátrányok '''
Lehetővé teszi, hogy egy objektum megváltozása esetén értesíteni tudjon tetszőleges más objektumokat anélkül, hogy bármit is tudna róluk. Ez az ún. observer minta lényege
+
* Memento használata sokszor erőforrásigényes
Struktúra:  
+
* nem mindig jósolható meg a Caretaker által lefoglalt hely, és ez sok is lehet
Subject: Tárolja a beregisztrált Observer-eket; Interfészt definiál Observer-ek be- és kiregisztrálására valamint értesítésére
+
 
Observer: Interfészt definiál azon objektumok számára, amelyek értesülni szeretnének a Subject-ben bekövetkezett változásról (Update művelet)
+
=== Observer ===
ConcreteSubject: Az observer-ek számára érdekes állapotot tárol; Értesíti a beregisztrált observer-eket, amikor az állapota megváltozik
+
'''Cél:''' Hogyan tudják objektumok értesíteni egymást állapotuk megváltozásáról anélkül, hogy függőség lenne a konkrét osztályaiktól
ConcreteObserver: Referenciát tárol a megfigyelt ConcreteSubject objektumra; Olyan állapotot tárol, amit a megfigyelt ConcreteSubject állapotával konzisztensen kell tartani; Implemetálja az Observer interfészét (Update művelet), ez az, amit a Subject meghív, amikor a ConcreteSubject állapota megváltozik. Ebben frissíti a saját állapotát a megfigyelt ConcreteSubject? állapotának megfelelően
+
 
Használjuk, ha:  
+
'''Példa:''' MVC vagy Document-View architektúra - A felhasználó megváltoztatja az egyik nézeten az adatokat, hogyan frissítsük a többit?
Amikor egy objektum megváltoztatása maga után vonja más objektumok megváltoztatását, és nem tudjuk, hogy hány objektumról van szó
+
 
Amikor egy objektumnak értesítenie kell más objektumokat az értesítendő objektum szerkezetére vonatkozó feltételezések nélkül
+
'''Előnyök'''
Megjegyzés: az Observer az egyik leggyakrabban használt minta
+
* a modell kódjában csak egy IView lista van, így a modell független az egyes IView-t implementáló osztályoktól. A modell újrafelhasználható!
Előnyök:
+
* egy egyszerű mechanizmust kaptunk arra, hogy az összes view konzisztens nézetét mutassa az adatoknak.
Laza kapcsolat a Subject és az Observer között
+
* a rendszer könnyen kiterjeszthető új view osztályokkal. Sem a modellt, sem a többi view osztályt nem kell ehhez módosítani.
Üzenetszórás támogatása
+
* Lehetővé teszi, hogy egy objektum megváltozása esetén értesíteni tudjon tetszőleges más objektumokat anélkül, hogy bármit is tudna róluk. Ez az ún. observer minta lényege
Hátrányok:
+
 
Felesleges Update-ek
+
'''Struktúra: '''
Az egyszerű Update alapján az Subject összes adatát le kell kérdezni (bár a Subject az Object::Update meghívásakor megadhatja paraméterként, hogy mi változott meg).
+
* Subject: Tárolja a beregisztrált Observer-eket; Interfészt definiál Observer-ek be- és kiregisztrálására valamint értesítésére
Az előbbi modellben a Subject ::Notifyt meghívó Observer-re is meghívódik az Update, holott az változtatta meg a ConcreteSubject állapotát
+
* Observer: Interfészt definiál azon objektumok számára, amelyek értesülni szeretnének a Subject-ben bekövetkezett változásról (Update művelet)
Iterator
+
* ConcreteSubject: Az observer-ek számára érdekes állapotot tárol; Értesíti a beregisztrált observer-eket, amikor az állapota megváltozik
Cél: Szekvenciális hozzáférést biztosít egy összetett (pl. lista) objektum elemeihez anélkül, hogy annak belső reprezentációját felfedné
+
* ConcreteObserver: Referenciát tárol a megfigyelt ConcreteSubject objektumra; Olyan állapotot tárol, amit a megfigyelt ConcreteSubject állapotával konzisztensen kell tartani; Implemetálja az Observer interfészét (Update művelet), ez az, amit a Subject meghív, amikor a ConcreteSubject állapota megváltozik. Ebben frissíti a saját állapotát a megfigyelt ConcreteSubject? állapotának megfelelően
Példa: Lista
+
 
Használjuk, ha  
+
'''Használjuk, ha: '''
Úgy szeretnénk hozzáférni egy objektum tartalmazott objektumaihoz, hogy nem akarjuk felfedni a bels� m�ködését
+
* egy objektum megváltoztatása maga után vonja más objektumok megváltoztatását, és nem tudjuk, hogy hány objektumról van szó
Többféle hozzáférést szeretnénk biztosítani a tartalmazott objektumokhoz
+
* egy objektumnak értesítenie kell más objektumokat az értesítendő objektum szerkezetére vonatkozó feltételezések nélkül
Egy időben több, egymástól független hozzáférést szeretnénk a lista elemeihez
+
 
Ha különböző tartalmazott struktúrákhoz szeretnénk hozzáférni hasonló interfésszel
+
'''Megjegyzés:''' az Observer az egyik leggyakrabban használt minta
State
+
 
Cél: Lehetővé teszi egy objektum viselkedésének megváltozását, amikor megváltozik az állapota.
+
'''Előnyök '''
Példa: TCPConnection osztály egy hálózati kapcsolatot reprezentál; Három állapota lehet: Listening, Established, Closed; A kéréseket az állapotától függően kezeli
+
* laza kapcsolat a Subject és az Observer között
Használjuk ha:
+
* üzenetszórás támogatása
Az objektum viselkedése függ az állapotától, és a viselkedését az aktuális állapotnak megfelel�en futás közben meg kell változtatnia
+
 
A műveleteknek nagy feltételes ágai vannak, melyek az objektum állapotától függenek
+
'''Hátrányok'''
Előnyök:
+
* felesleges Update-ek
Egységbezárja az állapotfüggő viselkedést, így könnyű új állapotok bevezetése
+
* az egyszerű Update alapján az Subject összes adatát le kell kérdezni (bár a Subject az Object::Update meghívásakor megadhatja paraméterként, hogy mi változott meg).
Áttekinthetőbb kód (nincs nagy switch-case szerkezet)
+
* Az előbbi modellben a Subject ::Notifyt meghívó Observer-re is meghívódik az Update, holott az változtatta meg a ConcreteSubject állapotát
A State objektumokat meg lehet osztani
+
 
Hátrányok:
+
=== Iterator ===
az osztályok száma (csak indokolt esetben használjuk)
+
'''Cél:''' Szekvenciális hozzáférést biztosít egy összetett (pl. lista) objektum elemeihez anélkül, hogy annak belső reprezentációját felfedné
Mediator
+
 
Cél: Olyan objektumot definiál, ami egységbe zárja, hogy objektumok egy csoportja hogyan éri el egymást (hogyan kommunikál egymással). Megoldja, hogy az egymással kommunikáló objektumoknak ne kelljen egymásra hivatkozást tárolniuk, ezáltal biztosítja az objektumok laza csatolását.  
+
'''Példa:''' Lista
Példa: Egy Form vagy dialógus ablak  
+
 
Szerkezet:  
+
'''Használjuk, ha '''
 +
* úgy szeretnénk hozzáférni egy objektum tartalmazott objektumaihoz, hogy nem akarjuk felfedni a belső működését
 +
* többféle hozzáférést szeretnénk biztosítani a tartalmazott objektumokhoz
 +
* egy időben több, egymástól független hozzáférést szeretnénk a lista elemeihez
 +
* különböző tartalmazott struktúrákhoz szeretnénk hozzáférni hasonló interfésszel
 +
 
 +
=== State ===
 +
'''Cél:''' Lehetővé teszi egy objektum viselkedésének megváltozását, amikor megváltozik az állapota.
 +
 
 +
'''Példa:''' TCPConnection osztály egy hálózati kapcsolatot reprezentál; Három állapota lehet: Listening, Established, Closed; A kéréseket az állapotától függően kezeli
 +
 
 +
'''Használjuk ha'''
 +
* az objektum viselkedése függ az állapotától, és a viselkedését az aktuális állapotnak megfelelően futás közben meg kell változtatnia
 +
* a műveleteknek nagy feltételes ágai vannak, melyek az objektum állapotától függenek
 +
 
 +
'''Előnyök'''
 +
* egységbezárja az állapotfüggő viselkedést, így könnyű új állapotok bevezetése
 +
* áttekinthetőbb kód (nincs nagy switch-case szerkezet)
 +
* a State objektumokat meg lehet osztani
 +
 
 +
'''Hátrányok '''
 +
* nő az osztályok száma (csak indokolt esetben használjuk)
 +
 
 +
=== Mediator ===
 +
'''Cél:''' Olyan objektumot definiál, ami egységbe zárja, hogy objektumok egy csoportja hogyan éri el egymást (hogyan kommunikál egymással). Megoldja, hogy az egymással kommunikáló objektumoknak ne kelljen egymásra hivatkozást tárolniuk, ezáltal biztosítja az objektumok laza csatolását.  
 +
 
 +
'''Példa:''' Egy Form vagy dialógus ablak  
 +
 
 +
'''Szerkezet: '''
 
Minden vezérlőelem tartalmaz egy referenciát a dialógus ablakra (mediátor)
 
Minden vezérlőelem tartalmaz egy referenciát a dialógus ablakra (mediátor)
 
A dialógus ablak minden vezérlőelemre tartalmaz egy referenciát
 
A dialógus ablak minden vezérlőelemre tartalmaz egy referenciát
Strategy
+
 
Cél: Algoritmusok egy csoportján belül az egyes algoritmusok egységbe zárása és egymással kicserélhetővé tétele. A kliens szemszögéből az általa használt algoritmusok szabadon kicserélhetőek.  
+
=== Strategy ===
Példa: A kliens objektum különféle sorrendező algoritmusokat használhat; A kliens tartalmaz egy SortAlgorithm típusú pointert/referenciát egy konkrét (QuickSort v. HeapSort) objektumra.  
+
'''Cél:''' Algoritmusok egy csoportján belül az egyes algoritmusok egységbe zárása és egymással kicserélhetővé tétele. A kliens szemszögéből az általa használt algoritmusok szabadon kicserélhetőek.  
-- Estrica - 2008.06.09.
+
 
 +
'''Példa:''' A kliens objektum különféle sorrendező algoritmusokat használhat; A kliens tartalmaz egy SortAlgorithm típusú pointert/referenciát egy konkrét (QuickSort v. HeapSort) objektumra.
 +
 
 +
[[Category:Infoalap]]

A lap jelenlegi, 2013. szeptember 14., 21:42-kori változata

Sablon:RightTOC

Főbb kategóriák

Creational

  • Factory method: a leszármazottra bízza az objektum létrehozását
  • Abstract factory: külön factory hierarchia létezik termékcsaládok létrehozására
  • Singleton: csak egy példány létezzen, ami bárhonnan közvetlenül elérhető
  • Prototype: egy prototípust használ az objektum létrehozására

Structural

  • Adapter
  • Bridge
  • Proxy
  • Composite
  • Facade

Behavioral

  • Template method
  • Iterator
  • Observer
  • Mediator
  • Strategy
  • Command

Részletes leírás

Factory method

Célja: A Factory Method lehetővé teszi, hogy az új példány létrehozását a leszármazott osztályra bízzuk. Szokás virtuális konstruktornak is nevezni.

Példa: Framework, ami egyszerre több dokumentum kezelését támogatja (mint pl. a Visual Studio)

Használjuk, ha

  • Egy osztály nem látja előre annak az objektumnak az osztályát, amit létre kell hoznia
  • Ha egy osztály azt szeretné, hogy leszármazottai határozzák meg azt az objektumot, amit létre kell hoznia

Abstract factory

Példa: Ablakos rendszerek, GUI vezérlőelemek (ablak, nyomógomb, kiválasztógomb, stb.)

Használjuk, amikor

  • a rendszernek függetlennek kell lennie az általa létrehozott dolgoktól ("termék" objektumok, pl. felhasználói felület elemek)
  • a rendszernek több termékcsaláddal kell együttműködnie
  • a rendszernek szorosan összetartozó "termék" objektumok adott családjával kell dolgoznia, és ezt akarjuk kényszeríteni a rendszerben

Előnyök

  • Elszigeteli a konkrét osztályokat
  • A termékcsaládokat könnyű kicserélni
  • Elősegíti a termékek közötti konzisztenciát

Hátrányok

  • Nehéz új termék hozzáadása. Ekkor az Abstract Factory egész hierarchiáját módosítani kell, mert az interfész rögzíti a létrehozható termékeket
  • Megjegyzés: ezt bizonyos esetekben ki lehet kerülni

Singleton

Célja: Biztosítja, hogy egy osztályból csak egy példányt lehessen létrehozni, és ehhez az egy példányhoz globális hozzáférést biztosít.

Megoldás:

  • Legyen az osztály felelőssége, hogy csak egy példányt lehessen belőle létrehozni
  • Biztosítson globális hozzáférést ehhez az egy példányhoz.

Az Instance osztály-művelet (statikus) meghívásával lehet példányt létrehozni, illetve az "egyetlen" példányt elérni. A Singleton::Instance()

  • Mindig ugyanazt az objektumot adja vissza
  • Bárhol leírható ez:
    • C++ esetén Singleton::Instance()
    • Java esetén Singleton.GetInstance()
    • C# esetén propertyvel célszerű: Singleton.Instance
    • globális hozzáférés a példányhoz

A Singleton konstruktora protected láthatóságú! Ez garantálja, hogy csak a statikus Instance metódushíváson keresztül lehessen példányt létrehozni.

Kód (C#):

public class Singleton{

  private static Singleton instance = null;

  public static Singleton Instance{
     get{
        if (instance == null)
           instance = new Singleton();
        return instance;
     }
  }

  protected Singleton() { }
  public void Print() {...}

  }

Használata:

  Singleton s1 = Singleton.Instance;
  Singleton.Instance.Print()

Prototype

Célja: a prototípus alapján új objektumpéldányok készítése

Példa: Grafikus keretrendszerre építve kottaszerkesztő alkalmazás elkészítése

Használjuk, ha

  • egy rendszernek függetlennek kell lennie a létrehozandó objektumok típusától
  • ha a példányosítandó osztályok futási időben határozhatók meg
  • ha nem akarunk nagy párhuzamos osztályhierarchiákat
  • amikor az objektumok felparaméterezése körülményes, és könnyebb egy prototípust inicializálni majd azt másolni

Minden objektum támogatja (Object osztály művelete):

  • protected Object MemberwiseClone() művelet (shallow copy)

Igazi, publikus, mély másolatot végző klónozáshoz implementálható az ICloneable interfész:

  • Object Clone() művelet (deep copy)

Előnyök

  • objektumok hozzáadása és elvétele futási időben
  • új, változó struktúrájú objektumok létrehozása
  • redukált származtatás, kevesebb alosztály

Hátrányok

  • Minden egyes prototípusnak implementálnia kell a Clone() függvényt, ami igen bonyolult lehet

Adapter

Cél: Egy osztály interfészét olyan interfésszé konvertálja, amit a kliens vár. Lehetővé teszi olyan osztályok együttműködését, melyek egyébként az inkompatibilis interfészeik miatt nem tudnának együttműködni.

Példa: Grafikus editor Objektum kompozícióval, delegálással oldja meg az adaptálást

Szereplők:

  • mint a Class Adapter-nél
  • az Adapter tartalmaz egy pointert vagy referenciát az Adaptee-ra
  • az adapter delegálja a művelet végrehajtását az Adaptee-ra
  • agy adapter képes több Adaptee-t is magában foglalni, beleértve azok alosztályait is

Használjuk, ha

  • egy olyan osztályt szeretnénk használni, amelynek interfésze nem megfelelő Adapter
  • egy újrafelhasználható osztályt szeretnénk készíteni, amely együttműködik előre nem látható vagy független szerkezetű osztályokkal (pluggable adapters)

Bridge

Cél: Különválasztja az absztrakciót (interfészt) az implementációtól, hogy egymástól függetlenül lehessen őket változtatni

Példa: hordozható ablakozós rendszer XWindow és Presentation Manager alá

Előnyei

  • az absztrakció és az implementáció különválasztása
  • az implementáció dinamikusan, akár futási időben is megváltoztatható
  • az implementációs részletek a klienstől teljesen elrejthetők
  • az implementációs hierarchia külön lefordított komponensbe tehető, így ha ez ritkán változik, nagy projektek esetén nagymértékben gyorsítható a fordítás/buildelés ideje
  • ugyanaz az implementációs objektum, több helyen is felhasználható

Composite

Célja: Rész-egész viszonyban álló objektumokat fastruktúrába rendezi. A kliensek számára lehetővé teszi, hogy az egyszerű és kompozit objektumokat egységesen kezelje.

Példa: Olyan grafikus alkalmazás, amely lehetővé teszi összetett grafikus objektumok létrehozását

Használjuk, ha

  • objektumok rész-egész viszonyát szeretnénk kezelni
  • a kliensek számára el akarjuk rejteni, hogy egy objektum egyedi objektum vagy kompozit objektum: bizonyos szempontból egységesen szeretnénk kezelni őket.

Decorator

Célja: Objektumok funkciójának dinamikus kiterjesztése. Rugalmas alternatívája a leszármaztatásnak.

Példa: Adott egy GUI keretrendszer (pl. Windows Forms-Decorator Formshoz, AWT-hez hasonló). Az ablakokokhoz, vezérlőelemekhez hozzá szeretnénk rendelni keretet (Border), görgetősávot (Scrollbar), Animációt (Animation), Árnyékot,... Ezeket tetszőleges kombinációban szeretnénk az osztályokhoz rendelni. Tegyük fel hogy beépítve NEM támogatja a keretrendszer!

Használjuk, ha

  • dinamikusan szeretnénk funkcionalitást/viselkedést hozzárendelni az egyes objektumokhoz
  • a funkcionalitást a kliens számára átlátszó módon szeretnénk az objektumhoz rendelni
  • amikor a származtatás nem praktikus

Előnyök

  • sokkal rugalmasabb, mint a statikus öröklődés
  • több testreszabható osztály határozza meg a tulajdonságokat

Hátrányok

  • némiképp bonyolultabb, mint az egyszerű öröklés (több osztály szerepel)
  • a decorator és a dekorált komponens interfésze ugyan azonos, de maga az osztály nem ugyanaz. Ha reflexióval építünk a konkrét típusra, akkor a dekorátor alkalmazása problémát okozhat.

Facade

Célja: Egységes interfészt definiál egy alrendszer interfészeinek halmazához. Magasabb szintű interfészt definiál, amin keresztül könnyebb az alrendszer használata.

Példa: Compiler; Többrétegű (többnyire üzleti) alkalmazások

Használjuk, ha

  • egyszerű interfészt szeretnénk biztosítani egy komplex rendszer felé
  • számos függőség van a kliens és az alrendszerek osztályai között. Ilyenkor ha létrehozva egy Facade-ot elősegítve az alrendszer függetlenségét és a hordozhatóságot
  • Layers (rétegelés) esetén

Megjegyzés

  • külön döntés, hogy engedünk-e hozzáférést az alrendszerek osztályaihoz
  • elvileg nem akadályozza meg, hogy a kliensek felhasználják az alrendszerek osztályait, ha arra is szükségük van

Proxy

Célja: Objektum helyett egy helyettesítő objektumot használ, ami szabályozza az objektumhoz való hozzáférést

Példa: Szövegszerkesztő (sok nagy méretű kép megjelenítésével)

Struktúra

  • Subject: közös interfészt biztosít a Subject és a Proxy számára (ezáltal tud a minta működni)
  • Realsubject: a valódi objektum, amit a proxy elrejt
  • Proxy: helyettesítő objektum. Tartalmaz egy referenciát a tényleges objektumra, hogy el tudja azt érni. Szabályozza a hozzáférést a tényleges objektumhoz, feladata lehet a tényleges objektum létrehozása és törlése is.

Típusok

  • Távoli Proxy: Távoli objektumok lokális megjelenítése átlátszó módon. A kliens nem is érzékeli, hogy a tényleges objektum egy másik címtartományban, vagy egy másik gépen van
  • Virtuális Proxy: Nagy erőforrás igényű objektumok igény szerinti létrehozása (pl. kép)
  • Védelmi Proxy: A hozzáférést szabályozza különböző jogok esetén
  • Smart Pointer: Egy pointer egységbezárása, hogy bizonyos esetekben automatikus műveleteket hajtson végre (pl.:lockolás)

Template method

Cél: Egy műveleten belül algoritmus vázat definiál, és ennek néhány lépésének implementálását a leszármazott osztályra bízza.

Példa: Framework-ben dokumentum megnyitása

Előny

  • lehetővé teszi, hogy az algoritmus invariáns részeit egy helyen definiáljuk, és a változó részeket a leszármazott osztályban adjuk meg. Így megoldható a kódduplikálás elkerülése: a hierarchiában a közös kódrészeket a szülő osztályban egy helyen adjuk meg (template method), ami a különböző viselkedést megvalósító egyéb műveleteket hívja meg. Ezeket a "különböző viselkedést megvalósító egyéb műveleteket" a leszármazott osztályban felül kell/lehet definiálni.

Lehetővé teszi ún. hook függvények definiálását: ezek kiterjesztési pontok a kódban.

Command/Action

Cél: Egy kérés objektumként való egységbezárása. Ez lehetővé teszi a kliens különböző kérésekkel való felparaméterezését, a kérések sorba állítását, naplózását és visszavonását (undo) Nagyon rendszerfüggő (C++, .NET, stb.) a koncepció és az implementáció is

Példa: felhasználói parancsok

Használjuk, ha

  • a strukturált programban callback függvényt használnánk, OO programban használjunk commandot helyette.
  • szeretnénk a kéréseket különböző időben kiszolgálni. Ilyenkor várakozási sort használunk, a command-ban tároljuk a paramétereket, majd akár különböző folyamatokból/szálakból is feldolgozhatjuk őket.
  • visszavonás támogatására – eltároljuk az előző állapotot a command-ban

Előny

  • elválasztja a parancsot kiadó objektumot attól, amelyik tudja, hogyan kell lekezelni
  • kiterjeszthetővé teszi a Command specializálásával a parancs kezelését
  • összetett parancsok támogatása
  • egy parancs több GUI elemhez is hozzárendelhető: tipikusan menüelem és toolbar gomb
  • könnyű hozzáadni új parancsokat, mert ehhez egyetlen létező osztályt sem kell változtatni.

Memento

Cél: Az egységbezárás megsértése nélkül a külvilág számára elérhetővé tenni az objektum belső állapotát. Így az objektum állapota később visszaállítható.

Példa: Visszavonás (undo) funkció a Dokumentumban

Struktúra

  • Originator: az állapotát kell tudni visszaállítani.
    • A CreateMemento() elment (pontosabban visszaadja a state állapotot egy Memento objektum formájában)
    • A SetMemento() visszaállít, (pontosabban beállítja a state állapotot a paraméterben megkapott Memento objektum alapján)
  • Memento: az Originator állapotát tárolja és elméletileg csak az Originator számára biztosít hozzáférést az állapothoz (state). Pl. C++-ban a friend alkalmazásával oldható ez meg.
  • CareTaker: nyilvántartja a Mementokat

Használjuk, ha

  • egy objektum (rész)állapotát később vissza kell állítani és egy közvetlen interfész az objektum állapotához használná az implementációs részleteket, vagyis megsértené az objektum egységbezárását

Előnyök

  • megőrzi az egységbezárás határait
  • egyszerűsíti az Originatort

Hátrányok

  • Memento használata sokszor erőforrásigényes
  • nem mindig jósolható meg a Caretaker által lefoglalt hely, és ez sok is lehet

Observer

Cél: Hogyan tudják objektumok értesíteni egymást állapotuk megváltozásáról anélkül, hogy függőség lenne a konkrét osztályaiktól

Példa: MVC vagy Document-View architektúra - A felhasználó megváltoztatja az egyik nézeten az adatokat, hogyan frissítsük a többit?

Előnyök

  • a modell kódjában csak egy IView lista van, így a modell független az egyes IView-t implementáló osztályoktól. A modell újrafelhasználható!
  • egy egyszerű mechanizmust kaptunk arra, hogy az összes view konzisztens nézetét mutassa az adatoknak.
  • a rendszer könnyen kiterjeszthető új view osztályokkal. Sem a modellt, sem a többi view osztályt nem kell ehhez módosítani.
  • Lehetővé teszi, hogy egy objektum megváltozása esetén értesíteni tudjon tetszőleges más objektumokat anélkül, hogy bármit is tudna róluk. Ez az ún. observer minta lényege

Struktúra:

  • Subject: Tárolja a beregisztrált Observer-eket; Interfészt definiál Observer-ek be- és kiregisztrálására valamint értesítésére
  • Observer: Interfészt definiál azon objektumok számára, amelyek értesülni szeretnének a Subject-ben bekövetkezett változásról (Update művelet)
  • ConcreteSubject: Az observer-ek számára érdekes állapotot tárol; Értesíti a beregisztrált observer-eket, amikor az állapota megváltozik
  • ConcreteObserver: Referenciát tárol a megfigyelt ConcreteSubject objektumra; Olyan állapotot tárol, amit a megfigyelt ConcreteSubject állapotával konzisztensen kell tartani; Implemetálja az Observer interfészét (Update művelet), ez az, amit a Subject meghív, amikor a ConcreteSubject állapota megváltozik. Ebben frissíti a saját állapotát a megfigyelt ConcreteSubject? állapotának megfelelően

Használjuk, ha:

  • egy objektum megváltoztatása maga után vonja más objektumok megváltoztatását, és nem tudjuk, hogy hány objektumról van szó
  • egy objektumnak értesítenie kell más objektumokat az értesítendő objektum szerkezetére vonatkozó feltételezések nélkül

Megjegyzés: az Observer az egyik leggyakrabban használt minta

Előnyök

  • laza kapcsolat a Subject és az Observer között
  • üzenetszórás támogatása

Hátrányok

  • felesleges Update-ek
  • az egyszerű Update alapján az Subject összes adatát le kell kérdezni (bár a Subject az Object::Update meghívásakor megadhatja paraméterként, hogy mi változott meg).
  • Az előbbi modellben a Subject ::Notifyt meghívó Observer-re is meghívódik az Update, holott az változtatta meg a ConcreteSubject állapotát

Iterator

Cél: Szekvenciális hozzáférést biztosít egy összetett (pl. lista) objektum elemeihez anélkül, hogy annak belső reprezentációját felfedné

Példa: Lista

Használjuk, ha

  • úgy szeretnénk hozzáférni egy objektum tartalmazott objektumaihoz, hogy nem akarjuk felfedni a belső működését
  • többféle hozzáférést szeretnénk biztosítani a tartalmazott objektumokhoz
  • egy időben több, egymástól független hozzáférést szeretnénk a lista elemeihez
  • különböző tartalmazott struktúrákhoz szeretnénk hozzáférni hasonló interfésszel

State

Cél: Lehetővé teszi egy objektum viselkedésének megváltozását, amikor megváltozik az állapota.

Példa: TCPConnection osztály egy hálózati kapcsolatot reprezentál; Három állapota lehet: Listening, Established, Closed; A kéréseket az állapotától függően kezeli

Használjuk ha

  • az objektum viselkedése függ az állapotától, és a viselkedését az aktuális állapotnak megfelelően futás közben meg kell változtatnia
  • a műveleteknek nagy feltételes ágai vannak, melyek az objektum állapotától függenek

Előnyök

  • egységbezárja az állapotfüggő viselkedést, így könnyű új állapotok bevezetése
  • áttekinthetőbb kód (nincs nagy switch-case szerkezet)
  • a State objektumokat meg lehet osztani

Hátrányok

  • nő az osztályok száma (csak indokolt esetben használjuk)

Mediator

Cél: Olyan objektumot definiál, ami egységbe zárja, hogy objektumok egy csoportja hogyan éri el egymást (hogyan kommunikál egymással). Megoldja, hogy az egymással kommunikáló objektumoknak ne kelljen egymásra hivatkozást tárolniuk, ezáltal biztosítja az objektumok laza csatolását.

Példa: Egy Form vagy dialógus ablak

Szerkezet: Minden vezérlőelem tartalmaz egy referenciát a dialógus ablakra (mediátor) A dialógus ablak minden vezérlőelemre tartalmaz egy referenciát

Strategy

Cél: Algoritmusok egy csoportján belül az egyes algoritmusok egységbe zárása és egymással kicserélhetővé tétele. A kliens szemszögéből az általa használt algoritmusok szabadon kicserélhetőek.

Példa: A kliens objektum különféle sorrendező algoritmusokat használhat; A kliens tartalmaz egy SortAlgorithm típusú pointert/referenciát egy konkrét (QuickSort v. HeapSort) objektumra.