Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
ZveřejnilAlexandra Mašková
1
Prototyp
2
O čem to bude?
3
Prototyp Účel vytváření objektů nový objekt se vytváří kopírováním (klonováním) vzoru – prototypu
4
Prototyp – motivace Obecný grafický editor Graphic obecný grafický objekt Tool umí cosi dělat s objekty Graphic třída GraphicTool produkuje komponenty Graphic Editor hudebních partitur noty, pomlky,... – podtřídy Graphic problém – jak pomocí GraphicTool vytvářet instance konkrétních tříd? GraphicTool je obecná! řešení – GraphicTool bude „klonovat“ instanci podtřídy Graphic – prototyp GraphicTool je parametrizovaný tímto prototypem prototyp implementuje metodu Clone()
5
Motivace – Hudební framework Požadavky: Navrhnout hudební framework Návrh: Application specific classes Tool Manipulate() Staff Draw(Position) GraphicTool Manipulate() Graphic Draw(Position) GraphicToolStaff Manipulate() Nový potomek pro každou grafickou třídu Framework classes
6
Motivace – Hudební framework Požadavky: Navrhnout hudební framework Návrh: Elegantnější!!! Třídy aplikace Třídy frameworku
7
Prototyp – struktura Prototype: deklaruje rozhraní pro klonování ConcretePrototype: implementuje klonování Client: vytváří objekt zavoláním metody Clone() na prototypu Vylepšení: PrototypeManager (registr prototypů) Client operation() Prototype clone() prototype ConcretePrototype1 clone() ConcretePrototype2 clone() Vrací svou kopii p = prototype.clone()
8
Prototyp – příklad struktury abstraktní třída (rozhraní) pro grafické objekty nástroj pro tvorbu objektů je parametrizovaný konkrétní instancí - prototypem abstraktní třída pro manipulaci s grafickými objekty
9
Prototyp – použití Kdy se nám hodí? třídy specifikované za běhu nechceme duplikovat hierarchii tříd paralelní hierarchií továren jedna třída, několik málo stavů Co přinese? přidávání a odebírání prototypů za běhu specifikace nových objektů změnou hodnoty vytváření menšího počtu podtříd dynamická konfigurace aplikace pomocí tříd
10
Prototyp – implementace Operace Clone „mělká vs. hluboká“ kopie Mělká kopie Hluboká kopie pozor na cyklické reference!! builtin podpora C++ copy konstruktor Java: Object.clone(), interface Cloneable = prototyp C#: object.MemberwiseClone(), ICloneable AB AClone AB BClone @Override public Object clone() throws CloneNotSupportedException { A aClone = (A)super.clone(); aClone.b = (B)b.clone(); return aClone; }
11
Prototyp – implementace další parametry pro konstruktor? Clone() to neumí Initialize(...) pozor na deep copy a leaky Správce prototypů volitelně dynamický katalog, asociativní pole vyhledávání, registrace prototypů pro nějaký klíč
12
Prototyp – příklad implementace třída MazePrototypeFactory konstruktor MazePrototypeFactory přebírá prototypy jako argumenty ušetřili jsme tvorbu podtříd pro každý druh stěn nebo místností class MazePrototypeFactory : public MazeFactory { public: MazePrototypeFactory (Maze*, Wall*, Room*, Door*); virtual Maze* MakeMaze() const; virtual Room* MakeRoom(int) const; virtual Wall* MakeWall() const; virtual Door* MakeDoor(Room*, Room*) const; private: Maze* prototypeMaze_; Room* prototypeRoom_; Wall* prototypeWall_; Door* prototypeDoor_; }; MazePrototypeFactory:: MazePrototypeFactory ( Maze* m, Wall* w, Room* r, Door* d) { prototypeMaze_ = m; prototypeWall_ = w; prototypeRoom_ = r; prototypeDoor_ = d; }
13
Prototyp – příklad implementace jednoduché metody pro tvorbu (stěn, místností, dveří) klonují prototyp a potom ho inicializují bludiště vytvoříme pomocí MazePrototypeFactory inicializovanou prototypy základních komponent bludiště Wall* MazePrototypeFactory::MakeWall () const { return prototypeWall_->Clone(); } Door* MazePrototypeFactory:: MakeDoor (Room* r1, Room *r2) const { Door* door = prototypeDoor_->Clone(); door->Initialize(r1, r2); return door; } MazeGame game; MazePrototypeFactory simpleMazeFactory( new Maze, new Wall, new Room, new Door ); Maze* maze = game.CreateMaze(simpleMazeFactory);
14
Prototyp – příklad implementace změna typu bludiště – inicializovat MazePrototypeFactory pomocí jiné sady prototypů objekt, který chceme použít jako prototyp, např. instance Door, musí podporovat operaci Clone, případně operaci Initialize MazePrototypeFactory bombedMazeFactory( new Maze, new BombedWall, new RoomWithABomb, new Door); class Door : public MapSite { public: Door(); Door(const Door&); virtual void Initialize(Room*, Room*); virtual Door* Clone() const; virtual void Enter(); Room* OtherSideFrom(Room*); private: Room* room1_; Room* room2_; }; Door::Door (const Door& other) { room1_ = other.room1_; room2_ = other.room2_; } void Door::Initialize (Room* r1, Room* r2) { room1_ = r1; room2_ = r2; } Door* Door::Clone () const { return new Door(*this); }
15
Prototyp – příklad implementace podtřída BombedWall musí operaci Clone přetížit a implementovat příslušný kopírovací konstruktor klienti klonující prototyp neví o jeho konkrétní podtřídě např.: BombedWall::Clone() vrací Wall*, ale implementace vrací ukazatel na novou instanci podtřídy ( BombedWall* ) Skrývá podtřídu klientům class BombedWall : public Wall { public: BombedWall(); BombedWall(const BombedWall&); virtual Wall* Clone() const; bool HasBomb(); private: bool bomb_; }; BombedWall::BombedWall (const BombedWall& other) : Wall(other) { bomb_ = other.bomb_; } Wall* BombedWall::Clone () const { return new BombedWall(*this); }
16
Praktické využití: Cacheování dat
17
public interface IPrototype { IPrototype Clone(); } public class Configuration : IPrototype { private string fileInformation; public void GetFileInformation() { Thread.Sleep(5000); //Nahrazeni asynchronniho volani fileInformation = "Long file information"; } IPrototype IPrototype.Clone() { Configuration c = new Configuration(); c.fileInformation = this.fileInformation; return c; } public void ShowInformation() { Console.WriteLine("Showing " + fileInformation); }
18
Praktické využití: Cacheování dat public class PrototypeManager { private Dictionary list = newDictionary (); public void AddPrototype(IPrototype p, int index) { list.Add(index, p); } public IPrototype GetPrototype(int index) { return list[index].Clone(); }
19
Praktické využití: Cacheování dat static void Main(string[] args) { Configuration c = new Configuration(); DateTime startTime = DateTime.Now; c.GetFileInformation(); //takes long time to create the first time DateTime endTime = DateTime.Now; Console.WriteLine("First Configuration object took " + endTime.Subtract(startTime).TotalSeconds + " seconds"); UserProfile p = new UserProfile(); startTime = DateTime.Now; p.GetDatabaseInformation(); //takes long time to create the first time endTime = DateTime.Now; Console.WriteLine("First UserProfile object took " + endTime.Subtract(startTime).TotalSeconds + " seconds"); //add prototypes to the manager PrototypeManager manager = new PrototypeManager(); manager.AddPrototype(c, 0); manager.AddPrototype(p, 1); startTime = DateTime.Now; (manager.GetPrototype(0).Clone() as Configuration).ShowInformation(); //new prototype copy endTime = DateTime.Now; Console.WriteLine("Second Configuration object took " + endTime.Subtract(startTime).TotalSeconds + " seconds"); startTime = DateTime.Now; (manager.GetPrototype(1).Clone() as UserProfile).ShowInformation(); //new prototype copy endTime = DateTime.Now; Console.WriteLine("Second UserProfile object took " + endTime.Subtract(startTime).TotalSeconds + " seconds"); }
20
Výhody (shrnutí) Možnost vytvářet objekty bez znalosti konkrétních tříd Specifikace nových objektů změnou hodnoty (flexibilní chování) Snížení počtu podtříd Specifikace nových objektů změnou struktury (kompozice) Odstranění hierarchie továren Vytváření instancí = volání Clone() Implementace v prototypu – žádná jiná třída není ovlivněna.
21
Nevýhody Nutnost úpravy kódu, pokud třída neimplementuje metodu clone() Cyklické reference
22
Vztah k ostatním vzorům Factory method Snadná na implementaci Není moc komplexní Vytváří nový objekt od začátku Abstract Factory, Builder Vysoce flexibilní Komplexní Oddělení objektu od jeho vytváření Vytváří nový objekt od začátku Prototype Vysoce flexibilní Komplexní Objekt a způsob jeho vytváření jsou specifikovány na stejném místě Kopíruje již existující objekt
23
Typické využití Nástroj pro grafické prvky Elektrické obvody Hudební software Šablony Pokud je vytváření instance drahé např: parsování XML dat pouze jednou Cacheování dat z databází Pokud instance třídy mají málo možných stavů
24
Prototyp – shrnutí Shrnutí nové objekty se vytváří klonováním inteligence pro klonování je v prototypu, ne v továrně pozor na implementaci klonování
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.