概念:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
上一篇博文我们了解了简单工厂模式,我们创建一个简单的工厂去创建披萨,但是我们只能创建一种风味的披萨,比如原生
风味的披萨,如果我们想再创建一种风味的披萨工厂,我们只能再创建一个对应的工厂。此时我们的披萨也不得不跟着也要
创建一个,这样程序就耦合了。所以我们来看看如何用工厂模式解决这个问题。
代码实现:
1,还是先定义披萨接口以及原生风味和纽约风味各自两种披萨(奶酪和蛤蜊)
package factorymode.factory; /** * @ClassName Pizaa * @Description 定义披萨接口 * @Author liuyi * @Date 2020/6/15 20:50 * @Version 1.0 */ public interface Pizaa { //准备 public void prepare(); //烘烤 public void bake(); //切片 public void cut(); //包装 public void box(); }
package factorymode.factory; /** * @ClassName CheesePizza * @Description 奶酪披萨 * @Author liuyi * @Date 2020/6/15 20:58 * @Version 1.0 */ public class CheesePizza implements Pizaa{ @Override public void prepare() { System.out.println("准备生产奶酪披萨"); } @Override public void bake() { System.out.println("烘烤奶酪披萨"); } @Override public void cut() { System.out.println("切片奶酪披萨"); } @Override public void box() { System.out.println("包装奶酪披萨"); } }
package factorymode.factory; /** * @ClassName ClamPizza * @Description 蛤蜊披萨 * @Author liuyi * @Date 2020/6/15 21:00 * @Version 1.0 */ public class ClamPizza implements Pizaa{ @Override public void prepare() { System.out.println("准备生产蛤蜊披萨"); } @Override public void bake() { System.out.println("烘烤蛤蜊披萨"); } @Override public void cut() { System.out.println("切片蛤蜊披萨"); } @Override public void box() { System.out.println("包装蛤蜊披萨"); } }
package factorymode.factory; /** * @ClassName CheesePizza * @Description 奶酪披萨 * @Author liuyi * @Date 2020/6/15 20:58 * @Version 1.0 */ public class NewYorkCheesePizza implements Pizaa{ @Override public void prepare() { System.out.println("准备生产纽约风味奶酪披萨"); } @Override public void bake() { System.out.println("烘烤纽约风味奶酪披萨"); } @Override public void cut() { System.out.println("切片纽约风味奶酪披萨"); } @Override public void box() { System.out.println("包装纽约风味奶酪披萨"); } }
package factorymode.factory; /** * @ClassName ClamPizza * @Description 蛤蜊披萨 * @Author liuyi * @Date 2020/6/15 21:00 * @Version 1.0 */ public class NewYorkClamPizza implements Pizaa{ @Override public void prepare() { System.out.println("准备生产蛤蜊披萨"); } @Override public void bake() { System.out.println("烘烤蛤蜊披萨"); } @Override public void cut() { System.out.println("切片蛤蜊披萨"); } @Override public void box() { System.out.println("包装蛤蜊披萨"); } }
2,定义一个创建对象的抽象类,这里为什么不是接口,其实不管是接口还是抽象类都是多态的一种呈现,这里用抽象类
的目的就是固定生产披萨的流程准备,烘烤,切面,封装(不能让我们的加盟店偷工减料,砸了自己的招牌。。。。)
package factorymode.factory;
/**
* @ClassName PizzaStrore
* @Description 定义购买披萨的商店的抽象类
* @Author liuyi
* @Date 2020/6/15 21:07
* @Version 1.0
*/
public abstract class PizzaStrore {
//订购披萨方法
public Pizaa orderPizza(String type){
Pizaa pizaa;
pizaa = createPizza(type);
pizaa.prepare();
pizaa.bake();
pizaa.cut();
pizaa.box();
return pizaa;
}
//定义抽象的创建披萨的方法
abstract Pizaa createPizza(String type);
}
3,为了迎合纽约市民的口味,在纽约附近创建一个纽约风味披萨店,即创建一个商店的具体实现类。子类自己去实现获取对象的方法
package factorymode.factory; /** * @ClassName PrimaryPizzaStrore * @Description TODO * @Author liuyi * @Date 2020/6/16 23:32 * @Version 1.0 */ public class NewYorkPizzaStrore extends PizzaStrore { @Override Pizaa createPizza(String type) { Pizaa pizaa = null; switch (type){ case "cheese": pizaa = new NewYorkCheesePizza(); break; case "clam": pizaa = new NewYorkClamPizza(); break; } return pizaa; } }
4,最后我们来看看如何生产一个纽约风味的奶酪披萨。
package factorymode.factory; /** * @ClassName Test * @Description TODO * @Author liuyi * @Date 2020/6/16 23:34 * @Version 1.0 */ public class Test { public static void main(String[] args) { //创建一个纽约风味的披萨商店 PizzaStrore pizzaStrore = new NewYorkPizzaStrore(); //调用orderPizza方法生产奶酪披萨 pizzaStrore.orderPizza("cheese"); // PizzaStrore pizzaStrore = new PrimaryPizzaStrore(); // pizzaStrore.orderPizza("cheese"); } }
分析生产披萨的流程,首先定义一个我们需要的风味披萨店,然后生产我们想要的披萨种类。此时我们再来看抽象披萨商店PizzaStrore,
在orderPizza方法中调用了createPiazza方法去创建披萨,但是我们在进行4个加工步骤的时候其实是不知道具体是什么类型的披萨的,达到了解耦的目的。
如果我们还要增加一种风味的商店,只需要创建一个类继承PizzaStrore,然后自己去实现创建对应风味的披萨对象的方法,这样我们的购买流程代码基本
不会改变,只是需要创建对应的商店即可,这样我们的代码就相比于简单工厂更利于扩展,更加灵活。