简单工厂模式
简单工厂的定义:定义一个创建对象的类,该类封装了实例化对象的行为。在实际开发中,如果我们遇到了需要大量创建某种、某类、某批对象时,就会用到工厂模式。
工厂模式更多的是一种理念,即将类的创建和使用分开,下面通过一个披萨订购的小案例说明简单工厂模式的这种理念。
package factory.simplefactory;
/**
* 设计一个披萨商店项目,可完成Pizza订购功能
*
* 要求:1、便于扩展pizza的种类
* 2、便于维护
*/
public class PizzaStore {
public static void main(String[] args) {
// main方法相当于一个客户端,调用OrderPizza类来订购pizza
OrderPizza orderPizza1 = new OrderPizza("cheese");
OrderPizza orderPizza2 = new OrderPizza("bbq");
}
}
/**
* OrderPizza是pizza订购类,它可以根据客户端传来的pizza类型创建不同种类的pizza
*
* 代码这样写是没问题的,但是违反了ocp原则(对扩展开放,对修改关闭)。如果新增一个Pizza子类,需要加if分支。
* 而且类的依赖太多,Order依赖了Pizza接口及其所有子类,因此耦合性太大。
* 实际中,可能有多个订购pizza的入口(即多种形式的OrderPizza类),那么Pizza接口及子类的修改必然导致各个OrderPizza类的修改
*
* 由此引出工厂模式,即将类的创建和类的使用分开,工厂负责创建指定的对象,使用者拿到想要的对象后,用就行了,不需要关心怎么创建的。
*
* 这样Pizza有再多的子类,也只修改工厂,使用者无需修改了。
*/
class OrderPizza {
private Pizza pizza;
OrderPizza(String pizzaType) {
if (pizzaType == "cheese") {
pizza = new CheesePizza();
} else if (pizzaType == "bbq") { // if判断会随着Pizza子类的增加而增加
pizza = new BBQPizza();
}
pizza.make();
pizza.pack();
}
}
// 下面就是最终要用到的Pizza产品族
abstract class Pizza {
public abstract void make(); // 制作
public abstract void pack(); // 打包
}
class CheesePizza extends Pizza{
@Override
public void make() {
System.out.println(" 芝士披萨制作 ");
}
@Override
public void pack() {
System.out.println(" 芝士披萨打包 ");
}
}
class BBQPizza extends Pizza {
@Override
public void make() {
System.out.println(" 烤肉披萨制作 ");
}
@Override
public void pack() {
System.out.println(" 烤肉披萨打包 ");
}
}
上述代码的类图是下面这样的,可以看到OrderPizza类依赖于所有的Pizza类。
那么,如果OrderPizza有多个呢?依赖关系会爆炸式增加,如下图:
综上,我们引出简单工厂模式,即在OrderPizza和Pizza之间再加一层类,这个类专注于产生Pizza类的对象,修改后的代码如下:
// 这里无需再去new对象,而是从工厂里拿
class OrderPizzaFromWeb {
private Pizza pizza;
private PizzaFactory pizzaFactory;
OrderPizzaFromWeb(String pizzaType) {
this.pizza = PizzaFactory.getPizzaInstance(pizzaType);
pizza.make();
pizza.pack();
}
}
// 这里无需再去new对象,而是从工厂里拿
class OrderPizzaFromMobile {
private Pizza pizza;
private PizzaFactory pizzaFactory;
OrderPizzaFromMobile(String pizzaType) {
this.pizza = PizzaFactory.getPizzaInstance(pizzaType);
pizza.make();
pizza.pack();
}
}
// 简单工厂,用来解耦类和类的使用者
class PizzaFactory {
private static Pizza pizza;
public static Pizza getPizzaInstance(String pizzaType) {
if (pizzaType == "cheese") {
pizza = new CheesePizza();
} else if (pizzaType == "bbq") {
pizza = new BBQPizza();
}
return pizza;
}
}
类图如下,这样就非常的解耦了。