Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Composite “Spojuj a panuj”.

Podobné prezentace


Prezentace na téma: "Composite “Spojuj a panuj”."— Transkript prezentace:

1 Composite “Spojuj a panuj”

2 Motivace - námořnictvo

3 Motivace

4 Naivní implementace Bez composite Třídy:
pro jednoduché objekty (Cruiser, Destroyer, ..) kontejner pro skupiny objektů (Fleet, Task Force, ..) Nutnost rozlišovat mezi objekty Chování kontejneru je jiné než u jednoduchých objektů private void Sail(Object obj) { if (obj is Ship) ((Ship) obj).sail(); else if (obj is Fleet) foreach(Object o in obj) Sail(o); }

5 Composite pattern Použití Účel
Když je potřeba vykonávat operace nad hierarchií objektů Hierarchie obsahuje různé typy objektů s odlišnými četnostmi Je možné hierarchii rekurzivně skládat (strom) Účel Používá stromovou strukturu pro reprezentaci hierarchie objektů typu část-celek Umožňuje uživateli ignorovat rozdíly mezi složenými a individuálními objekty K tomu implementuje několik metod, které musí být přístupné skrze hierarchii Redukuje složitost kódu

6 Composite – obecná struktura
for (Component c in components) c.operation();

7 Composite – účastníci Component Leaf (Cruiser, Destroyer)
Deklaruje interface pro objekty v kompozici Implementuje defaultní chování Leaf (Cruiser, Destroyer) (nemá potomky) Reprezentuje listové objekty v kompozici Definuje chování primitivních objektů Composite (Task force) Definuje chování složených komponent Uchovává potomky ve vhodné datové struktuře a umožňuje jejich správu Client (Naval commander) Používá objekty v kompozici přes rozhraní Component

8 Jednoduchý composite Chceme implementovat metodu sail() pro lodě a skupiny lodí Vytvoříme abstraktní třídu Component s metodami Add(), Remove(), Sail() public abstract class Component { public abstract void Sail(); public abstract void Add(Component c); public abstract void Remove(Component c); }

9 Jednoduchý composite Chceme implementovat metodu sail() pro lodě a skupiny lodí Vytvoříme abstraktní třídu Component s metodami Add(), Remove(), Sail() Vytvoříme třídy Composite a Leaf rozšiřující Component public class Composite : Component { List<Component> components = new List<Component>(); public override void Sail() foreach (var c in components) c.Sail(); } public override void Add(Component c) components.Add(c); public override void Remove(Component c) components.Remove(c);

10 Jednoduchý composite Chceme implementovat metodu sail() pro lodě a skupiny lodí Vytvoříme abstraktní třídu Component s metodami Add(), Remove(), Sail() Vytvoříme třídy Composite a Leaf rozšiřující Component public class Leaf extends Component { protected int fuel = 1000; // default fuel capacity protected int fuelConsumption = 10; // per mile public override void Sail(){ if (fuel > fuelConsumption) fuel -= fuelConsumtion; moveTo(..); } public override void Add(Component c) { // What to do here? } public override void Remove(Component c) { // What to do here? }

11 Jednoduchý composite Chceme implementovat metodu Sail() pro lodě a skupiny lodí Vytvoříme abstraktní třídu Component s metodami Add(), Remove(), Sail() Vytvoříme třídy Composit a Leaf rozšiřující Component Definujeme jednotlivé typy lodí a skupin Předáme uživateli (Commander) Ten si vytvoří strukturu -> může použít třeba builder Začne používat metodu Sail() Navy myRoyalNavy = NavyBuilder.Build() .AddFleet(new ForceGroup( new Carrier(), new Destroyer())) .AddShip(new StealthySubmarine()) .Get(); myRoyalNavy.Sail(); // We can define more: myRoyalNavy.SailOut(); myRoyalNavy.Attack(Enemy e); myRoyalNavy.FallBack(); myRoyalNavy.Dock();

12 Kdo deklaruje Add a Remove?
Component Transparentnější Ošetření neopatrnosti uživatele - defaultně error/výjimka (runtime) Bez ošetření může být rizikové public abstract class Component { public void Add(Component c) throw new InvalidOperationException(); }; public void Remove(Component c) }

13 Kdo deklaruje Add a Remove?
Component Transparentnější Ošetření neopatrnosti uživatele - defaultně error/výjimka (runtime) Bez ošetření může být rizikové Composite Bezpečnější (v staticky typovaných jazycích selže už při kompilaci) Nedodržuje transparentnost (Composite se liší od Component) public abstract class Component { public void Add(Component c) throw new InvalidOperationException(); }; public void Remove(Component c) }

14 getComposite() class Composite; class Component { //... virtual Composite GetComposite() { return null; } } class Composite : Component // ... void Add(Component); virtual Composite GetComposite() { return this; } class Leaf : public Component { }; Composite composite = new Composite; Component component = composite; Composite test = component.GetComposite(); if (test != null) { Test.Add(new Leaf); } GoF preferuje Add a Remove v Component s defaultním errorem z dnešního pohledu je výhodnější použít getComposite()

15 Možné úpravy Reference na rodiče Sdílení komponent
Zjednodušuje průchod a některé operace (delete) Je třeba zaručit invariant: Všichni potomci mají správné rodiče Sdílení komponent Redukce nároků na pamět/výkon Problematické, pokud ukládáme reference na rodiče => Flyweight Definice „class Component : List<Component>“ Už obsahuje metody Add a Remove Nebývá to dobrý nápad – zvětšuje paměťové nároky Pořadí uvnitř Composite Někdy potřebujeme prvky uvnitř Composite setřízené Např.: Aritmetická operace, u lodí specifická sekvence střelby, .. => Iterator Kešování Pro zlepšení výkonu Composite může ukládat informace získané z dětí Změna dat/vlastností komponenty musí být propagována do rodiče

16 Výhody a nevýhody Skrytí rozdílů mezi objekty a kolekcemi
Jednotlivé části lze libovolně skládat a zaměňovat Lehká integrace nových částí Uživatel na ni nemusí reagovat Composite může snížit výkon Je možné jej obejít? Plánujeme aplikaci rozšiřovat? Pokud obsahuje mnoho prvků, vytváří velký overhead Může učinit design příliš obecným Nutnost run-time kontroly typů objektů Maximalizace společného rozhraní nemusí dávat smysl např. Add() u listů U dynamicky typovaných jazyků existují lepší řešení

17 Composite – použití GUI Reprezentace XML
Komponenty a kontejnery Java: AWT, Swing, JSP … .NET: WinForms, WPF, Silverlight ...  C++: Qt, GTK+ …  Reprezentace XML  Destrukce objektů v OOP bez GC Parsing výrazů Reprezentace, interpretace Struktura souborů a adresářů  ... Téměř každá stromová struktura v OOP používá vzor Composite pattern-in-rdfowl.html

18 Související vzory Decorator Iterator Visitor Interpreter
Často používán s Composite Interface třídy Component z Decoratoru navíc obsahuje metody pro práci s dětmi Iterator Procházení potomků různými způsoby Visitor Lokalizuje operace a chování, které by jinak byly rozprostřeny v Composite i Leaf třídách Flyweight Pro sdílení komponent Interpreter Composite definuje strukturu pro reprezentaci jazyka, tu pak používá Interpreter Builder a Factories Pro vytváření hierarchie

19 Shrnutí Skrývá rozdíl mezi objektem a kolekcí těchto objektů
Definuje hierarchie tříd Zjednodušení kódu a práce klienta Jednoduchá struktura


Stáhnout ppt "Composite “Spojuj a panuj”."

Podobné prezentace


Reklamy Google