abstract factory abstract factory using factory method

38
Abstract Factory Abstract Factory using Factory Method

Upload: roxanne-hall

Post on 16-Jan-2016

281 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Abstract Factory Abstract Factory using Factory Method

Abstract Factory

Abstract Factory using Factory Method

Page 2: Abstract Factory Abstract Factory using Factory Method

Factory Method

PizzaStoreorderPizza()

SimplePizzaFactorycreatePizza()

Pizzaprepare()bake()cut()box()

CheesePizza

VeggiePizza

ClamPizza

ClamPizza

2

Page 3: Abstract Factory Abstract Factory using Factory Method

Creating multiple factories

PizzaStore

NYPizzaFactory

ChicagoPizzaFactory

3

Page 4: Abstract Factory Abstract Factory using Factory Method

Creating Multiple Factories To demonstrate the factory method pattern, the

pizza store example evolves To include the notion of different franchises That exist in different parts of the country (California,

New York, Chicago) Each franchise will need its own factory to create

pizzas that match the tastes of the locals However, we want to retain the creation process that

has made PizzaStore such a great success The Factory Method Design Pattern allows you to

do this by placing abstract, “code to an interface” code in a

superclass placing object creation code in a subclass PizzaStore becomes an abstract class with an abstract

createPizza() method We then create subclasses that override

CreatePizza() for each region4

Page 5: Abstract Factory Abstract Factory using Factory Method

Changes in PizzaStore

public abstract class PizzaStore

{

Pizza pizza = null;

public abstract Pizza CreatePizza(String type);

public void OrderPizza(String type)

{

pizza = CreatePizza(type);

pizza.Prepare();

pizza.Bake();

pizza.Cut();

pizza.Box();

}//Method of Ordering a Pizza

}5

Page 6: Abstract Factory Abstract Factory using Factory Method

Concrete Pizza Store Classespublic class NYPizzaStore :

PizzaStore

{

public override Pizza CreatePizza(string type)

{

if (type.Equals("cheese"))

{ return new NYCheesePizza(); }

else if (type.Equals("pepperoni"))

{return new NYPepperoniPizza();}

return null;

}

}

public class ChicagoPizzaStore : PizzaStore {

public override Pizza CreatePizza(String type)

{

if(type.Equals("cheese")) { return new ChicagoCheesePizza();}

else if(type.Equals("pepperoni")) { return new ChicagoPepperoniPizza();}

return null; } }

6

Page 7: Abstract Factory Abstract Factory using Factory Method

Calling Program

7

class Program { static void Main(string[] args) { //Calling the NY Pizza Store to Order our

Cheese Pizza PizzaStore nypizzastore = new

NYPizzaStore(); nypizzastore.OrderPizza("cheese");

Console.ReadLine(); } }

Page 8: Abstract Factory Abstract Factory using Factory Method

Allowing the subclasses to decide

PizzaStorecreatePizza()orderPizza()

NYStylePizzaStorecreatePizza()

ChicagoStylePizzaStorecreatePizza()

A factory method CreatePizza() handles object creation and encapsulates it in the subclass. This decouples the client code in the super class from the object creation that happens in the subclass.

8

Page 9: Abstract Factory Abstract Factory using Factory Method

Pizza Store Franchises

PizzaStorecreatePizza()orderPizza()

NYStylePizzaStorecreatePizza()

ChicagoStylePizzaStorecreatePizza()

Pizza

NYStyleCheesePizzaNYStyleCheesePizza

NYStyleCheesePizzaNYStyleCheesePizza

ChStyleCheesePizzaChStyleCheesePizza

ChStyleCheesePizzaChStyleCheesePizza

Creator Classes

Product Classes

9

Page 10: Abstract Factory Abstract Factory using Factory Method

Looking at object dependencies

PizzaStore

NyStyleCheezePizza

NyStyleCheezePizza

NyStyleCheezePizza

NyStyleCheesePizza

ChicagoCheezePizza

ChicagoCheezePizza

ChicagoCheezePizza

ChicagoCheesePizza

Because the Pizza Store depends on the concrete implementations any change in concrete classes may change the Pizza Store class

Before Applying Factory Method

