菜鸟的架构学习之路-24种设计模式之工厂方法和抽象工厂模式

思考

目前有一个支付业务场景的需求,包含跨境支付,支付宝、微信、银联支付三种支付方式,我们应该如何设计?

引用于咕泡学院《设计模式总览及工厂模式详解》课后作业

实现

菜鸟的架构学习之路-24种设计模式之工厂方法和抽象工厂模式_第1张图片
demo地址
在未使用工厂设计模式时,我们创建对象以及发送数据包的逻辑都放在了Test.doPay()里面。

    private static void doPay(String payName) throws IllegalAccessException {
        if("微信".equals(payName)){
            IPay pay = new WxPay();
            pay.send(objToMap(pay));
        }else if("支付宝".equals(payName)){
            IPay pay = new AliPay();
            pay.send(objToMap(pay));
        }else if("银联".equals(payName)){
            IPay pay = new YinLianPay();
            pay.send(objToMap(pay));
        }else if("跨境".equals(payName)) {
            IPay pay = new PayPal();
            pay.send(objToMap(pay));
        }else {
            System.out.println("未找到支付方式");
        }
    }

这样,如果对象创建比较麻烦得话,则使用者的开发效率会降低,于是有了以下的重构。

了解工厂方法模式、抽象工厂模式

工厂方法:
uml图:
菜鸟的架构学习之路-24种设计模式之工厂方法和抽象工厂模式_第2张图片
理解:
通过为每一个支付类创建对应的工厂,从而避免应用开发者将过多的时间浪费在对象创建上。

代码:

    public static void main(String[] args) throws IllegalAccessException {
        IPayFactory payFactory= new AliPayImpl();
        IPay iPay = payFactory.create();
        iPay.send(IPayFactory.objToMap(iPay));

        IPayFactory payFactory1= new WXPayImpl();
        IPay iPay1 = payFactory1.create();
        iPay1.send(IPayFactory.objToMap(iPay1));


        IPayFactory payFactory2= new YinLianPayImpl();
        IPay iPay2 = payFactory2.create();
        iPay2.send(IPayFactory.objToMap(iPay2));

        IPayFactory payFactory3= new PayPalImpl();
        IPay iPay3 = payFactory3.create();
        iPay.send(IPayFactory.objToMap(iPay3));
    }

想要得到某个对象时只需要初始化对应的工厂即可。
[demo地址](https://github.com/GaoHaiShan/mySimpTomcat/tree/master/factory-test/src/main/java/factorymethod)

如果为每一个类都去初始化一个工厂的话,这样实体类较少,采用工厂方法和方便,假如业务场景较多时,会出现代码臃肿的情况,因此出现了抽象工厂模式:
uml图:
菜鸟的架构学习之路-24种设计模式之工厂方法和抽象工厂模式_第3张图片
理解:
抽象工厂模式,是一个工厂初始化一系列的对象,比如这个例子跨境支付和境内支付是两个不同的工厂实现了,他们两个都具有创建支付实体类和创建转账实体类,不同的是跨境只能创建跨境的支付类的对象和跨境的转账类对象,境内只能创建境内的支付类的对象和境内的转账类对象,就好比海尔公司和格力公司,他们都能创造冰箱和彩电,但是格力公司创造不出海尔冰箱,海尔公司也创造不出格力冰箱。
海尔公司和格力公司就是一个个的产品族,而他们两个创造出来的冰箱总和就是一系列产品。
demo地址

关于工厂类一定需要将构造方法私有化吗

个人认为需要将工厂类的构造方法私有化,因为由这个工厂类实例出来的对象,功能是相同的,创建出多个这个工厂的对象,没有太大的意义,反而会增加堆内存占用空间,所以将工厂类设置成单例模式比较妥当。

你可能感兴趣的:(设计模式)