工厂模式&抽象工厂——HeadFirst设计模式学习笔记

当使用new实例化一个类时,使用的是实现,而不是接口,代码捆绑着具体类会导致代码更脆弱缺乏弹性,使用松耦合的OO模式可以得到解脱。

工厂:封装对象的创建,处理创建对象的细节

静态工厂:利用静态方法定义一个简单的工厂。优点:不需要创建工厂类的实例化。缺点:不能通过继承改变创建方法行为。

简单工厂:简单工厂并不是一种设计模式,因为只是简单的把创建对象的代码封装起来

工厂模式:在父类定义了一个创建对象的接口,通过让子类决定创建的对象是什么,来达到让对象创建的过程封装的目的。工厂方法让类把实例化推迟到子类

抽象工厂:提供一个接口,用于创建相关或依赖对象的家族,而不需要指明具体的类

特点:

  • 工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样客户程序中超类的代码就和子类对象的创建部分解耦了
  • 简单工厂vs工厂模式:简单工厂把全部的事情在一个地方做完了,而工厂模式是一个创建框架,让子类决定如何实现
  • 抽象工厂vs工厂模式
    • 抽象工厂的方法经常以工厂方法的方式实现,抽象工厂的任务是定义一个负责创建一组产品的接口
    • 工厂方法使用继承,抽象工厂使用组合
    • 工厂方法只是用来创建一种产品,而抽象工厂创建的是一个产品家族
    • 使用工厂模式意味着需要扩展一个类并覆盖它的工厂方法。抽象工厂提供了一个创建产品家族的抽象类型,类型的子类定义了产品生产的方式

设计原则:

  • 依赖倒置原则:要依赖抽象,不要依赖具体类。高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。(http://baike.baidu.com/link?url=mYRSYyXnTF-kbBdpEpLn53DrmxWb2QJBIIbxS4PA5IkqKJQolObBS8fzAXU81mOX962UcGuwwY6UOlAUavEX1WFQdJY7Xg96ezG7vj-Ss_y_8R_fCiSmSGN-DMM6XSroAmE6sKIFiSSBXJIOBl7cca)
    • 变量不要持有具体类的引用
    • 不要让类派生至具体类
    • 不要覆盖基类中实现的方法

 类图及代码:

1、简单工厂

 1 public class SimplePizzaFactory {
 2     public Pizza createPizza(String type) {
 3         Pizza pizza = null;
 4 
 5         if (type.equals("cheese")) {
 6             pizza = new CheesePizza();
 7         } else if (type.equals("pepperoni")) {
 8             pizza = new PepperoniPizza();
 9         } else if (type.equals("clam")) {
10             pizza = new ClamPizza();
11         } else if (type.equals("veggie")) {
12             pizza = new VeggiePizza();
13         }
14         return pizza;
15     }
16 }

2、工厂模式

 1 public abstract class PizzaStore {
 2  
 3     //这里定义一个工厂方法
 4     abstract Pizza createPizza(String item);
 5  
 6     public Pizza orderPizza(String type) {
 7     
 8         Pizza pizza = createPizza(type);
 9         
10         System.out.println("--- Making a " + pizza.getName() + " ---");
11         pizza.prepare();
12         pizza.bake();
13         pizza.cut();
14         pizza.box();
15         
16         return pizza;
17     }
18 }
 1 public class ChicagoPizzaStore extends PizzaStore {
 2 
 3     Pizza createPizza(String item) {
 4             if (item.equals("cheese")) {
 5                     return new ChicagoStyleCheesePizza();
 6             } else if (item.equals("veggie")) {
 7                     return new ChicagoStyleVeggiePizza();
 8             } else if (item.equals("clam")) {
 9                     return new ChicagoStyleClamPizza();
10             } else if (item.equals("pepperoni")) {
11                     return new ChicagoStylePepperoniPizza();
12             } else return null;
13     }
14 }
 1 public class PizzaTestDrive {
 2  
 3     public static void main(String[] args) {
 4         PizzaStore nyStore = new NYPizzaStore();
 5  
 6         Pizza pizza = nyStore.orderPizza("cheese");
 7         System.out.println("Ethan ordered a " + pizza.getName() + "\n");
 8 
 9         pizza = nyStore.orderPizza("clam");
10         System.out.println("Ethan ordered a " + pizza.getName() + "\n");
11     }
12 }

3、抽象工厂

 

先来定义一个接口PizzaIngredientFactory,他定义了一系列的创建Pizza材料的方法

 1 public interface PizzaIngredientFactory {
 2  
 3     public Dough createDough();
 4     public Sauce createSauce();
 5     public Cheese createCheese();
 6     public Veggies[] createVeggies();
 7     public Pepperoni createPepperoni();
 8     public Clams createClam();
 9  
10 }

子类

 1 public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
 2  
 3     public Dough createDough() {
 4         return new ThinCrustDough();
 5     }
 6  
 7     public Sauce createSauce() {
 8         return new MarinaraSauce();
 9     }
10  
11     public Cheese createCheese() {
12         return new ReggianoCheese();
13     }
14  
15     public Veggies[] createVeggies() {
16         Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };
17         return veggies;
18     }
19  
20     public Pepperoni createPepperoni() {
21         return new SlicedPepperoni();
22     }
23 
24     public Clams createClam() {
25         return new FreshClams();
26     }
27 }

Pizza类

 1 public class CheesePizza extends Pizza {
 2     //这里组合了一个PizzaIngredientFactory对象的引用,用于提供不同的原料
 3     PizzaIngredientFactory ingredientFactory;
 4  
 5     /**
 6      * 通过传入一个PizzaIngredientFactory原料工厂,我们可以在制作Pizza的时候动态的产生所需要的原料
 7      * @param ingredientFactory
 8      */
 9     
10     public CheesePizza(PizzaIngredientFactory ingredientFactory) {
11         this.ingredientFactory = ingredientFactory;
12     }
13  
14     void prepare() {
15         System.out.println("Preparing " + name);
16         dough = ingredientFactory.createDough();
17         sauce = ingredientFactory.createSauce();
18         cheese = ingredientFactory.createCheese();
19     }
20 }

Pizza商店

 1 public class NYPizzaStore extends PizzaStore {
 2  
 3     protected Pizza createPizza(String item) {
 4         Pizza pizza = null;
 5         PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
 6  
 7         if (item.equals("cheese")) {
 8   
 9             pizza = new CheesePizza(ingredientFactory);
10             pizza.setName("New York Style Cheese Pizza");
11   
12         } else if (item.equals("veggie")) {
13  
14             pizza = new VeggiePizza(ingredientFactory);
15             pizza.setName("New York Style Veggie Pizza");
16  
17         } else if (item.equals("clam")) {
18  
19             pizza = new ClamPizza(ingredientFactory);
20             pizza.setName("New York Style Clam Pizza");
21  
22         } else if (item.equals("pepperoni")) {
23 
24             pizza = new PepperoniPizza(ingredientFactory);
25             pizza.setName("New York Style Pepperoni Pizza");
26  
27         } 
28         return pizza;
29     }
30 }

 

posted @ 2016-10-22 13:24  HectorHou  阅读(973)  评论(0编辑  收藏  举报