这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
提出问题
在实际编码中,我们经常需要选择地 new 出多个对象,就像是零售店在售卖产品时,总是需要根据用户的临时选择来提供不同的商品对象:
class Store {
Product order(type) {
Product production;
if(isMilk) {
production = new Milk();
} else if(isBread) {
production = new Bread();
}
return production;
}
}
使用 new 是没有问题的,问题总是出现在改变的时候,一旦零售店增添了或者删减了新的产品,由于有大量实例化具体类,就必须对它本身代码做出修改。在理想情况下,我们的代码应该是对修改关闭而对扩展开放的。这样当商品发生改变时,零售店本身不需要发生改变,这时候我们考虑将变化的部分抽取出来并使用多态。
简单工厂模式
Pizza店的改进
参考 Head Firse 设计模式 首先假设我们有一个 Pizza 的零售店,售卖各种不同种类的 Pizza,为了把变化的部分剥离出来,我们可以假想一个生产 Pizza 的工厂,根据我们的订单为我们返回不同种类的 Pizza,在零售店中我们使用多态来完成调用。
/**
* 首先实现一个Piiza的抽象类
* 包含Pizza的种类名字和对已完成的pizza的操作
*/
abstract class Pizza {
String name;
void brake() {
System.out.println("brake");
}
void cut() {
System.out.println("cut");
}
void box() {
System.out.println("box");
}
}
然后我们由抽象类派生一些具体的 Pizza 类
class CheesePizza extends Pizza {
CheesePizza() {
name = "cheesePizza";
}
}
class PepperoniPizza extends Pizza {
PepperoniPizza() {
name = "PepperoniPizza";
}
}
然后我们制定一个生产 Pizza 的简单工厂,用来根据需要 new 出不同的对象
class SimplePizzaFactory {
static Pizza createPizza(String type) {
Pizza pizza = null;
if(type.equals("cheese")) {
System.out.println("creating CheesePizza");
pizza = new CheesePizza();
}else if(type.equals("pepperoniPizza")) {
System.out.println("creating PepperoniPizza");
pizza = new PepperoniPizza();
}
return pizza;
}
}
接下来就可以实现这个 Pizza 零售店
class PizzaStore {
Pizza orderPizza(String type) {
Pizza pizza = SimplePizzaFactory.createPizza(type);
pizza.brake();
pizza.cut();
pizza.box();
return pizza;
}
}
在简单工厂中,我们可以把 Factory 的 create 方法声明为静态方法,这样在我们调用时就不需要实例化 Factory 的对象直接用用类调用 create 方法来得到实例化的子类对象。
下面我们进行测试
public class SimpleFactoryTest {
public static void main(String[] args) {
PizzaStore pizzaStore = new PizzaStore();
Pizza pizza = pizzaStore.orderPizza("cheese");
System.out.println(pizza.name);
}
}
得到最终结果
简单工厂模式又称静态工厂模式,作为一种创建模式,简单工厂将不同子类的实例化给剥离出来,专门定义一个类负责创建其他类的实例,我们只需要知道不同子类中的一个参数,然后利用参数对基类进行调用就可以得到不同的子类,被创建的子类有着相同的父类。
模式结构
Factory:用来得到实例化子类对象的工厂
Product:抽象产品,所有对象的父类,描述所有对象共有的公共接口
ConcreteProduct:具体的产品,创新对象都是它的实例化
模式分析
优点
通过工厂模式将对象的创建和对象本身的业务处理分开,这样降低了系统的耦合度,同时关闭了修改,开放了扩展。客户端只需要知道具体产品对应的参数,无需知道类名和创建它的方法,实现了责任个分割,有专门的工厂类为他提供需要的对象实例。
缺点
使所有的操作集中在 Factory 上,但是这样使得 Factory 的职责过重,所有创建子类的逻辑分析都由 Factory 负担。在修改产品类型时必须对 Factory 进行修改,当产品类型较多时,不易于维护。
简单工厂模式应用情况
- 在客户端不需要知道得到类的全部情况,只需要知道对应参数时
- 在需要创建的子类不多,工厂中逻辑业务不会过度复杂时