设计模式--工厂模式

工厂模式分为简单工厂模式,工厂方法模式和抽象工厂模式。
(1)简单工厂模式
简单工厂模式并不是一个设计模式,看起来更像是一种编程模式,但是由于经常被使用就被称之为一种设计模式。例如:

public class PizzaStore {

    SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory) {
        this.factory = factory;
    }

    Pizza orderPizza(String type) {
        Pizza pizza = null;
        pizza = factory.createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

因为pizza = factory.createPizza(type);是一个根据不同的场景会变化的代码块,所以把这一块代码抽取出来形成一个工厂类

public class SimplePizzaFactory {

    public Pizza createPizza(String type){
        Pizza pizza =null;
        if(type.equals("cheese")){
            pizza=new CheesePizza();
        }else if(type.equals("clam")){
            pizza=new ClamPizza();
        }
        return pizza;
    }

}

当需要创建不同的产品时只需要改变工厂类中的代码就可以,而PizzaStore 并不关心。

public class Pizza {

    String name;
    String dough;
    String sauce;
    ArrayList<String> toppings = new ArrayList<String>();

    void prepare() {
        System.out.println("Prepare " + name);
        System.out.println("Tossing dough..");
        System.out.println("Adding sauce.. ");
        System.out.println("Adding toppings");
        for (int i = 0; i < toppings.size(); i++) {
            System.out.println("  " + toppings.get(i));
        }
    }

    void bake() {
        System.out.println("Baking for 25min at 350");
    }

    void cut() {
        System.out.println("将披萨切成许多块。。");
    }

    void box() {
        System.out.println("请把披萨装到装披萨的包装盒里");
    }

    public String getName() {
        return name;
    }
}

加长Pizza类就是一个完整的简单工厂模式。
(2)工厂方法模式
所有的工厂模式都是用来封装对象的创建,工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象的过程进行封装的目的。
同样还是上面的例子,当PizzaStore要引进不同的风味时,简单工厂模式就不能很方便的实现。所以在createPizza时就需要根据不同的PizzaStore来创建,那么新的PizzaStore为:

public abstract class PizzaStore {

    public static String CHEESE = "cheese";

    public Pizza orderPizza(String type) {
        Pizza pizza = null;
        pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

    public abstract Pizza createPizza(String type);
}

将createPizza方法抽象出来,由PizzaStore的子类去实现要创建什么样的pizza。
例如创建一个NY风格和Chicago风格的pizza;

public class NYStyleCheesePizza extends Pizza {

    public NYStyleCheesePizza() {
        name="纽约芝士披萨";
        dough="纽约芝士披萨 面";
        sauce="纽约芝士披萨 酱汁";
        toppings.add("纽约芝士披萨");
    }
}
public class NYStylePizzaStore extends PizzaStore {

    @Override
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals(PizzaStore.CHEESE)) {
            pizza = new NYStyleCheesePizza();
        }
        return pizza;
    }

}

这样就形成了一个工厂方法模式的例子。总的来说工厂方法模式定义了一个创建对象的接口,但由子类决定实例化的是哪一个,工厂方法让类把实例化推迟到子类。
那么工厂方法模式和简单工厂模式的区别是什么呢?
简单工厂把全部的事情在一个地方就处理完了,然而工厂方法模式创建了一个框架,让子类决定如何实现。简单工厂不具备工厂方法的弹性,因为简单工厂不能更改已经在创建的产品。
(3)抽象工厂模式
抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定类。抽象工厂模式允许客户使用抽象的接口来实现一组相关的产品,而不需要实际产出的具体是什么,这样一来客户就从具体的产品中被解耦。
还是上面的例子,由于NY和Chicago是处于不同的地方,所以产品在原料上也会有很大的区别,所以根据不同的商店使用不同的原料。

public interface PizaaIngredientFactory {

    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Clams createClams();
}

定义一个接口,负责创建所有的原料。那么下一步需要做的事就是
1、为每一个区域创建一个工厂;
2、实现一组原料类供工厂使用;
3、然后将这些组织起来,将新的原料工厂放到以前的PizzaStore中。
NY原料工厂的实现:

public class NYPizzaIngredientFactory implements PizaaIngredientFactory{

    @Override
    public Dough createDough() {
        return new ThinCrustDough();
    }

    @Override
    public Sauce createSauce() {
        return new MarinaraSauce();
    }

    @Override
    public Clams createClams() {
        return new FreshClams();
    }

}

其中省略了一部分原料的实现都一样,Chicago原来工厂:

public class ChicagoPizzaIngredientFactory implements PizaaIngredientFactory{

    @Override
    public Dough createDough() {
        return new ThickCrustDough();
    }

    @Override
    public Sauce createSauce() {
        return new PlumTomatoSauce();
    }
}

原料类,其他的类似。。。。。

public class ThickCrustDough implements Dough {

    public String toString() {
        return "用于chicago的Dough";
    }
}

然后重新实现Pizza类

public abstract class Pizza {
    String name;
    Dough dough;
    Sauce sauce;
    Veggies veggies[];
    Cheese cheese;
    Pepperoni pepperoni;
    Clams clams;

    abstract void prepare();

    void bake() {
        System.out.println("bake for 25 minutes at 350");
    }

    void cut() {
        System.out.println("切披萨。。。");
    }

    void box() {
        System.out.println("包装披萨。。。。");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

特定的CheesePizza,其他的类似。。。。

public class CheesePizza extends Pizza{

    PizaaIngredientFactory ingredientFactory;

    public CheesePizza(PizaaIngredientFactory ingredientFactory) {
        this.ingredientFactory = ingredientFactory;
    }

    @Override
    void prepare() {
        System.out.println("开始准备..."+name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }

}

重新实现NYPizzaStore….,其他的类似。,,

public class NYPizzaStore extends PizzaStore {

    @Override
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        PizaaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
        if (type.equals("cheese")) {
            pizza = new CheesePizza(ingredientFactory);
            pizza.setName("纽约芝士披萨");
        }
        return pizza;
    }

}

那么一个抽象工厂也就实现了,通过以上的代码,引入了新的工厂来原件新的原料家族。测试。。。

public class AbstractFactoryTest {

    public static void main(String[] args) {
        PizzaStore nyPizzaStore = new NYPizzaStore();
        Pizza pizza = nyPizzaStore.orderPizza("cheese");
        System.out.println("-----"+pizza.getName());

    }
}

总结:
简单工厂,虽然不是真正的设计模式,但是可以将程序从具体类中解耦。
工厂方法模式使用继承,把对象委托给子类,子类实现工厂方法来创建对象。
抽象工厂使用组合,对象的创建被实现在工厂接口所暴露的方法中。
所有的工厂模式都是通过减少应用程序和具体类之间的耦合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值