factory method explained. intent define an interface for creating an object, but let subclasses...

33
Factory Method Explained

Upload: brendan-douglas

Post on 05-Jan-2016

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

Factory Method

Explained

Page 2: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

2

Intent

Define an interface for creating an object, but let subclasses decide which class to instantiate.

Factory Method lets a class defer instantiation to subclasses.

a.k.a. Virtual Constructor The main intent of the virtual constructor idiom

in C++ is to create a copy of an object or a new object without knowing its concrete type and this is exactly what the Factory Method does

Can a constructor be virtual?

Page 3: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

3

Motivation Frameworks use abstract classes to define and

maintain relationships between objects A framework is often responsible for creating

these objects as well They must instantiate classes but only know

about abstract classes - which they cannot instantiate

Factory method encapsulates knowledge of which subclass to create - moves this knowledge out of the framework

Page 4: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

4

Motivation (Cont’d)

Consider a framework for presenting multiple documents to the user

Key abstraction in this framework are Application and Document classes

Both classes are abstract and realized in subclasses

Application class is responsible for managing and creating the Documents as and when required.

Page 5: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

5

Motivation (Cont’d)

The particular Document subclass to instantiate is application specific, and

The Application class can’t predict the subclass of Document to instantiate. As it only knows when a new document should be created.

NOT What kind of a Document to create. This creates a dilemma…

Page 6: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

6

Motivation (Cont’d)

Factory method solves this problem. It encapsulates the knowledge of which Document to create and moves this knowledge out of the framework.

factory method

Page 7: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

7

Motivation (Cont’d) Application subclasses redefine an abstract

CreateDocument operation to return Document subclasses

Once an Application subclass is instantiated, it can then instantiate application specific Documents

We call CreateDocument a factory method as it’s responsible for manufacturing a object.

Page 8: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

8

Applicability Use the Factory Method pattern when

A class can’t anticipate the class of objects it must create

A class wants it’s subclasses to specify the objects it creates

Classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.

Page 9: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

9

Structure

Page 10: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

10

Participants

Product (Document) defines the interface of objects the factory method creates

Concrete Product (MyDocument) Implements the product interface

Creator (Application) declares the factory method which return a Product type. May also define a default implementation of the factory

method that returns a default ConcreteProduct object May call the factory method to create a Product object.

Concrete Creator (MyApplication) Overrides the factory method to return Concrete Product

Page 11: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

11

Collaborations Creator relies on it’s subclasses to define the

factory method so that it returns an instance of the appropriate ConcreteProduct(Subclasses of Product)

Page 12: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

12

Consequences Factory methods eliminate the need to bind

application specific classes into your code The code only deals with the Product

interface; therefore it can work with any user defined ConcreteProduct classes.

A potential disadvantage of using Factory pattern is that client also has to subclass the Creator class in order to create a particular ConcreteProduct object.

Page 13: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

13

Consequences (Cont’d) Provides hooks for subclasses

Creating objects inside a class with a factory method is always more flexible than creating an object directly

Factory method gives subclasses a hook for providing an extended version of an object

Example: the Document class could define a factory method called CreateFileDialog for opening an existing document.

Page 14: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

14

Consequences (Cont’d)

Connects Parallel Class Hierarchies Parallel Class hierarchies result when a class

delegates some of it’s responsibilities to a separate class

Clients can use factory methods to connect between parallel class hierarchies

Page 15: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

15

Consequences (Cont’d) The figure class provides a CreateManipulator

factory method that lets clients create a Figure’s corresponding Manipulator

Figure subclasses override this method to return an instance of the required manipulator subclass

Alternatively the Figure class may implement CreateManipulator to return a default manipulator. The figure subclasses may inherit the default.

The figure classes that do so need no corresponding Manipulator subclasses. Hence partially parallel class hierarchies

This is how the factory method defines connection between these class hierarchies

Page 16: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

16

Implementation Styles Two Major Varieties

The case when the Creator class is an abstract class and does not provide an implementation of factory method

The case when the Creator class is a concrete class and has a default implementation of the factory method

The first case requires subclasses to define an implementation as there is no reasonable default

In the second case the subclasses or concrete Creator uses factory method primarily for flexibility.

Page 17: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

17

Implementation Styles (Cont’d) Parameterized factory methods

create multiple kinds of products the factory method takes a parameter that

identifies the kind of object to create the object share the Product interface

Naming conventions The name of the Factory method in code should

clearly mark its purpose.

Page 18: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

18

Implementation So the situation is that you have a set of

related concrete classes and there may be some conditions to call any one of them

Page 19: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

19

Implementation (Cont’d) When we see code like this we know that when it

comes to changes and extensions, we will have to re-open this code and examine what needs to be added or deleted.

Often this type of code ends up in several parts of an application making maintenance and updates more difficult and error prone.

By coding to an interface we know we can insulate ourselves with lot of changes occurring down the road

However if you have concrete classes then you might end up in trouble if more concrete classes are added

In other words code would not be closed for modification

So what’s the solution?

Page 20: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

20

Implementation (Cont’d) Remember the design principle “Identify the

aspects that vary and separate them from what stays the same”

We will now see an example implementation of Pizza shop to illustrate the application of this design principle

We will have a function of OrderPizza() to determine one type of Pizza and run different processes for making a pizza.