10

Page 11: Abstract Factory Abstract Factory using Factory Method

Design PrincipleDependency Inversion Principle

Depend upon abstractions. Do not depend upon concrete classes.

“High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.”

11

Page 12: Abstract Factory Abstract Factory using Factory Method

Applying the principle

PizzaStore

NyStyleCheezePizza

NyStyleCheezePizza

NyStyleCheezePizza

NyStyleCheesePizza

ChicagoCheezePizza

ChicagoCheezePizza

ChicagoCheezePizza

ChicagoCheesePizza

Pizza

Pizza is an abstract class

12

Page 13: Abstract Factory Abstract Factory using Factory Method

Some guidelines to help with the principle Try and avoid having variables that refer to a

concrete class Instead of using new use a factory to achieve this

Try and avoid deriving from a concrete class Derive from an abstract class

Try and avoid overriding an implemented method Could be done if deriving from an abstract class

13

Page 14: Abstract Factory Abstract Factory using Factory Method

Moving On… The factory method approach to the pizza

store is a big success allowing our company to create multiple franchises across the country quickly and easily

But, bad news, we have learned that some of the franchises while following our procedures (the abstract code

in PizzaStore forces them to) are skimping on ingredients in order to lower costs

and increase margins So what can be done?

14

Page 15: Abstract Factory Abstract Factory using Factory Method

Abstract Factory to the Rescue! We will alter our design such that a factory is

used to supply the ingredients that are needed during the pizza creation process

Since different regions use different types of ingredients, we’ll create region-specific subclasses of the ingredient factory to ensure that the right ingredients are used

But, even with region-specific requirements, since we are supplying the factories, we’ll make sure that ingredients that meet our quality standards are used by all franchises

But first let us look at what Abstract Factory Pattern is?

15

Page 16: Abstract Factory Abstract Factory using Factory Method

Intent

Provide an interface for creating families of related or dependent objects without specifying their concrete classes

A.k.a Kit The Abstract Factory pattern is very similar

to the Factory Method pattern One difference between the two is that

with the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition

Whereas the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation

16

Page 17: Abstract Factory Abstract Factory using Factory Method

Motivation Consider a user interface that supports multiple look

and feel standards Different look and feel standards define different

appearances and behaviors of user interface widgets like buttons, windows etc.

The application should not hard code its widgets to a particular look and feel

Using objects of individual look and feel standards makes it hard to change the look and feel later.

This problem can be solved by Abstract Widget Factory class, and abstract classes for each kind of widget.

Concrete classes implement the widgets for a particular look and feel standard

Also enforces dependencies between the concrete classes. 17

Page 18: Abstract Factory Abstract Factory using Factory Method

Motivation (Cont’d)

Scrollbar*

CreateScrollBar()CreateWindow()

WidgetFactory*

CreateScrollBar()CreateWindow()

MotifWidgetFactory

CreateScrollBar()CreateWindow()

PMWidgetFactory

Client

Window*

MotifWindow

MotifScrollbarPMScrollbar

PMWindow

18

Page 19: Abstract Factory Abstract Factory using Factory Method

ApplicabilityUse the Abstract Factory pattern when A system should be independent of how its

products are created, composed and 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, and you need to enforce this constraint.

You want to provide a class library of products, and you want to reveal just their interfaces, not their implementations.

19

Page 20: Abstract Factory Abstract Factory using Factory Method

Structure

20

Page 21: Abstract Factory Abstract Factory using Factory Method

Participants Abstract Factory (WidgetFactory)

Declares an interface for operations that create abstract product objects

Concrete Factory (MotifWidgetFactory, PMWidgetFactory) Implements the operations to create concrete product

objects Abstract Product (Window, Scrollbar, Button)

Declares an interface for a type of product object Concrete Product (MotifWindow, MotifScrollbar)

Defines a product to be created by the corresponding concrete factory.

Implements the AbstractProduct interface. Client

uses only interfaces declared by AbstractFactory and AbstractProduct classes.

21

Page 22: Abstract Factory Abstract Factory using Factory Method

Collaborations

