工厂模式应该是我们比较常用的设计模式之一。暴露创建逻辑,调用者只需要根据自己的需要获取需要的对象,即可“开箱即用”。换句话说,我要什么,你就得给什么。我们用生活中常用的支付来说明工厂模式的实现逻辑。我们在用手机支付的时候,总是会选择支付方式,比如微信支付、支付宝支付,当然还有其他方式比如微付收费支付、连连支付等等。当用户选择某种支付方式时,需要相应地生成支付对象,并执行该支付方式。在这里,我们将付款对象的生成留给工厂。首先为支付定义一个抽象类:抽象产品类的作用是规范支付对象,指定支付对象可以进行的操作,即下单。然后我们可以指定我们的支付对象。这里以微信支付和支付宝支付为例:微信支付产品类别支付宝支付产品类别有了具体的支付产品类别,我们就可以创建工厂进行生产,微信支付支付宝支付的支付对象创建:工厂类很简单,根据支付类型返回支付对象。接下来做一个模拟用户支付的小测试,假设用户选择的是微信支付:测试方法可以看到最终执行了微信下单方法。OK,大功告成,可以下班了!但这真的是我们想要的工厂模式吗?如果我们需要添加另一种支付方式,比如连续支付,如何解决?简单,加一个持续付费的产品类,工厂给类加一个if判断,返回持续付费的对象,不就可以了吗?这是可以实现的。但是如果我们在扩展的时候不小心留下了工厂类的bug,可能会导致整个工厂类不可用,进而导致整个支付系统不可用,这显然是不合理的。事实上,这样的工厂模式违背了一个很重要的设计原则——开闭原则。开闭原则就是当你在扩展程序的时候,不改变原来的代码,达到热插拔的效果。这种工厂模式其实叫做简单工厂模式。这是一个杂乱无章的小作坊,但我们需要的是一个井然有序、收放自如的现代化工厂。因此,这里又扩展了另一种工厂模式——工厂方法模式。既然在原来的工厂类上扩展不合理,那就干脆把工厂类分开,一个支付一个工厂类,每个工厂类产生自己的支付对象。当需要扩展时,只需要创建自己的工厂即可。类和支付产品类,不管其他支付方式,这样就达到了热插拔的效果。所以我们的代码可以进化为保留原来的支付抽象类和支付产品类,去掉工厂类,新建一个抽象工厂类。微信支付和支付宝支付实现了各自的工厂类。抽象工厂类、支付宝支付工厂类、微信支付工厂类实现了工厂类的分离。微信支付工厂类负责微信支付产品的生产,支付宝支付工厂类负责支付宝支付产品的生产。所有工厂类各司其职。不要互相干扰。测试一下:这样就实现了工厂方法模式。这其实是我们平时使用最多的模式。工厂模式通常指的是工厂方法模式。当然,工厂模式还有抽象工厂方法模式,是比小作坊、小工厂更高级的超级工厂模式。
