文章目录
- 五、工厂方法
- 六、抽象工厂
五、工厂方法
工厂方法,使用工厂可以像使用人员屏蔽对象创建的细节,使用者无需指定具体的类即可使用功能,达到信息隐蔽的作用,便于后期的维护,修改和扩展。
在看工厂方法前还有一类是 简单工厂,相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护。
比如我们在聚合支付的时候有,微信支付和支付宝支付,在不同的选择要获取不同的对象,如果用简单方法来实现的话:
- 先定义统一的支付抽象类,定义支付和取消支付抽象方法
public interface PayInterFace {
//支付
void pay();
//取消支付
void cancelPay();
}
- 定义微信支付类
public class WxPay implements PayInterFace {
@Override
public void pay() {
System.out.println("微信支付中...");
}
@Override
public void cancelPay() {
System.out.println("微信取消支付!");
}
}
- 定义支付宝类
public class ZfbPay implements PayInterFace {
@Override
public void pay() {
System.out.println("支付宝支付中...");
}
@Override
public void cancelPay() {
System.out.println("支付宝取消支付!");
}
}
- 创建简单工厂
public class SimplePayFactory {
public static PayInterFace getPay(String payType) {
if (Objects.equals(payType, "wx")) {
return new WxPay();
} else if (Objects.equals(payType, "zfb")) {
return new ZfbPay();
} else {
return null;
}
}
}
- 使用
public class demo {
public static void main(String[] args) {
PayInterFace pay = SimplePayFactory.getPay("wx");
pay.pay();
pay.cancelPay();
PayInterFace pay1 = SimplePayFactory.getPay("zfb");
pay1.pay();
pay1.cancelPay();
}
}
通过传入不同的标识获取不同的对象,且无需指定具体对象,让使用者无需关注创建对象的细节,增加对象需要在工厂中添加对应的实例化程序,当类型过多时不利于系统的扩展维护。
那下面来看下工厂方法的做法:
- 在上面的基础上,再建立 支付工厂接口:
public interface PayFactory {
PayInterFace getPay();
}
- 建立微信支付工厂
public class WxPayFactory implements PayFactory {
@Override
public PayInterFace getPay() {
return new WxPay();
}
}
- 建立支付宝工厂
public class ZfbPayFactory implements PayFactory {
@Override
public PayInterFace getPay() {
return new ZfbPay();
}
}
- 使用
public class demo {
public static void main(String[] args) {
PayInterFace pay = new WxPayFactory().getPay();
pay.pay();
pay.cancelPay();
PayInterFace pay1 = new ZfbPayFactory().getPay();
pay1.pay();
pay1.cancelPay();
}
}
这种方式同样屏蔽了对象建立的细节,且无需指定具体对象,但相对于上面的简单工厂,更易于做扩展,比如要引入新的支付,只需要创建新的工厂并实现PayFactory
即可,更利于系统的扩展。
六、抽象工厂
上面学习了简单工厂和工厂方法,下面来看下抽象工厂。
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
在上面的场景中,加入支付后需要扣除库存,就需要引入库存工厂,并调用扣除库存的方法,库存工厂和支付工厂貌似不相干,但在抽象工厂中,抽象工厂相当于一个公司,库存和支付相当与部门,相对于公司来看,支付和库存都是公司下的部门,是一个整体。所以抽象工厂就是定义一个产品组,可以完成一系列的过程,而不是单一的活动。
下面使用抽象工厂定义支付后扣除库存的设计:
- 定义库存操作接口
public interface RepertoryInterFace {
void deductRepertory();
}
- 以苹果为例,定义具体库存为苹果的库存
public class AppleRepertory implements RepertoryInterFace {
@Override
public void deductRepertory() {
System.out.println("苹果库存 扣除库存...");
}
}
- 定义抽象工厂,定义支付和扣库存抽象方法
public interface BuyAbstractFactory {
//支付
PayInterFace pay();
//扣库存
RepertoryInterFace deductRepertory();
}
- 定义抽象工厂实现,这里演示效果,直接采用微信支付对象
public class BuyAbstractFactoryImpl implements BuyAbstractFactory {
@Override
public PayInterFace pay() {
return new WxPay();
}
@Override
public RepertoryInterFace deductRepertory() {
return new AppleRepertory();
}
}
- 使用
public class demo {
public static void main(String[] args) {
BuyAbstractFactory factory = new BuyAbstractFactoryImpl();
factory.pay().pay();
factory.deductRepertory().deductRepertory();
}
}
使用抽象工厂方式,颗粒化程度大,让使用者无需知道整个工作组的对象,即可完成一连串的操作,对可扩展性,可修改修都很友好。