Chapter 4 Study Notes of head first Design Pattern
I. Design Principles
Dependency abstraction, not specific classes. When you instantiate an object directly, it is dependent on its specific class.
If there is a class that does not seem to change, it is no problem to instantiate a specific class directly in the code.
Ii. Factory Model
<1> simple factory Model
Simple factory mode: A class method (which can be a static method) determines the instance of a specific product class based on the input parameters.
A simple factory is not a design pattern, but rather a programming habit. The class diagram is as follows:
<2> factory method mode
Factory method mode: defines an interface for object creation, but the subclass determines the class to be instantiated. The factory method delays the class Instantiation to the subclass.
A factory method with parameters, called a parametric factory method, can create different objects based on input parameters. (Parameterized Factory methods are not recommended because each specific method is implemented, which is the same as that of a simple factory)
The factory method class diagram is as follows:
The abstract factory class creator defines an abstract method factorymethod for object creation. In each specific factory class, this method is implemented to create a specific product instance.
<3> Abstract Factory Model
Abstract Factory mode: provides an interface for creating a family of related or dependent objects without specifying a specific class. The class diagram is as follows:
Every method of the abstract factory actually looks like a factory method.
Iii. Example
1. Simple factory model example
Pizza shops make pizzas. Pizza is an abstract pizza class, And cheespizza, greekpizza, clampizza are specific pizza implementation classes. The simple factory mode is used to create different pizzas based on different parameters. The code snippet is as follows:
Simple factory simplepizzafactory class:
public class SimplePizzaFactory { public static Pizza createPizza(String type) { Pizza pizza = null; if ("cheese".equals(type)) { pizza = new CheesePizza(); } else if ("greek".equals(type)) { pizza = new GreekPizza(); } else if ("clam".equals(type)) { pizza = new ClamPizza(); } return pizza; }}
Pizzastore class (client ):
public class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza = SimplePizzaFactory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; }}
Test code:
public class PizzaTestDrive { public static void main(String[] args) { PizzaStore store = new PizzaStore(); Pizza pizza = store.orderPizza("cheese"); System.out.println("Ethan ordered a " + pizza.getName()); pizza = store.orderPizza("clam"); System.out.println("Joel ordered a " + pizza.getName()); }}
2. Example of factory method mode
Different pizza shops in different regions make different pizza products. In the factory method mode, pizzastore is responsible for defining the method for creating pizza. However, the specific implementation of the method is implemented by the pizza shops in various regions and the specific pizza is created.
Abstract Factory class:
Public abstract class pizzastore {public pizza orderpizza (string type) {pizza = createpizza (type); pizza. prepare (); pizza. bake (); pizza. cut (); pizza. box (); Return pizza;} // abstract method, implemented by each subclass. Here we use the Parameterized Factory method protected abstract pizza createpizza (string type );}
Specific factory categories:
public class ChicagoPizzaStore extends PizzaStore { protected Pizza createPizza(String type) { if ("cheese".equals(type)) { return new ChicagoStyleCheesePizza(); } return null; }}
Specific factory categories:
public class NYPizzaStore extends PizzaStore { protected Pizza createPizza(String type) { if ("cheese".equals(type)) { return new NYStyleCheesePizza(); } return null; }}
Test example:
public class PizzaTestDrive { public static void main(String[] args) { PizzaStore nyStore = new NYPizzaStore(); PizzaStore chicagoStore = new ChicagoPizzaStore(); Pizza pizza = nyStore.orderPizza("cheese"); System.out.println("Ethan ordered a " + pizza.getName()); pizza = chicagoStore.orderPizza("cheese"); System.out.println("Joel ordered a " + pizza.getName()); }}
3. Example of Abstract Factory
4. Application of the factory model in JDK
Simple Factory:
- Java. Lang. boolean # valueof (string)
- Java. Lang. Reflect. Proxy # newproxyinstance ()
- Java. Lang. class # forname ()
- Java. Lang. class # newinstance ()
Factory method:
- Java. Lang. Object # tostring ()
Iv. Summary
1. In simple factory mode, a factory class is in the center of product class instantiation. It knows every product and determines which product class should be instantiated. This mode allows the client to be relatively independent from the product creation process, and does not need to modify the client when the system introduces a new product. That is to say, to some extent, it supports the "open-close" principle. However, the disadvantage of this mode is that the support for the "Open-Close" principle is insufficient, because if a new product is added to the system, the factory class needs to be modified, add the necessary logic to the factory class.
2. In the factory method mode, the core factory class is no longer responsible for the creation of all products, but the specific creation work is handed over to the Child class. After the factory method model degrades, it can become much like a simple factory model: imagine that if a system needs only one specific factory class, it would be better to merge the abstract factory into a specific factory class. Due to the use of polymorphism, the factory method pattern maintains the advantages of the simple factory pattern and overcomes its shortcomings.
References:
1. Head first design patterns 2. Java and patterns 3. Design Patterns in JDK