故事(一):
美女喜欢网购,国内国外的都喜欢,付钱的时候就会涉及国内支付和国外的支付。
类图:
抽象工厂类AbstractFactoryPay。里面有三个方法,一个是licese(),来中国开通支付功能肯定要有相关部门的执照。另外两个是抽象方法分别返回抽象的产品(接口或者抽象类)ChinesePay和OverseaPay。抽象产品有多个具体实现,阿里支付(ALIPay),京东支付(JingDongPay),以及苹果支付(AppayPay)
思考:
抽象工厂里面生产的产品书上称为产品族,我理解是一系列不同的产品。如果现在要增加一个抖音支付,或者是微软支付,只需要分别实现ChinesePay和OverseaPay即可,还是符合开闭原则的思想。但是现在忽然发现了外星人,他们也喜欢网购,这时候就需要来一个AlienPay,这时候就改动很大了。就需要修改顶层抽象工厂,增加一个产品族,以及具体的工厂,还要添加新的抽象产品以及实现。
伪代码:
public class PayTest {
public static void main(String[] args) {
PayFactory payFactory = new PayFactory();
ChinesePay ali = payFactory.chinesePay("ALI"); //通过if条件判断,创建不同的支付方式(产品)
ali.spend();
ChinesePay jingDong = payFactory.chinesePay("JING_DONG");
jingDong.spend();
OverseaPay overseaPay = payFactory.overseaPay(ApplePay.class);//通过反射,创建不同的支付方式(产品)
overseaPay.spend();
}
}
抽象工厂确实有些复杂,因此需要再来一个故事。
故事(二):
帅哥买了新房子,需要购买一些家电产品。现在物联网很流行啊,自家都有自己的生态圈。小米(冰箱,洗衣机,电视机)、格力、
海尔。
类图:
假设有一个电器抽象工厂(AbstractFactory),里面有电视机(TV)、冰箱(Fridge)、洗衣机(Washing)。这些都是不同的产品,理解为产品族的概念。小米工厂分别生产这些产品,格力也是一样的。当然小米电视还可以继续细分,小米2电视,小米3电视。
思考:
董小姐忽然心血来潮,想要再参与到手机市场。想要造格力手机,这就是需要增加一个产品族,这样整个生产线都要改动了。即需要在AbstraactFactory方法里面增加一个createPhone()。这样改动的东西就很多了,董小姐应该要花很多钱吧。
伪代码:
public class BandTest {
public static void main(String[] args) {
XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
Fridge fridge = xiaoMiFactory.createFridge();
TV tv = xiaoMiFactory.createTV();
Washing washing = xiaoMiFactory.createWashing();
GeLiFactory geLiFactory = new GeLiFactory();
Fridge fridgeGeLi = geLiFactory.createFridge();
TV tvGeLi = geLiFactory.createTV();
Washing washingGeLi = geLiFactory.createWashing();
}
}
总结:
工厂里面创建的产品称为产品族,我理解为不同的产品。增加一个产品族,对抽象工厂模式来说改动非常大,违背了开闭原则的思想。
所以在运用抽象工厂模式的时候,要认识到你的产品族不应该经常会有变动,至少几年内都不会改变。第一个例子将来有外星人来购物,当时是无法预测的;董小姐要造手机,这在5年前也是无法预测的。
优点:无需关心具体产品的创建,将一系列产品族在一个工厂里面创建
缺点:增加了系统的抽象性和理解难度。如果后期增加产品族,改动很大,违背开闭原则。
一个具有注脚的文本。1
第一个例子境外支付和国内支付,说成是不同的产品族可能有些牵强,但是知识最重要。哈哈哈。。。 ↩︎