工厂模式
概念
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
举一个简单的栗子
需求
假设现在我们正在开一家比萨店,店里有许多的种类的披萨, 比如奶油披萨,虾仁披萨。每个披萨都需要经过准备,制作,切割,包装四个步骤。最后我们需要在一个前台中将披萨销售出去
简易类图
简易实现
-
Pizza
package factory.model; public abstract class Pizza { private String name; public Pizza(String name){ this.name = name; } public void prepare(){ System.out.println(name + "正在准备"); } public void make(){ System.out.println(name + "正在制作"); } public void cut(){ System.out.println(name + "正在切割"); } public void pack(){ System.out.println(name + "正在打包"); } }
这是一个抽象类,所有的披萨都继承这个类。
-
MilkPizza
package factory.model; public class MilkPizza extends Pizza{ public MilkPizza() { super("牛奶披萨"); } }
-
ShrimpPizza
package factory.model; public class ShrimpPizza extends Pizza { public ShrimpPizza() { super("虾仁披萨"); } }
-
Order
package factory.order; import factory.model.MilkPizza; import factory.model.Pizza; import java.util.Scanner; public class Order { public void orderPizza(){ do{ System.out.print("请输入披萨类型"); Scanner scanner = new Scanner(System.in); String type = scanner.next(); Pizza pizza = null; if ("milk".equals(type)){ pizza = new MilkPizza(); } else if ("shrimp".equals(type)){ pizza = new ShrimpPizza(); } if(pizza == null){ break; } pizza.prepare(); pizza.make(); pizza.cut(); pizza.pack(); }while (true); } }
-
PizzaStore
package factory.store; import factory.order.Order; public class PizzaStore{ public static void main(String[] args) { Order order = new Order(); order.orderPizza(); } }
代码分析
优点:
- 这是最容易想到的代码
- 整体逻辑较为清晰
缺点:
- 比如我们现在全国有128家门店,突然总部提出新增一个板栗披萨。如果按照现在这种设计的话,我们需要修改128个
orderPizza
方法,这显然不切实际。
针对于以上的缺点,我们引入简单工厂设计模式。
简单工厂设计模式
这种设计思想本质上,就是在Order类与Pizza类之间加一个缓冲层,让工厂去接管创建Pizza的功能
代码修改
-
SimpleFactory
package factory; import factory.model.MilkPizza; import factory.model.Pizza; import factory.model.ShrimpPizza; public enum SimpleFactory { SIMPLE_FACTORY; public Pizza createPizza(String type){ Pizza pizza = null; if ("milk".equals(type)){ pizza = new MilkPizza(); } else if ("shrimp".equals(type)){ pizza = new ShrimpPizza(); } return pizza; } }
-
Order
package factory.order; import factory.SimpleFactory; import factory.model.Pizza; import java.util.Scanner; public class Order { public void orderPizza(){ do{ System.out.print("请输入披萨类型"); Scanner scanner = new Scanner(System.in); String type = scanner.next(); Pizza pizza = SimpleFactory.SIMPLE_FACTORY.createPizza(type); if(pizza == null){ break; } pizza.prepare(); pizza.make(); pizza.cut(); pizza.pack(); }while (true); } }
缺点
- 虽然解决了无法统一创建披萨的问题。但是也带来了新的问题。
- 如果存在两个门店,一个门店有胡椒披萨,而另一个门店没有胡椒披萨。这个时候当前的设计模式现在无法满足需求
工厂方法模式
定义一个抽象的创建对象方法,借由子类决定实例化的类。
-
AbstractOrder
package factory.order; import factory.SimpleFactory; import factory.model.Pizza; import java.util.Scanner; public abstract class AbstractOrder { public void orderPizza(){ do{ System.out.print("请输入披萨类型"); Scanner scanner = new Scanner(System.in); String type = scanner.next(); Pizza pizza = create(type); if(pizza == null){ break; } pizza.prepare(); pizza.make(); pizza.cut(); pizza.pack(); }while (true); } protected abstract Pizza create(String type); }
-
BeijingOrder
package factory.order; import factory.model.MilkPizza; import factory.model.PepperPizza; import factory.model.Pizza; import factory.model.ShrimpPizza; public class BeijingOrder extends AbstractOrder { @Override protected Pizza create(String type) { Pizza pizza = null; if ("milk".equals(type)){ pizza = new MilkPizza(); } else if ("shrimp".equals(type)){ pizza = new ShrimpPizza(); }else if ("pepper".equals(type)){ pizza = new PepperPizza(); } return pizza; } }
-
ShanghaiOrder
package factory.order; import factory.model.MilkPizza; import factory.model.Pizza; import factory.model.ShrimpPizza; public class ShanghaiOrder extends AbstractOrder { @Override protected Pizza create(String type) { Pizza pizza = null; if ("milk".equals(type)){ pizza = new MilkPizza(); } else if ("shrimp".equals(type)){ pizza = new ShrimpPizza(); } returnpizza; } }
-
PizzaStore
package factory.store; import factory.order.AbstractOrder; import factory.order.BeijingOrder; public class PizzaStore{ public static void main(String[] args) { AbstractOrder beijing = new BeijingOrder(); beijing.orderPizza(); } }
抽象工厂模式
这个模式可以看作工厂方法模式与简单工厂模式的结合。它将创建Pizza的类抽象成一个接口,所有需要用到创建Pizza功能的类都去实现这个接口。
-
IFactory
package factory; import factory.model.Pizza; public interface IFactory { Pizza create(String type); }
-
BeiJingFactory
package factory; import factory.IFactory; import factory.model.MilkPizza; import factory.model.PepperPizza; import factory.model.Pizza; import factory.model.ShrimpPizza; public class BeiJingFactory implements IFactory { @Override public Pizza create(String type) { Pizza pizza = null; if ("milk".equals(type)){ pizza = new MilkPizza(); } else if ("shrimp".equals(type)){ pizza = new ShrimpPizza(); }else if ("pepper".equals(type)){ pizza = new PepperPizza(); } return pizza; } }
-
Order
package factory.order; import factory.IFactory; import factory.model.Pizza; import java.util.Scanner; public class Order { public void orderPizza(IFactory factory){ do{ System.out.print("请输入披萨类型"); Scanner scanner = new Scanner(System.in); String type = scanner.next(); Pizza pizza = factory.create(type); if(pizza == null){ break; } pizza.prepare(); pizza.make(); pizza.cut(); pizza.pack(); }while (true); } }
-
PizzaStore
package factory.store; import factory.BeiJingFactory; import factory.order.Order; public class PizzaStore{ public static void main(String[] args) { Order order = new Order(); order.orderPizza(new BeiJingFactory()); } }
说明
pizza.pack();
}while (true);
}
}
- `PizzaStore`
```java
package factory.store;
import factory.BeiJingFactory;
import factory.order.Order;
public class PizzaStore{
public static void main(String[] args) {
Order order = new Order();
order.orderPizza(new BeiJingFactory());
}
}
说明
- 这种方式较之前两种更具备拓展性。