Normally a single instance of a ConcreteFactory class is created at run-time. (This is an example of the Singleton Pattern.) This concrete factory creates product objects having a particular implementation. To create different product objects, clients should use a different concrete factory.

AbstractFactory defers creation of product objects to its ConcreteFactory

22

Page 23: Abstract Factory Abstract Factory using Factory Method

Consequences Isolates concrete classes

Factory encapsulates the responsibility & process of creating product objects

Makes exchanging product families easy The class of concrete factory appears only once in

the application - that is , where it’s instantiated Promotes consistency among products

Enforces, that products from one family are used together at one time

Supporting new kinds of products is difficult AbstractFactory interface fixes the set of

products that can be created Involves changing AbstractFactory interface

and all its subclasses.23

Page 24: Abstract Factory Abstract Factory using Factory Method

Implementation Factories can be implemented as singletons Creating the products

Use Factory Method pattern declare FactoryMethod for each kind of

product in AbstractFactory override FactoryMethod in ConcreteFactory

Use Prototype pattern for ConcreteFactory if many product families are possible initialize the concrete factory with a

prototypical instance of each product in the family

concrete factory will create a new product by cloning the prototype

no need for a new concrete factory class for each new family24

Page 25: Abstract Factory Abstract Factory using Factory Method

Extending the factory pattern… Now we Expand the Pizza store example How are you going to ensure that each franchise

uses quality ingredients We are going to build factory of ingredients which

is going to produce them and ship them to the franchises.

How do we deal with families of ingredients? Chicago: ThickCrust Dough,PlumTomato Sauce,Raggiano

Cheese and Dakin Pepperoni New York: ThinCrust Dough,Mariana Sauce,Mozzarella

Cheese and Sliced Pepperoni Basically, we have got same product families

(Dough, Sauce, Cheese, Pepperoni) but different implementations based on region.25

Page 26: Abstract Factory Abstract Factory using Factory Method

Building the ingredient factories Lets start by defining interface that is going to

create all our ingredients

public interface PizzaIngredientsFactory { Dough CreateDough(); Sauce CreateSauce(); Cheese CreateCheese(); Pepperoni CreatePepperoni(); }

26

Page 27: Abstract Factory Abstract Factory using Factory Method

Building Individual Ingredient Interfaces Defining interfaces for individual ingredient

/* Defining Interfaces for our Ingredients like * Dough,Sauce,Cheese,Pepperoni */ public interface Dough{string toString();} public interface Sauce{string toString();} public interface Cheese{string toString();} public interface Pepperoni{string toString();}

27

Page 28: Abstract Factory Abstract Factory using Factory Method

Building NY ingredient factorypublic class NYPizzaIngredientsFactory : PizzaIngredientsFactory{

public NYPizzaIngredientsFactory() { }

public Dough CreateDough() {

return new ThinCrustDough();

}

public Sauce CreateSauce() {

return new MarianaSauce();

}

public Cheese CreateCheese(){

return new MozzarellaCheese();

}

public Pepperoni CreatePepperoni(){

return new SlicedPepperoni();

}

}

28

Page 29: Abstract Factory Abstract Factory using Factory Method

Building Chicago ingredient factory

29

public class ChicagoPizzaIngredientsFactory : PizzaIngredientsFactory {

public ChicagoPizzaIngredientsFactory() { }

public Dough CreateDough() {

return new ThickCrustDough();

}

public Sauce CreateSauce() {

return new PlumTomatoSauce();

}

public Cheese CreateCheese() {

return new RaggianoCheese();

}

public Pepperoni CreatePepperoni() {

return new DakinPepperoni();

}

}

Page 30: Abstract Factory Abstract Factory using Factory Method

Concrete Individual Ingredient Classespublic class ThickCrustDough : Dough

{

public String toString()

{return "ThickCrust style extra thick crust dough";}

}

public class ThinCrustDough : Dough{

public String toString()

{ return "Thin crust dough"; }

}

public class PlumTomatoSauce : Sauce{

public String toString()

{ return "PlumTomato Sauce"; }

}

public class MarianaSauce : Sauce{

public String toString()

{ return "Mariana Sauce"; }}

public class MozzarellaCheese : Cheese{

public String toString()

{ return "Mozzarella Cheese"; }

}

