1 / 29

02 - Creational Design Patterns – 2

02 - Creational Design Patterns – 2. Moshe Fresko Bar-Ilan University תשס"ח 2008. Builder. Moshe Fresko Bar-Ilan University תשס"ו - 2005-2006 Design Patterns Course. Builder.

Télécharger la présentation

02 - Creational Design Patterns – 2

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 02 - Creational Design Patterns – 2 Moshe Fresko Bar-Ilan University תשס"ח 2008

  2. Builder Moshe Fresko Bar-Ilan University תשס"ו - 2005-2006 Design Patterns Course

  3. Builder • Intent: Separate the construction of a complex object from its representation so that the same construction process can create different representations. • Motivation: • An RTF reader should be able to convert an RTF document to many text formats. The number of possible conversions are open-ended. • Plain ASCII Text • Text Widget for Editing • RTF-Reader parses the RTF document. It uses Text-Converter to perform the conversion. • Whenever the RTF-Reader recognizes an RTF token it issues a request to the Text-Converter to convert the token.

  4. Builder – Motivation • Each converter class is called a Builder, and the reader is called the Director.

  5. Builder – Applicability • Use the Builder pattern when • The algorithm for creating a complex object should be independent of the parts that make up the object and how they are assembled. • The construction process must allow different representations for the object that is constructed.

  6. Builder – Structure

  7. Builder - Participants • Builder (TextConverter) • Specifies an abstract interface for creating parts of a product object. • ConcreteBuilder (AsciiConverter, TeXConverter, …) • Constructs and assembles parts of products • Defines and keeps track of the representation it creates • Provides an interface for retrieving the product • Director (RTFReader) • Constructs an object using the Builder interface • Product (AsciiText, TeXText, …) • Represents the complex object under construction

  8. Builder – Director cooperation

  9. Builder – Consequences • It let’s you vary a product’s internal representation • It isolates code for construction and representation • It gives you finer control over the construction process

  10. Builder – Implementation Issues • Assembly and Construction Interface • Builders construct their products step-by-step. • Usually appending simply the parts is enough. • Sometimes access to parts is needed. (Door between rooms, children nodes for a tree structures) • Why no abstract class for products? • The products differ greatly. • The client configures the director with the concrete builder. • Empty methods as default in builder.

  11. Builder – Sample Code class MazeBuilder { public: virtual void BuildMaze() { } virtual void BuildRoom(int n){ } virtual void BuildDoor(int nfrom, int nto){ } virtual Maze* GetMaze() { return 0 ; } protected: MazeBuilder() ; } ; Maze* MazeGame::CreateMaze(MazeBuilder& builder) { builder.BuildMaze() ; builder.BuildRoom(1) ; builder.BuildRoom(2) ; builder.BuildDoor(1,2) ; return builder.GetMaze() ; }

  12. Builder – Sample Code Maze* MazeGame::CreateComplexMaze ( MazeBuilder& builder) { builder.BuildMaze() ; builder.BuildRoom(1) ; builder.BuildRoom(2) ; builder.BuildDoor(1,2) ; … builder.BuildRoom(1000) ; return builder.GetMaze() ; }

  13. Builder – Sample Code class StandardMazeBuilder : public MazeBuilder { private: Maze* currentMaze ; public: StandardMazeBuilder() : currentMaze(0) { } virtual void BuildMaze() { currentMaze = new Maze() ; } Maze* GetMaze() { return currentMaze ; } virtual void BuildRoom(int n) { if (! currentMaze->RoomNo(n)) { Room* room = new Room(n) ; currentMaze->AddRoom(room) ; room->SetSide(North, new Wall()) ; room->SetSide(South, new Wall()) ; room->SetSide(East , new Wall()) ; room->SetSide(West , new Wall()) ; } } virtual void BuildDoor(int n1,int n2) { Room* r1 = currentMaze->RoomNo(n1) ; Room* r2 = currentMaze->RoomNo(n2) ; Door* d = new Door(r1,r2) ; r1->SetSide(CommonWall(r1,r2),d) ; r2->SetSide(CommonWall(r2,r1),d) ; } } ;

  14. Builder – Sample Code • Usage Maze* maze; MazeGame game; StandardMazeBuilder builder; game.CreateMaze(builder); maze = builder.GetMaze();

  15. Builder – Sample Code • Another builder for counting class CountingMazeBuilder : public MazeBuilder { private: int doors; int rooms; public: CountingMazeBuilder(): doors(0), rooms(0) { } virtual void BuildMaze() { doors=0; rooms=0; } virtual void BuildRoom(int i) { rooms++; } virtual void BuildDoor(int r1,int r2) { doors++; } void GetCounts(int& roomcount, int& doorcount) { roomcount=rooms; doorcount=doors; } };

  16. Builder – Sample Code int rooms, doors; MazeGame game; CountingMazeBuild builder; game.CreateMaze(builder); builder.GetCounts(rooms,doors); cout << “The maze has ” << rooms << “ rooms and ” << doors << “ doors” << endl ;

  17. Prototype Moshe Fresko Bar-Ilan University תשס"ו - 2005-2006 Design Patterns Course

  18. Prototype • Intent: Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. • Motivation: • To build an editor for music scores by customizing a general framework for graphical editors and adding new objects that represent notes, rests and staves. • Let’s have a Graphic class for graphic components like notes (a quarter-note), staves, etc. And a GraphicTool class for adding such components. • The classes of notes and staves are specific to application and GraphicTool is a general framework. Subclassing GraphicTool needs a subclass for each Graphic class. It is better to use composition. • Solution is to add a cloning instance (Prototype) into GraphicTool.

  19. Prototype – Motivation

  20. Prototype – Applicability • Use Prototype pattern when a system should be independent of how its products are created, composed, and represented; and • When the classes to instantiate are specified at run-time • To avoid building class-hierarchy of factories that parallels the class hierarchy of products • When instances of a class can have only one of a few different combinations of states.

  21. Prototype – Structure

  22. Prototype – Participants • Prototype (Graphic) • Declares an interface for cloning itself • ConcretePrototype (Staff, WholeNote, HalfNote) • Implements an operation for cloning itself • Client (GraphicTool) • Creates a new object by asking a prototype to clone itself.

  23. Prototype – Consequences • It hides concrete product classes from the client • Let a client work with application-specific classes without modification • Adding and removing products at run-time. • Specifying new objects by varying values. • Specifying new objects by varying structure. • Reduced subclassing. • Configuring an application with classes dynamically. • Adding Clone() to each product may be difficult.

  24. Prototype – Implementation Issues • Using a prototype manager. To keep a registry of possible prototypes. • Implementing the Clone operation. Shallow Copy versus Deep Copy.Serialization (Save-Load) can be used for cloning. • Initializing clones.Set operations can solve this problem.

  25. Prototype – Sample class MazePrototypeFactory : public MazeFactory { private: Maze* pMaze; Wall* pWall; Room* pRoom; Door* pDoor; public: MazePrototypeFactory ( Maze* m, Wall* w, Room* r, Door* d) : pMaze(m), pWall(w), pRoom(r), pDoor(d) { } virtual Maze* MakeMaze() const { return pMaze->Clone() ; } virtual Room* MakeRoom(int r) const { Room* p = pRoom->Clone() ; p->initialize(r) ; return p; } virtual Wall* MakeWall() const { return pWall->Clone(); } virtual Door* MakeDoor(Room* r1, Room* r2) const { Door* door = pDoor->Clone(); door->initialize(r1,r2); return door; } };

  26. Prototype – Sample MazeGame game; MazePrototypeFactory simpleMazeFactory(new Maze, new Wall, new Room, new Door); MazePrototypeFactory bombedMazeFactory(new Maze, new BombedWall, new RoomWithABomb, new Door); Maze* maze1 = game.CreateMaze(simpleMazeFactory); Maze* maze2 = game.CreateMaze(bombedMazeFactory);

  27. Prototype – Sample class Door: public MapSite { private: Room* room1; Room* room2; public: Door(): room1(0), room2(0) { } Door(const Door& d): room1(d.room1), room2(d.room2) { } virtual void Initialize(Room* r1, Room* r2) { room1 = r1 ; room2 = r2 ; } virtual Door* Clone() const { return new Door(*this) ; } } ;

  28. Prototype – Sample Code class BombedWall: public Wall { private: bool bomb; public: BombedWall() : bomb(true) { } BombedWall(bool b) : bomb(b) { } BombedWall(const BombedWall& other) { bomb = other.bomb; } virtual Wall* Clone() const { return new BombedWall(*this) ; } bool HasBomb() { return bomb; } } ;

  29. Creational Design Patterns – Discussion • Two ways two parameterize a system by the classes of objects it creates. • To subclass the class that creates objects- Factory MethodMain drawback is that it requires a new subclass just to change the class of the product. • By object composition- Abstract Factory: Factory Object producing objects of several classes- Builder: Factory Object building a complex product- Prototype: Factory Object building a product by copying a prototype object.

More Related