设计模式 -- 工厂模式

所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。

理论介绍
  • 工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
  • 抽象工厂模式:提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。
应用场景
  • 工厂方法模式:可以将你的客户代码从需要实例化的具体类中解耦。或者如果你目前还不知道将来需要实例化哪些具体类时,可以选择使用。使用方法简单,只需要继承成子类,并实现他的工厂方法。
  • 抽象工厂模式:需要创建产品家族和想让制造的相关产品集合时,可以选择使用。这是通过对象的组合
代码实现参考
工厂方法模式
//PizzaStore.java
package factory_pattern.factory1;

public abstract class PizzaStore {

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

    //把工厂对象的这个方法移到这里来
    abstract Pizza createPizza(String type);
}

将PizzaStore定义为抽象类,让每个地方具体的NYPizzaStore和ChicagoPizzaStore去继承PizzaStore。

package factory_pattern.factory1;

public class NYPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new NYStyleCheesePizza();
        }else if (type.equals("veggie")){
            return new NYStyleVeggiePizza();
        }else if (type.equals("clam")){
            return new NYStyleClamPizza();
        }else if (type.equals("pepperoni")){
            return new NYStylePepperoniPizza();
        }else {
            return null;
        }
    }
}

-------------------------------------------------------------------------------------
public class ChicagoPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new ChicagoCheesePizza();
        }else if (type.equals("veggie")){
            return new ChicagoVeggiePizza();
        }else if (type.equals("clam")){
            return new ChicagoClamPizza();
        }else if (type.equals("pepperoni")){
            return new ChicagoPepperoniPizza();
        }else {
            return null;
        }
    }
}

让每个具体的类的createPizza()创建各自风味的不同种类的Pizza。

工厂方法模式

package factory_pattern.factory1;

public class Test {
    public static void main(String[] args) {
        NYPizzaStore pizzaStore = new NYPizzaStore();
        Pizza pepperoni = pizzaStore.orderPizza("pepperoni");
        System.out.println(pepperoni.getClass().getSimpleName());

        System.out.println("---------------------------------");

        ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
        Pizza clam = chicagoPizzaStore.orderPizza("clam");
        System.out.println(clam.getClass().getSimpleName());

    }
}

那么只需要创建一个具体的PizzaStore,在orderPizza()方法中选择口味,就可以了。
这我们就利用Pizza工厂定制了Pizza。

抽象工厂方法

抽象工厂模式与前者虽然操作不一样,但目的一致。

抽象工厂模式
这时考虑到需要建造一个原料工厂来生成原料。由于每个地区存在差异,将所有的原料抽象成一个接口。

package factory_pattern.factory2;
public interface PizzaIngredientFactory {
    public Dough createDough();
    public Sauce createSauce();
    //...other ingredient...
}

同样需要具体的工厂类实现。

package factory_pattern.factory2;

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    @Override
    public Dough createDough() {
        return null;
    }

    @Override
    public Sauce createSauce() {
        return null;
    }
}

重做Pizza…

package factory_pattern.factory2;

public abstract class Pizza {
    Dough dough;
    Sauce sauce;
    abstract void prepare();
    void bake(){}
    void cut(){}
    void box(){}
}

package factory_pattern.factory2;

public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;

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

    @Override
    void prepare() {
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
    }
}

总结一下,我们到底做了什么。我们引入新类型的抽象工厂,来创建Pizza原料家族(集合)。通过抽象工厂所提供的接口,可以创建产品的家族,利用这个接口书写代码,我们的代码将从实际工厂解耦,以便在不同的上下文中实现各式各样的工厂,制造出不同的产品。

补充

依赖倒置原则:不能让高层组件依赖低层组件,两者都应该依赖于抽象。

祝进步

猜你喜欢

转载自blog.csdn.net/zhaohancsdn/article/details/88891794