public class RaggianoCheese : Cheese{

public String toString()

{ return "Raggiano Cheese"; }

}

public class SlicedPepperoni : Pepperoni{

public String toString()

{ return "Sliced Pepperoni"; }

}

public class DakinPepperoni : Pepperoni{

public String toString()

{ return "Dakin Pepperoni"; }}

30

Page 31: Abstract Factory Abstract Factory using Factory Method

Reworking the pizzas (abstract pizza class)

public abstract class Pizza {

protected String name;

protected Dough dough;

protected Sauce sauce;

protected Cheese cheese;

protected Pepperoni pepperoni;

public Pizza() { }

//Declarations of Pizza Funtions

public abstract void Prepare();

public abstract void Bake();

public abstract void Cut();

public abstract void Box();

}

31

Page 32: Abstract Factory Abstract Factory using Factory Method

Reworking the Pizza Concrete classes

32

When we wrote the Factory method we had four concrete classes of Pizza NYCheesePizza ChicagoCheesePizza NYPepperoniPizza ChicagoPepperoniPizza

Now we don’t need these four classes and the Factory is going to handle the type of pizza for us we would only have two classes now CheesePizza PepperoniPizza

Page 33: Abstract Factory Abstract Factory using Factory Method

CheesePizza Class

33

public class CheesePizza : Pizza {

PizzaIngredientsFactory ingredientsfactory;

public CheesePizza(PizzaIngredientsFactory ingredientsfactory){

this.ingredientsfactory = ingredientsfactory;

}

public override void Prepare(){

dough = ingredientsfactory.CreateDough();

sauce = ingredientsfactory.CreateSauce();

cheese = ingredientsfactory.CreateCheese();

pepperoni = ingredientsfactory.CreatePepperoni();

Console.WriteLine("Pizza has been Prepared using" + dough.toString() + sauce.toString() + cheese.toString() + pepperoni.toString());

}

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 34: Abstract Factory Abstract Factory using Factory Method

Reworking the PizzaStore Concrete Classes

34

We will work on the individual Pizza Stores like NY Pizza Store to update them about the relevant ingredients factory

public class NYPizzaStore : PizzaStore {

protected override Pizza CreatePizza(string type){

Pizza pizza = null;

PizzaIngredientsFactory ingredientsFactory = new NYPizzaIngredientsFactory();

if (type.Equals("Cheese"))

{ pizza = new CheesePizza(ingredientsFactory); }

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

{ pizza = new PepperoniPizza(ingredientsFactory); }

return pizza;

}

Page 35: Abstract Factory Abstract Factory using Factory Method

Our Calling Program

class Program { static void Main(string[] args) { NYPizzaStore nypizzastore = new

NYPizzaStore(); nypizzastore.OrderPizza("Pepperoni"); Console.ReadLine(); } }

35

Page 36: Abstract Factory Abstract Factory using Factory Method

Summary: What did we just do?

36

We created an ingredient factory interface to allow for the creation of a family of ingredients for a particular pizza

This abstract factory gives us an interface for creating a family of products The factory interface decouples the client code from

the actual factory implementations that produce context-specific sets of products

Our client code (PizzaStore) can then pick the factory appropriate to its region, plug it in, and get the correct style of pizza (Factory Method) with the correct set of ingredients (Abstract Factory)

Page 37: Abstract Factory Abstract Factory using Factory Method

ProductA1

Abstract Factory Pattern example

<<Interface>>PizzaIngFactoryCreateDough()

CreateCheese()

ConcreteFactory1

CreateProductA()CreateProductB()

ChicPizzaIngFctry

CreateDough()CreateCheese()

Pizza

<<Interface>>Dough

ThinCrust

<<Interface>>Cheese

NYPizzaIngFctry

CreateDougn()CreateCheese()

Reggiano

ThickCrust

Mozzarella

37

Page 38: Abstract Factory Abstract Factory using Factory Method

Factory Method used inside Abstract Factory

38

The job of an Abstract Factory is to define an interface for a set of products

Each method in that interface is responsible for creating a concrete product

These methods are normally factory methods, in other words factory methods are a natural way to implement the product methods in the abstract factories