工厂模式

1.定义

定义一个创建对象的接口,由子类决定实例化的类是哪一个,工厂方法把类的实例化推迟到子类.

注意:虽然简单工厂模式平常用的很多,但是它更像是一个编程习惯而并不是一个设计模式,工厂模式主要包括工厂模式和抽象工厂模式.

2.代码实现

还是以pizza为例子,上个简单工厂模式中说到了有四种披萨,分别是:芝士披萨,花甲披萨,意式香肠披萨,蔬菜披萨.

假如不同地区生产的pizza不一样,比如有:

纽约芝士披萨,纽约花甲披萨,纽约意式香肠披萨,纽约蔬菜披萨

或者是

芝加哥芝士披萨,芝加哥花甲披萨,芝加哥意式香肠披萨,芝加哥纽约蔬菜披萨.

这些披萨的实现类如下:

定义抽象披萨类

public abstract class Pizza {
    String name;
    String dough;
    String sauce;
    ArrayList toppings = new ArrayList();
    public void prepare() {
        System.out.println("Prepare:"+name);
        System.out.println(toppings);
    }
    public void bake() {
        System.out.println("bake:"+name);
    }
    public void cut() {
        System.out.println("cut:"+name);
    }
    public void box() {
        System.out.println("box:"+name);
    }
    public String getName() {
        return name;
    }
}

纽约四种披萨:

public class NYStyleCheesePizza extends Pizza {

    public NYStyleCheesePizza() {
        name = "NY Style Sauce and Cheese Pizza";
        dough = "Thin Crust Dough";
        sauce = "Marinara Sauce";
        toppings.add("Grated Reggiano Cheese");
    }
    
}
public class NYStyleClamPizza extends Pizza {

}
public class NYStylePepperoniPizza extends Pizza {

}
public class NYStyleVeggiePizza extends Pizza {

}

 

芝加哥四种披萨:

public class ChicagoStyleCheesePizza extends Pizza {

    public ChicagoStyleCheesePizza() {
        name = "Chicago Style Deep and Cheese Pizza";
        dough = "Extra Thick Crust Dough";
        sauce = "Plum Tomato Sauce";
        toppings.add("Shredded Mozzarella Cheese");
    }
    
    public void cut() {
        System.out.println("Cutting the pizza into square slices");
    }
    
}
public class ChicagoStyleClamPizza extends Pizza {

}
public class ChicagoStylePepperoniPizza extends Pizza {

}
public class ChicagoStyleVeggiePizza extends Pizza {

}

 

 

虽然简单工厂可以创建不同的工厂类来生成,但是这些工厂类在传入Store后只能生成一种地区的pizza,如果要生成别的地区的pizza还要重新传入工厂类.

这里我们用改进后的工厂模式实现.

定义抽象披萨商店类,这边和简单工厂模式不同的是定义成了抽象类,因为需要子类来决定具体生产哪一种披萨

public abstract class PizzaStore {
    
    public PizzaStore() {}

    
    public Pizza orderPizza(String type) {
        Pizza pizza;
        pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
    /**
     * 让子类决定生成哪一种披萨
     * @param type 参数类型
     * @return 披萨
     */
    abstract Pizza createPizza(String type);
}

定义纽约披萨商店和芝加哥披萨商店

public class NYStylePizzaStore extends PizzaStore {
    
    public NYStylePizzaStore() {
        super();
    }


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

}
public class ChicagoStylePizzaStore extends PizzaStore {


    @Override
    Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            return new ChicagoStyleCheesePizza();
        } else if (type.equals("pepperoni")) {
            return new ChicagoStylePepperoniPizza();
        } else if (type.equals("veggie")) {
            return new ChicagoStyleVeggiePizza();
        } else if (type.equals("clam")) {
            return new ChicagoStyleClamPizza();
        }
        return null;
    }

}

 

定义测试类并进行测试

public class PizzaTest {
     public static void main(String[] args) {
         PizzaStore nyPizzaStore = new NYStylePizzaStore();
         PizzaStore chicagoStore = new ChicagoStylePizzaStore();
         
         Pizza pizza = nyPizzaStore.orderPizza("cheese");
         System.out.println();
         pizza = chicagoStore.orderPizza("cheese");
         /*
              输出如下:
            Prepare:NY Style Sauce and Cheese Pizza
            [Grated Reggiano Cheese]
            bake:NY Style Sauce and Cheese Pizza
            cut:NY Style Sauce and Cheese Pizza
            box:NY Style Sauce and Cheese Pizza
            
            Prepare:Chicago Style Deep and Cheese Pizza
            [Shredded Mozzarella Cheese]
            bake:Chicago Style Deep and Cheese Pizza
            Cutting the pizza into square slices
            box:Chicago Style Deep and Cheese Pizza
          */
    }
}

 

3.总结

可以看到工厂模式最主要的特点就是子类决定生成哪一种披萨,虽然和简单工厂模式有点像,if  else 挺多的,但是子类来做决定的话弹性更高一点,而且也更直观理解要生成什么对象.

虽然工厂模式避免不了用new关键字创建类,但是它把类的创建都归并到一起了,便于管理.

反射也可以创建类,spring就是通过反射来实现ioc的.

 

posted @ 2019-07-01 18:56  随意的马蒂洛克  阅读(126)  评论(0编辑  收藏  举报