Presentation is loading. Please wait.

Presentation is loading. Please wait.

Creational Patterns, Abstract Factory, Builder Billy Bennett June 11, 2009.

Similar presentations


Presentation on theme: "Creational Patterns, Abstract Factory, Builder Billy Bennett June 11, 2009."— Presentation transcript:

1 Creational Patterns, Abstract Factory, Builder Billy Bennett June 11, 2009

2 Creational Patterns Two Recurring Themes: 1. Encapsulate knowledge about which concrete classes the system uses. 2. Hide how these instances are created and put together.

3 The Maze Example

4 Maze* MazeGame::CreateMaze () { Maze* aMaze = new Maze; Room* r1 = new Room (1); Room* r2 = new Room (2); Door* theDoor = new Door (r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, new Wall); r1->SetSide(East, theDoor); r1->SetSide(South, new Wall); r1->SetSide(West, new Wall); r2->SetSide(North, new Wall); r2->SetSide(East, new Wall); r2->SetSide(South, new Wall); r2->SetSide(West, theDoor); return aMaze; }

5 Uh-oh This gets complicated. It’s inflexibly coded. It’s difficult to reuse. Only makes 2 rooms. Creational patterns let us make this design more flexible and thus more reusable.

6 Potential Patterns Virtual functions instead of constructors for ◦ Rooms ◦ Doors ◦ Walls Make a subclass of MazeGame to redefine these functions Factory Method

7 Potential Patterns CreateMaze is passed an object as a parameter, which is used to change the classes used to make ◦ Rooms ◦ Doors ◦ Walls Abstract Factory

8 Potential Patterns CreateMaze is passed an object that can create a maze all by itself, then you can use inheritance to change parts of the maze: ◦ Rooms ◦ Doors ◦ Walls Builder

9 Potential Patterns CreateMaze is parameterized by various prototypical: ◦ Rooms ◦ Doors ◦ Walls You can replace these prototypical objects with different ones to change the maze Prototype

10 Abstract Factory

11 Intent ◦ Provide an interface for creating families of related or dependent objects without specifying their concrete classes A.K.A. ◦ “Kit”

12 Applicability A system should be independent of how its products are created, composed, or represented A system should be configured with one of multiple families of products A family of related product objects is designed to be used together You want to provide a class library of objects, but reveal only their interfaces

13

14 Participants Client AbstractFactory ConcreteFactory AbstractProduct ConcreteProduct

15 Consequences 1. Concrete class isolation (Good) Client does not interact with the implementation classes Client only manipulates instances through the abstract interfaces

16 Consequences 2. Product families easily exchanged (Good) Only have to change the concrete factory Can be done at run time

17 Consequences 3. Products are more consistent (Good) Helps the products in each product family consistently be applied together (assuming they work well together) Only one family at a time

18 Consequences 4. Difficult to support new kinds of products (Bad) Extending existing abstract factories to make new products is difficult and time consuming The family of products available is fixed by Abstract Factory interface

19 Implementation Issues Concrete Factories make excellent Singletons (not necessarily one factory, but one per product family) Factory Methods within Concrete Factories for each product, or Prototypes if many product families Move implementation one step closer to Client by adding a parameter specifying product type (less safe, more extensible)

20 Class MazeFactory { Public: MazeFactory(); virtual Maze* MakeMaze () const {return new Maze;} virtual Wall* MakeWall () const {return new Wall;} virtual Room* MakeRoom (int n) const {return new Room(n);} virtual Door* MakeDoor (Room* r1, Room* r2) {return new Door(r1, r2);} };

21 Maze* MazeGame::CreateMaze () { Maze* aMaze = new Maze; Room* r1 = new Room (1); Room* r2 = new Room (2); Door* theDoor = new Door (r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, new Wall); r1->SetSide(East, theDoor); r1->SetSide(South, new Wall); r1->SetSide(West, new Wall); r2->SetSide(North, new Wall); r2->SetSide(East, new Wall); r2->SetSide(South, new Wall); r2->SetSide(West, theDoor); return aMaze; }

22 Maze* MazeGame::CreateMaze (MazeFactory& factory) { Maze* aMaze = factory.MakeMaze(); Room* r1 = factory.MakeRoom (1); Room* r2 = factory.MakeRoom (2); Door* theDoor = factory.MakeDoor (r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, factory.MakeWall); r1->SetSide(East, theDoor); r1->SetSide(South, factory.MakeWall); r1->SetSide(West, factory.MakeWall); r2->SetSide(North, factory.MakeWall); r2->SetSide(East, factory.MakeWall); r2->SetSide(South, factory.MakeWall); r2->SetSide(West, theDoor); return aMaze; }

23 Related Patterns Factory Method Prototype Singleton

24 Builder Intent ◦ Separate the construction of a complex object from its representation so that the same construction process can create different representations

25 Applicability The algorithm for creating a complex object should be independent of the parts that make up the object and how they’re assembled The construction process must allow for different representations for that object that’s constructed

26

27

28 Participants Director Builder Concrete Builder Product

29 Consequences 1. Varying a product’s internal representation (Good) The Director doesn’t see the product’s construction, only the Builder does

30 Consequences 2. Isolates code for construction and representation (Good) The Client only retrieves the product The Client doesn’t know anything about the internal construction of the product Question: Multiple directors?

31 Consequences 3. Step by step construction (Good?) The Client only retrieves the product The Client doesn’t know anything about the internal construction of the product Question: Multiple directors?

32 Implementation Issues Builder needs a very general interface Builder(s) may need access to a variety of components – parse trees are one solution No abstract product class (products are too different, commonly)

33 Class MazeBuilder { public: virtual void BuildMaze() {...} virtual void BuildRoom (int room) {...} virtual void BuildDoor (int roomFrom, int roomTo) {...} virtual Maze* GetMaze() {return Maze to client} Protected: MazeBuilder(); };

34 Maze* MazeGame::CreateMaze (MazeBuilder& builder) { builder.BuildMaze(); builder.BuildRoom(1); builder.BuildRoom(2); builder.BuildDoor(1,2); return builder.GetMaze(); }

35 Other thoughts The “abstract interface” theme among patterns OOP bias? Why do some patterns seem so similar – is there a standard for defining novelty among patterns?


Download ppt "Creational Patterns, Abstract Factory, Builder Billy Bennett June 11, 2009."

Similar presentations


Ads by Google