创建型设计模式-工厂模式和应用
工厂模式介绍:
它提供了一种创建对象的最佳方式,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
例子:
需要购买一辆车,不用管车辆如何组装,且可以购买不同类型的比如轿车、SUV、跑车,直接去4s店购买就行(4s店就是工厂)工厂生产电脑,除了A品牌、还可以生产B、C、D品牌电脑业务开发中,支付很常见,里面有统一下单和支付接口,具体的支付实现可以微信、支付宝、银行卡等
工厂模式有 3 种不同的实现方式
简单工厂模式:通过传入相关的类型来返回相应的类,这种方式比较单 一,可扩展性相对较差;工厂方法模式:通过实现类实现相应的方法来决定相应的返回结果,这种方式的可扩展性比较强;抽象工厂模式:基于上述两种模式的拓展,且支持细化产品
应用场景:
解耦:分离职责,把复杂对象的创建和使用的过程分开
复用代码 降低维护成本:
如果对象创建复杂且多处需用到,如果每处都进行编写,则很多重复代码,如果业务逻辑发生了改变,需用四处修改;使用工厂模式统一创建,则只要修改工厂类即可,降低成本
一、简单工厂模式的应用
简单工厂模式
又称静态工厂方法, 可以根据参数的不同返回不同类的实例,专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类
由于工厂方法是静态方法,可通过类名直接调用,而且只需要传入简单的参数即可
实现代码如下
public static PayFactory createPay(String payType){if (payType == null){return null;}else if(payType.equalsIgnoreCase("WECHAT_PAY")){return new WechatPay();}else if(payType.equalsIgnoreCase("ALI_PAY")){return new AliPay();}return null;}
Pay pay = SimplePayFactory.createPay("ALI_PAY");pay.unifiedorder();
优点:
将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
缺点
工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背即开闭原则(Open Close Principle)对扩展开放,对修改关闭,程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果将会增加系统中类的个数,在一定程度上增加了系统的复杂度和理解难度,不利于系统的扩展和维护,创建简单对象就不用模式
二、工厂方法模式的应用
工厂方法模式
又称工厂模式,是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则通过工厂父类定义负责创建产品的公共接口,通过子类来确定所需要创建的类型相比简单工厂而言,此种方法具有更多的可扩展性和复用性,同时也增强了代码的可读性将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化哪一个类。
代码如下
*** 抽象工厂方法*/public interface PayFactory {Pay getPay();}/*** 具体产品工厂*/public class AliPayFactory implements PayFactory {@Overridepublic Pay getPay() {return new AliPay();}}/*** 抽象产品*/public interface Pay {/*** 统一下单*/void unifiedorder();}/*** 具体产品*/public class AliPay implements Pay {@Overridepublic void unifiedorder() {System.out.println("支付宝支付 统一下单接口");}}
运行效果如下
如果需要拓展微信支付:
//创建微信支付方法对象的工厂public class WechatFactory implements PayFactory{@Overridepublic Pay getPay() {return new WechatPay();}}//微信支付的方法public class WechatPay implements Pay{@Overridepublic void unifiedorder() {System.out.println("微信支付被调用");}}
运行效果如下
缺点:
增加一个产品,需要实现对应的具体工厂类和具体产品类;每个产品需要有对应的具体工厂和具体产品类
三、抽象工厂方法模式的实践指南和应用
抽象工厂模式:基于上述两种模式的拓展,是工厂方法模式的升级版,当需要创建的产品有多个产品线时使用抽象工厂模式是比较好的选择
抽象工厂模式在 Spring 中应用得最为广泛的一种设计模式
背景
工厂方法模式引入工厂等级结构,解决了简单工厂模式中工厂类职责过重的问题但工厂方法模式中每个工厂只创建一类具体类的对象,后续发展可能会导致工厂类过多,因此将一些相关的具体类组成一个“具体类族”,由同一个工厂来统一生产,强调的是一系列相关的产品对象!!!
实现步骤
1、定义两个接口 Pay、Refund
2、创建具体的Pay产品、创建具体的Refund产品
3、创建抽象工厂 OrderFactory 接口
里面两个方法 createPay/createRefund
4、创建支付宝产品族AliOderFactory,实现OrderFactory抽象工厂
5、创建微信支付产品族WechatOderFactory,实现OrderFactory抽象工厂
6、定义一个超级工厂创造器,通过传递参数获取对应的工厂
代码如下
/*** 超级工厂,定义同个产品族的其他相关子工厂*/public interface OrderFactory {PayFactory createPay();RefundFactory createRefund();}//产品族工厂的产品,可以不叫Factory,看公司团队规范,比如类名叫 IPay 也可以的public interface PayFactory {/*** 统一下单*/void unifiedorder();}//产品族工厂public class AliOrderFactory implements OrderFactory {@Overridepublic PayFactory createPay() {return new AliPay();}@Overridepublic RefundFactory createRefund() {return new AliRefund();}}//具体产品public class AliPay implements PayFactory {@Overridepublic void unifiedorder() {System.out.println("支付宝支付 统一下单接口");}}//超级工厂生产器,传参生产对应的子工厂public class FactoryProducer {public static OrderFactory getFactory(String type) {if (type.equalsIgnoreCase("WECHAT")) {return new WechatOrderFactory();} else if (type.equalsIgnoreCase("ALI")) {return new AliOrderFactory();}return null;}}
运行效果如下
工厂方法模式和抽象工厂方法模式
当抽象工厂模式中每一个具体工厂类只创建一个产品对象,抽象工厂模式退化成工厂方法模式优点 当一个产品族中的多个对象被设计成一起工作时,它能保证使用方始终只使用同一个产品族中的对象产品等级结构扩展容易,如果需要增加多一个产品等级,只需要增加新的工厂类和产品类即可, 比如增加银行支付、退款
缺点
产品族扩展困难,要增加一个系列的某一产品,既要在抽象的工厂和抽象产品里修改代码,不是很符合开闭原则
增加了系统的抽象性和理解难度