文章目录
- 五、工厂方法
- 六、抽象工厂
五、工厂方法
工厂方法,使用工厂可以像使用人员屏蔽对象创建的细节,使用者无需指定具体的类即可使用功能,达到信息隐蔽的作用,便于后期的维护,修改和扩展。
在看工厂方法前还有一类是 简单工厂,相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护。
比如我们在聚合支付的时候有,微信支付和支付宝支付,在不同的选择要获取不同的对象,如果用简单方法来实现的话:
- 先定义统一的支付抽象类,定义支付和取消支付抽象方法
public interface PayInterFace {//支付void pay();//取消支付void cancelPay();
}
- 定义微信支付类
public class WxPay implements PayInterFace {@Overridepublic void pay() {System.out.println("微信支付中...");}@Overridepublic void cancelPay() {System.out.println("微信取消支付!");}
}
- 定义支付宝类
public class ZfbPay implements PayInterFace {@Overridepublic void pay() {System.out.println("支付宝支付中...");}@Overridepublic 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 {@Overridepublic PayInterFace getPay() {return new WxPay();}
}
- 建立支付宝工厂
public class ZfbPayFactory implements PayFactory {@Overridepublic 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 {@Overridepublic void deductRepertory() {System.out.println("苹果库存 扣除库存...");}
}
- 定义抽象工厂,定义支付和扣库存抽象方法
public interface BuyAbstractFactory {//支付PayInterFace pay();//扣库存RepertoryInterFace deductRepertory();
}
- 定义抽象工厂实现,这里演示效果,直接采用微信支付对象
public class BuyAbstractFactoryImpl implements BuyAbstractFactory {@Overridepublic PayInterFace pay() {return new WxPay();}@Overridepublic RepertoryInterFace deductRepertory() {return new AppleRepertory();}
}
- 使用
public class demo {public static void main(String[] args) {BuyAbstractFactory factory = new BuyAbstractFactoryImpl();factory.pay().pay();factory.deductRepertory().deductRepertory();}
}
使用抽象工厂方式,颗粒化程度大,让使用者无需知道整个工作组的对象,即可完成一连串的操作,对可扩展性,可修改修都很友好。