Download presentation
Presentation is loading. Please wait.
Published byRoxanne Hall Modified over 9 years ago
1
Abstract Factory Abstract Factory using Factory Method
2
Factory Method PizzaStore orderPizza() SimplePizzaFactory createPizza() Pizza prepare() bake() cut() box() CheesePizza VeggiePizza ClamPizza 2
3
Creating multiple factories PizzaStore NYPizzaFactory ChicagoPizzaFactory 3
4
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 region 4
5
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
6
Concrete Pizza Store Classes public 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
7
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(); }
8
Allowing the subclasses to decide PizzaStore createPizza() orderPizza() NYStylePizzaStore createPizza() ChicagoStylePizzaStore createPizza() 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
9
Pizza Store Franchises PizzaStore createPizza() orderPizza() NYStylePizzaStore createPizza() ChicagoStylePizzaStore createPizza() PizzaNYStyleCheesePizza ChStyleCheesePizza Creator Classes Product Classes 9
10
Looking at object dependencies Pizza Store NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Cheese Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Cheese Pizza 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
11
Design Principle Dependency 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
12
Applying the principle Pizza Store NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Cheeze Pizza NyStyle Cheese Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Cheeze Pizza Chicago Cheese Pizza Pizza is an abstract class 12
13
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
14
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
15
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
16
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
17
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
18
Motivation (Cont’d) 18
19
Applicability Use 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
20
Structure 20
21
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
22
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
23
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
24
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 family 24
25
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
26
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
27
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
28
Building NY ingredient factory public 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
29
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(); }
30
Concrete Individual Ingredient Classes public 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
31
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
32
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
33
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"); } }
34
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; }
35
Our Calling Program class Program { static void Main(string[] args) { NYPizzaStore nypizzastore = new NYPizzaStore(); nypizzastore.OrderPizza("Pepperoni"); Console.ReadLine(); } 35
36
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)
37
ProductA1 Abstract Factory Pattern example > PizzaIngFactory CreateDough() CreateCheese() ConcreteFactory1 CreateProductA() CreateProductB() ChicPizzaIngFctry CreateDough() CreateCheese() Pizza > Dough ThinCrust > Cheese NYPizzaIngFctry CreateDougn() CreateCheese() Reggiano ThickCrust Mozzarella 37
38
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
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.