共计 2457 个字符,预计需要花费 7 分钟才能阅读完成。
前言
后面的文章中提到一个设计准则——针对接口编程,不针对实现编程,那必定有人会问,实例化对象的时候不就是在针对实现编程了么?的确如此,实例化这个流动常常造成“耦合”问题,因而实例化流动不应该总是公开地进行。那么怎么能力更加的松耦合的进行开发呢?那么就是本篇文章的主题——工厂模式。
简略工厂模式
假如你要制作一个披萨点餐零碎,那么你的代码可能是这么写的。
function orderPizza () {let pizza = new Pizza();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
然而当你须要更多的披萨类型,须要减少肯定的代码来判断制作哪种披萨,于是减少了一段判断的代码。
function orderPizza (type) {
let pizza;
if (type === 'a') {pizza = new aPizza();
} else if(type === 'b') {pizza = new bPizza();
) else {pizza = new cPizza();
}
...
}
然而实际上披萨类型并没有那么少,并且随着工夫的扭转,品种也可能删除,所以依据之前提到的设计准则——类应该对扩大凋谢,对设计敞开,因而咱们须要对那些会扭转和不会扭转的局部进行封装。
class PizzaStore {
factory = null;
constructor (factory) {this.factory = factory;}
orderPizza (type) {let pizza = this.factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
class SimplePizzaFactory {createPizza (type) {
let pizza;
if (type === 'a') {pizza = new aPizza();
} else if(type === 'b') {pizza = new bPizza();
) else {pizza = new cPizza();
}
return pizza;
}
}
通过将创立披萨逻辑抽离进来,失去了一个专门用来生产对象的办法,咱们将其称之为工厂。有了工厂当前,orderPizza 就不关怀具体的生产对象的过程,只须要你返回一个披萨给我。这样做还有什么益处呢?首先是这个工厂办法是能够复用的,不光是能够用在 orderPizza 这个办法里,只有是须要生产对象的中央都能够应用这个工厂,而批改的时候也只须要批改工厂。
上述的办法其实叫做 简略工厂 ,其实简略工厂不是一个设计模式,而更像一种编程习惯,然而这种办法经常被应用,因此有些开发人员的确会误会为 工厂模式。然而不得不说,尽管不属于模式的一种,然而够用就行,开发的时候不须要时时刻刻都套用各种设计模式在其中,咱们其实只须要某种程度的“完满”就够了。
那么怎么样才是真正的 工厂模式 呢?
工厂模式
工厂办法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂办法让类把实例化推延到子类。
假如当初披萨开设不同地区的分店,因而风味将会有各种各样的差别。那么如果应用下面的简略工厂模式,会是怎么样呢?首先写出三种不同的工厂来继承 SimplePizzaFactory,重写 createPizza 办法,别离是 aFactory,bFactory,cFactory。
aStore = new PizzaStore(new aFactory());
aStore.orderPizza('a');
bStore = new PizzaStore(new bFactory());
bStore.orderPizza('b');
这种写法看起来没什么问题,然而你可能会发现有人会不应用你设定的 PizzaStore,开始应用借鉴的流程,导致标准失落。因而咱们须要须要建设一个更好的框架,使其具备更好的弹性,那么这里就要用到这次讲的模式——工厂模式来实现。
那么要做的事件就是要把 createPizza 办法放到 PizzaStore 外面,不过要把它设置成“形象办法”,而后为不同的分店建设子类。上面先看 pizzaStore 的扭转。
class PizzaStore {orderPizza(type){
let pizza;
pizza = this.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
creatPizza () {} // 形象办法
}
当初让 PizzaStore 的各个子类去负责定义本人的 createPizza 办法,这样就可能实现领有灵便的实现形式,同时又是建设在咱们设定的框架之下。先来实现一个分店的代码。
class aPizzaStore extends PizzaStore {creatPizza (type) {
let pizza;
if (type === 'a') {pizza = new aPizza();
} else if(type === 'b') {pizza = new bPizza();
) else {pizza = new cPizza();
}
return pizza;
}
}
能够看到 orderPizza 中的 pizza 在执行各种办法的时候,是不晓得哪只具体类参加了进来,换句话说,这就是“解耦”。
总结
工厂办法模式可能封装具体类型的实例化,pizzaStore 中提供的 createPizza 创建对象的办法也叫做“工厂办法”。在 pizzaStore 类中可能还会有其余办法会用到这个办法,然而只有子类才真正的实现了这个办法并实例化对象。
看到这里应该还是会有人困惑简略工厂和工厂模式之间的差别,尽管它们的确很像,然而简略工厂是把全副事件都放在一个中央解决完了的办法。然而工厂模式却是先建设起来一个框架,让子类来决定实现。然而简略工厂不具备工厂办法的弹性,因为简略工厂不能变更正在创立的产品。