设计模式之简单工厂模式–利用工厂解耦实例化对象
简单工厂模式
是最常被提起的一个设计模式,他的意思是
利用简单工厂来决定实例化哪个类,而不是由外部程序来决定,把创建对象的操作内聚,解耦到工厂类中。
为什么要使用简单工厂模式
工厂模式除了简单工厂模式
还有工厂方法模式
,抽象工厂模式
。
简单工厂模式有什么好处呢?
简单,非常简单。并且拥有工厂模式的特性,解耦对象的生成。
如果不使用工厂模式,那么对象的创建散落在程序的各个地方,如果需要修改,那么很麻烦。
我们在设计类的时候,为了遵循单一职责原则
,我们应该把类划分的尽可能单一,拿一个实际应用例子来说,支付场景。
支付场景
我们需要在小程序端使用小程序支付,公众号端使用h5支付,pc端使用扫码支付。
后端统一提供支付接口。代码类似下面这样。
function wechatPay() {
//...省略
if (小程序) {
//小程序支付
} else if (公众号) {
//公众号支付
} else if (pc) {
//扫码支付
}
}
上面的是一个伪代码,这样写不管扩展性,维护性都不好,更不符合单一职责,所以我们应该把支付逻辑抽出来。
interface pay{
function pay();
}
class miniWechatPay implements pay{
function pay() {
//调用小程序支付
}
}
class jsAPIPay implements pay{
function pay() {
//调用公众号,jsapi支付
}
}
class nativePay implements pay{
function pay() {
//调用扫码支付
}
}
//微信支付方法 省略了类
function wechatPay() {
//...省略
if (小程序) {
//小程序支付
$pay = new miniWechatPay;
$pay->pay();
} else if (公众号) {
//公众号支付
$pay = new jsAPIPay;
$pay->pay();
} else if (pc) {
//扫码支付
$pay = new nativePay;
$pay->pay();
}
}
在if判断里面有重复的地方,都是调用pay
方法,我们可以抽出来。
//微信支付方法 省略了类
function wechatPay() {
//...省略
if (小程序) {
//小程序支付
$pay = new miniWechatPay;
} else if (公众号) {
//公众号支付
$pay = new jsAPIPay;
} else if (pc) {
//扫码支付
$pay = new nativePay;
}
$pay->pay();
}
如果接下来我们还要增加刷脸支付等等其他支付怎么办呢,我们只能修改这个方法,这显然是不对的,违反了开闭原则
。
增加支付其实和这个业务逻辑不是一个紧耦合的,我们应该增加他的复用性,如果我们要在其他地方支付呢。应该把实例化这部分也抽出来。就形成了简单工厂类
。
//简单工厂类
class factory{
function static createPay() {
if (小程序) {
//小程序支付
$pay = new miniWechatPay;
} else if (公众号) {
//公众号支付
$pay = new jsAPIPay;
} else if (pc) {
//扫码支付
$pay = new nativePay;
}
return $pay;
}
}
//微信支付方法 省略了类
function wechatPay() {
//...省略
$pay = factory::createPay();
$pay->pay();
}
这样拆分有什么好处呢?
虽然增加支付的时候依旧需要修改代码,但是只需要修改简单工厂类,而不用修改业务逻辑类,避免了因为修改业务逻辑类而产生的业务逻辑bug。使得实例化对象和具体业务无关。
增加了代码的复用性,维护性,灵活性,测试性等。
代码放在了我的github上面。