Page 21: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

21

Implementation (Cont’d)public class Pizza { Pizza pizza; //Declarations public Pizza() { } //Constructor of Pizza //Declarations of Pizza Functions public virtual void Prepare() {} public virtual void Bake() { } public virtual void Cut() { } public virtual void Box() { }//Method of Ordering a Pizza public void OrderPizza() {

pizza = new Pizza(); pizza.Prepare();

pizza.Bake(); pizza.Cut(); pizza.Box(); } //Return only one type of Pizza

Page 22: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

22

Implementation (Cont’d) The concrete classes of Pizza like cheese pizza and

pepperoni pizzapublic class CheesePizza : Pizza

{

public CheesePizza() {

Console.WriteLine("Constructing CHEESE PIZZA"); }

public override void Prepare()

{ Console.WriteLine("Preparing CHEESE PIZZA"); }

public override void Bake()

{ Console.WriteLine("Baking CHEESE PIZZA"); }

public override void Cut()

{ Console.WriteLine("Cutting CHEESE PIZZA"); }

public override void Box()

{ Console.WriteLine("Boxing CHEESE PIZZA"); }

}

Page 23: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

23

Implementation (Cont’d)public class PepperoniPizza : Pizza{ public PepperoniPizza() { Console.WriteLine("Constructing Pepperoni Pizza"); } public override void Prepare()

{ Console.WriteLine("Preparing Pepperoni Pizza"); } public override void Bake()

{ Console.WriteLine("Baking Pepperoni Pizza"); } public override void Cut()

{ Console.WriteLine("Cutting Pepperoni Pizza"); } public override void Box()

{ Console.WriteLine("Boxing Pepperoni Pizza"); } }

Page 24: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

24

Implementation (Cont’d) Now we will add code that determines different

types of pizza and then goes about making it. The order pizza function will changepublic void OrderPizza(String type){

if (type.Equals("Cheese")){

pizza = new CheesePizza(); //Calling object of Subclass for Cheese Pizza

}

else if (type.Equals("Pepperoni")) {

pizza = new PepperoniPizza();//Calling object of Subclass for Pepperoni Pizza

}

pizza.Prepare();

pizza.Bake();

pizza.Cut();

pizza.Box();

}

Page 25: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

25

Implementation (Cont’d) We have now passed the type of pizza (string

type) to OrderPizza function Based on the type of pizza we instantiate the

correct concrete class and assign it to the pizza instance variable.

Note that each pizza here would have to implement the pizza interface.

So each pizza type knows how to prepare itself.

But the pressure in on to add or subtract pizza types

Page 26: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

26

Implementation (Cont’d)public void OrderPizza(String type){ if (type.Equals("Cheese")){ pizza = new CheesePizza(); } else if (type.Equals("Pepperoni")){ pizza = new PepperoniPizza(); }// “here we can add more pizza types” pizza.Prepare(); pizza.Bake(); pizza.Cut(); pizza.Box(); }

This part of code is changing

This part of code is supposed to remain unchanged

Page 27: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

27

Implementation (Cont’d) Clearly we can now make out what’s variable

in our code and we need to separate it What we can do is that place the object

creation code into another object (class) whose sole purpose is to create different types of pizza

This object can be called a SimplePizzaFactory Once we have a factory the OrderPizza()

becomes a client of that factory. Anytime it needs a pizza it asks the factory to make one

OrderPizza will get a correct pizza and would call prepare(),bake(),cut() and box()

Page 28: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

28

Implementation (Cont’d) Here is the new class SimplePizzaFactory

public class SimplePizzaFactory { public SimplePizzaFactory() { } public Pizza CreatePizza(String type)//This method would be used by all to

create new objects { Pizza pizza = null; if (type.Equals("Cheese")) { pizza = new CheesePizza(); //Calling object of Subclass for Cheese Pizza } else if (type.Equals("Pepperoni")) { pizza = new PepperoniPizza();//Calling object of Subclass for Pepperoni

Pizza } return pizza; } }

Page 29: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

29

Implementation (Cont’d) The orderpizza method also be moved out of the Pizza class

and would be changed as under

public class PizzaStore { SimplePizzaFactory factory = new SimplePizzaFactory(); //Creates the

factory public PizzaStore() { } public void OrderPizza(String type) { Pizza pizza; pizza = factory.CreatePizza(type); //Get the correct pizza from

Factory pizza.Prepare(); pizza.Bake(); pizza.Cut(); pizza.Box(); }//Method of Ordering a Pizza }

Page 30: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

30

Implementation (Cont’d)

Page 31: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

31

Implementation (Cont’d) Now the Pizza class would be changed as under

public abstract class Pizza //Superclass Pizza { public Pizza() { } //Contructor of Pizza

//Declarations of Pizza Funtions public virtual void Prepare() { } public virtual void Bake() { } public virtual void Cut() { } public virtual void Box() { } }

Page 32: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

32

Implementation (Cont’d) The calling program for our codeclass Program

{

static void Main(string[] args)

{

PizzaStore pizzastore = new PizzaStore();// The client just knows the pizza store

pizzastore.OrderPizza("Pepperoni");

Console.ReadLine();

}

}

Page 33: Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method

33

Quiz # 1 Elements of a Design Pattern with an example Describe Scope Based Design Patterns

Classification?