设计模式---抽象工厂

目录

前言

1、简单工厂

2、静态工厂

3、工厂方法模式(使用继承)

4、抽象工厂(使用组合)


前言

为什么需要工厂模式?

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

1、简单工厂

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

public class SimplePizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza = null;

        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }
        return pizza;
    }
}

2、静态工厂

利用静态方法定义一个简单的工厂。优点:不需要创建工厂类的实例化。缺点:不能通过继承改变创建方法行为。可以简单理解为在简单工厂的基础上添加一个静态关键字

public class SimplePizzaFactory {
    public static Pizza createPizza(String type) {
        Pizza pizza = null;

        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }
        return pizza;
    }
}

3、工厂方法模式(使用继承)

在父类定义了一个创建对象的接口方法,通过让子类决定创建的对象是什么,来达到让对象创建的过程封装的目的。工厂方法让类把实例化推迟到子类。工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样客户程序中超类的代码就和子类对象的创建部分解耦了

4、抽象工厂(使用组合)

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

  • 简单工厂vs工厂模式

简单工厂把全部的事情在一个地方做完了,而工厂模式是一个创建框架,让子类决定如何实现

  • 抽象工厂vs工厂模式

抽象工厂的方法经常以工厂方法的方式实现,抽象工厂的任务是定义一个负责创建一组产品的接口
工厂方法使用继承,抽象工厂使用组合
工厂方法只是用来创建一种产品,而抽象工厂创建的是一个产品家族
使用工厂模式意味着需要扩展一个类并覆盖它的工厂方法。抽象工厂提供了一个创建产品家族的抽象类型,类型的子类定义了产品生产的方式

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

public interface PizzaIngredientFactory {
 
    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Clams createClam();
 
}

子类 

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
 
    public Dough createDough() {
        return new ThinCrustDough();
    }
 
    public Sauce createSauce() {
        return new MarinaraSauce();
    }
 
    public Cheese createCheese() {
        return new ReggianoCheese();
    }
 
    public Veggies[] createVeggies() {
        Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };
        return veggies;
    }
 
    public Pepperoni createPepperoni() {
        return new SlicedPepperoni();
    }

    public Clams createClam() {
        return new FreshClams();
    }
}

Pizza类 

public abstract class Pizza {
    String name;
    // 每个披萨都持有一组在准备时会用到的原料
    Dough dough;
    Sauce sauce;
    Veggies veggies[];
    Cheese cheese;
    Pepperoni pepperoni;
    Clams clams;
 
    // 现在把prepare()方法声明成抽象。在这个方法中,我们需要收集披萨所需的原料,而这些原料当然是来自原料工厂了。
    abstract void prepare();
 
    // 其他的方法保持不动
    void bake(){
        // ...
    }
 
    void cut(){
        // ...
    }
 
    void box(){
        // ...
    }
}
public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;
 
    // 要制作披萨,需要工厂提供原料。
    // 所以每个披萨类都需要从构造器参数中得到一个工厂,并把这个工厂存储在一个实例变量中。
    public CheesePizza(PizzaIngredientFactory ingredientFactory){
        this.ingredientFactory = ingredientFactory;
    }
 
    @Override
    void prepare() {
        // prepare()方法一步一步地创建芝士披萨,每当需要原料时,就跟工厂要。
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
}

Pizza商店

public abstract class PizzaStore {
 
    public Pizza orderPizza(String type) {
        Pizza pizza;
 
        // 现在createPizza()方法从工厂对象中移回PizzaStore
        pizza = createPizza(type);
 
        // 这些都没变
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
 
        return pizza;
    }
 
    // 现在把工厂对象移到这个方法中
    // 在PizzaStore里,“工厂方法”现在是抽象的
    abstract Pizza createPizza(String type);
}
public class NYPizzaStore extends PizzaStore {
 
    protected Pizza createPizza(String item) {
        Pizza pizza = null;
        PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
 
        if (item.equals("cheese")) {
  
            pizza = new CheesePizza(ingredientFactory);
            pizza.setName("New York Style Cheese Pizza");
  
        } else if (item.equals("veggie")) {
 
            pizza = new VeggiePizza(ingredientFactory);
            pizza.setName("New York Style Veggie Pizza");
 
        } else if (item.equals("clam")) {
 
            pizza = new ClamPizza(ingredientFactory);
            pizza.setName("New York Style Clam Pizza");
 
        } else if (item.equals("pepperoni")) {

            pizza = new PepperoniPizza(ingredientFactory);
            pizza.setName("New York Style Pepperoni Pizza");
 
        } 
        return pizza;
    }
}

PizzaStore实现为工厂方法,因为我们需要根据区域变化创建产品。通过工厂方法,每个区域都有自己的具体工厂,他们都知道如何制作适合该区域的披萨。

因为我们需要创建一个产品家族(也就是原料),我们把PizzaIngredientFactory实现为抽象工厂。每个子类都使用其区域的供货商来实现这些原料。

工厂方法使用继承,把对象的创建委托给子类,子类实现工厂方法来创建对象。工厂方法允许类将实例化延迟到子类进行。

抽象工厂使用对象组合,对象的创建被实现在工厂接口所暴露出来的方法中。抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。

所有工厂都是用来封装对象的创建。所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。

参考:

《head first 设计模式》

http://www.importnew.com/23495.html

猜你喜欢

转载自blog.csdn.net/l1394049664/article/details/81568035
今日推荐