When instantiating a class using new, the implementation is used instead of the interface, and the code is bundled with a specific class that causes the code to become more brittle and inflexible, and the loosely coupled oo pattern can be used to relieve it.
Factory: Encapsulates the creation of objects, handling the details of creating objects
Static Factory: Define a simple factory with a static method. Pros: You do not need to create an instantiation of a factory class. Disadvantage: You cannot create a method behavior through inheritance changes.
Simple factory: A simple factory is not a design pattern because it simply encapsulates the code that creates the object
Factory mode: Defines an interface for creating objects in the parent class, by allowing subclasses to decide what objects are created to encapsulate the process for object creation. Factory methods let classes defer instantiation to subclasses
Abstract Factory: Provides an interface for creating a family of related or dependent objects without having to specify a specific class
Characteristics:
- The factory method is used to process the creation of objects and encapsulate such behavior in subclasses. In this way, the superclass code in the client program is decoupled from the creation part of the subclass object.
- Simple Factory vs. Factory mode: The simple factory has done all the things in one place, and the Factory mode is a framework for creating a subclass that determines how to implement
- Abstract Factory vs Factory mode
- Abstract factory methods are often implemented in a factory way, and the task of an abstract factory is to define an interface that is responsible for creating a set of products.
- Factory methods use inheritance, abstract factory use combination
- The factory method is only used to create a product, and the abstract factory creates a product family
- Using the Factory mode means that you need to extend a class and overwrite its factory methods. Abstract Factory provides an abstract type that creates a product family, and the subclass of the type defines how the product is produced
Design principles:
- Dependency inversion principle: to rely on abstractions, do not rely on specific classes. High-level modules should not be dependent on low levels of modules, they should all rely on abstraction. Abstractions should not be dependent on concrete implementations, but concrete implementations should rely on abstraction. (http://baike.baidu.com/link?url= Myrsyyxntf-kbbdpepln53drmxwb2qjbiibxs4pa5ikqkjqolobbs8fzaxu81mox962ucguwwy6uolauavex1wfqdjy7xg96ezg7vj-ss_y_8r _FCISMSGN-DMM6XSROAME6SKIFISSBXJIOBL7CCA)
- Variables do not hold references to specific classes
- Do not allow classes to be derived from specific classes
- Do not overwrite methods implemented in the base class
Class Diagram and code:
1. Simple Factory
1 Public classSimplepizzafactory {2 PublicPizza Createpizza (String type) {3Pizza Pizza =NULL;4 5 if(Type.equals ("Cheese")) {6Pizza =NewCheesepizza ();7}Else if(Type.equals ("Pepperoni")) {8Pizza =NewPepperonipizza ();9}Else if(Type.equals ("Clam")) {TenPizza =NewClampizza (); One}Else if(Type.equals ("Veggie")) { APizza =NewVeggiepizza (); - } - returnPizza; the } -}
2. Factory mode
1 Public Abstract classPizzastore {2 3 //this defines a factory method4 AbstractPizza Createpizza (String item);5 6 PublicPizza Orderpizza (String type) {7 8Pizza Pizza =Createpizza (type);9 TenSYSTEM.OUT.PRINTLN ("---Making a" + pizza.getname () + "---"); One Pizza.prepare (); A Pizza.bake (); - pizza.cut (); - Pizza.box (); the - returnPizza; - } -}
1 Public classChicagopizzastoreextendsPizzastore {2 3 Pizza Createpizza (String item) {4 if(Item.equals ("Cheese")) {5 return NewChicagostylecheesepizza ();6}Else if(Item.equals ("Veggie")) {7 return NewChicagostyleveggiepizza ();8}Else if(Item.equals ("Clam")) {9 return NewChicagostyleclampizza ();Ten}Else if(Item.equals ("Pepperoni")) { One return NewChicagostylepepperonipizza (); A}Else return NULL; - } -}
1 Public classpizzatestdrive {2 3 Public Static voidMain (string[] args) {4Pizzastore Nystore =NewNypizzastore ();5 6Pizza Pizza = Nystore.orderpizza ("Cheese");7System.out.println ("Ethan ordered a" + pizza.getname () + "\ n");8 9Pizza = Nystore.orderpizza ("Clam");TenSystem.out.println ("Ethan ordered a" + pizza.getname () + "\ n"); One } A}
3. Abstract Factory
First to define an interface Pizzaingredientfactory, he defines a series of methods for creating pizza materials.
1 Public InterfacePizzaingredientfactory {2 3 Publicdough Createdough ();4 PublicSauce createsauce ();5 PublicCheese Createcheese ();6 Publicveggies[] Createveggies ();7 Publicpepperoni Createpepperoni ();8 Publicclams Createclam ();9 Ten}
Sub-class
1 Public classNypizzaingredientfactoryImplementsPizzaingredientfactory {2 3 PublicDough Createdough () {4 return NewThincrustdough ();5 }6 7 PublicSauce createsauce () {8 return Newmarinarasauce ();9 }Ten One PublicCheese Createcheese () { A return NewReggianocheese (); - } - the Publicveggies[] Createveggies () { -Veggies veggies[] = {NewGarlic (),NewOnion (),NewMushroom (),Newredpepper ()}; - returnveggies; - } + - PublicPepperoni Createpepperoni () { + return NewSlicedpepperoni (); A } at - PublicClams Createclam () { - return Newfreshclams (); - } -}
Pizza class
1 Public classCheesepizzaextendsPizza {2 //a reference to a Pizzaingredientfactory object is combined to provide a different raw material .3 pizzaingredientfactory ingredientfactory;4 5 /**6 * by passing in a pizzaingredientfactory raw material factory, we can produce the necessary raw materials dynamically when making pizza.7 * @paramingredientfactory8 */9 Ten PublicCheesepizza (pizzaingredientfactory ingredientfactory) { One This. Ingredientfactory =ingredientfactory; A } - - voidprepare () { theSystem.out.println ("Preparing" +name); -Dough =Ingredientfactory.createdough (); -sauce =ingredientfactory.createsauce (); -Cheese =Ingredientfactory.createcheese (); + } -}
Pizza Store
1 Public classNypizzastoreextendsPizzastore {2 3 protectedPizza Createpizza (String item) {4Pizza Pizza =NULL;5Pizzaingredientfactory ingredientfactory =Newnypizzaingredientfactory ();6 7 if(Item.equals ("Cheese")) {8 9Pizza =NewCheesepizza (ingredientfactory);TenPizza.setname ("New York Style Cheese Pizza"); One A}Else if(Item.equals ("Veggie")) { - -Pizza =NewVeggiepizza (ingredientfactory); thePizza.setname ("New York Style Veggie Pizza"); - -}Else if(Item.equals ("Clam")) { - +Pizza =NewClampizza (ingredientfactory); -Pizza.setname ("New York Style Clam Pizza"); + A}Else if(Item.equals ("Pepperoni")) { at -Pizza =NewPepperonipizza (ingredientfactory); -Pizza.setname ("New York Style Pepperoni Pizza"); - - } - returnPizza; in } -}
Factory mode & Abstract Factory--headfirst Design Patterns Learning Notes