原创

设计模式详解(三)--------抽象工厂

我在上一篇文章中实现了一种工厂模式,但那只是“简单工厂模式”,并不能满足我们的需求。最重要的是,如果我们需要新添加一种计费方式,就需要去修改工厂类,这违反了开闭原则。所以我们在实际工作中就引入了另一种工厂设计理念:抽象工厂

一、抽象工厂

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

抽象工厂与简单工厂的的最大不同在于,一个抽象工厂可以生产一系列的产品。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

二、实现

1.在上一篇文章的基础上新增FeeTypeInterface.java

/**
 * @描述
 * @Author Baldwin
 * @E-Mail DikeyWang@163.com || baldwin@chancellorhk.com
 * @Time 2020/3/16 14:39
 * @Other
 */
public interface FeeTypeInterface {
    String getType();
}

2.工厂实现类

/**
 * \* User: Baldwin
 * \* E_Mail: baldwin@chancellorhk.com || DikeyWang@163.com
 * \* Date: 2020/3/16
 * \* Time: 14:46
 * \* Description:
 * \
 */
public class TypeFactory extends AbstractFactory {

    @Override
    public FeeInterface getFee(String feeName) {
        return null;
    }

    @Override
    public FeeTypeInterface getFeeType(String type) {
        FeeTypeInterface feeTypeInterface;

        if (null == type) return null;

        if ("SMS".equalsIgnoreCase(type)){
            feeTypeInterface = new TypeSms();
        }else if("MO".equalsIgnoreCase(type)){
            feeTypeInterface = new TypeMo();
        }else {
            feeTypeInterface = null;
        }
        return feeTypeInterface;
    }
}

 修改原有的FeeFactory类,继承AbstractFactory抽象类

/**
 * \* User: Baldwin
 * \* E_Mail: baldwin@chancellorhk.com || DikeyWang@163.com
 * \* Date: 2020/3/16
 * \* Time: 12:02
 * \* Description:
 * \
 */
public class FeeFactory extends AbstractFactory {

    @Override
    public FeeTypeInterface getFeeType(String type) {
        return null;
    }

    public FeeInterface getFee(String feeName){
        if (feeName == null) return null;
        FeeInterface feeInterface;
        if ("gzfee".equals(feeName)) {
            feeInterface = new GzFee();
        } else if ("MelonFee".equals(feeName)) {
            feeInterface = new MelonFee();
        } else if ("BeiJing".equals(feeName)) {
            feeInterface = new BeiJingFee();
        }else {
            feeInterface = null;
        }
        return feeInterface;
    }
}

3.新增产品

/**
 * \* User: Baldwin
 * \* E_Mail: baldwin@chancellorhk.com || DikeyWang@163.com
 * \* Date: 2020/3/16
 * \* Time: 14:41
 * \* Description:
 * \
 */
public class TypeMo implements FeeTypeInterface {
    public String getType() {
        return "MO";
    }
}
/**
 * \* User: Baldwin
 * \* E_Mail: baldwin@chancellorhk.com || DikeyWang@163.com
 * \* Date: 2020/3/16
 * \* Time: 14:40
 * \* Description:
 * \
 */
public class TypeSms implements FeeTypeInterface {
    public String getType() {
        return "SMS";
    }
}

4.工厂创造器/生成器类FactoryProducer

/**
 * \* User: Baldwin
 * \* E_Mail: baldwin@chancellorhk.com || DikeyWang@163.com
 * \* Date: 2020/3/16
 * \* Time: 14:52
 * \* Description:获取对应工厂
 * \
 */
public class FactoryProducer {
    public static AbstractFactory getFactory(String factoryType){
        AbstractFactory factory;
        if ("feeFactory".equalsIgnoreCase(factoryType)){
            factory = new FeeFactory();
        }else if ("typeFactory".equalsIgnoreCase(factoryType)){
            factory = new TypeFactory();
        }else {
            factory = null;
        }
        return factory;
    }
}

5.主要的AbstractFactory

/**
 * \* User: Baldwin
 * \* E_Mail: baldwin@chancellorhk.com || DikeyWang@163.com
 * \* Date: 2020/3/16
 * \* Time: 14:43
 * \* Description:
 * \
 */
public abstract class AbstractFactory {
    public abstract FeeInterface getFee(String feeName);
    public abstract FeeTypeInterface getFeeType(String type);
}

6.测试Demo

/**
 * \* User: Baldwin
 * \* E_Mail: baldwin@chancellorhk.com || DikeyWang@163.com
 * \* Date: 2020/3/16
 * \* Time: 14:56
 * \* Description:
 * \
 */
public class Demo {

    public static void main(String[] args) {

        //获取typeFactory
        AbstractFactory typeFactory = FactoryProducer.getFactory("typeFactory");
        //通过typeFactory获取typeSMS
        FeeTypeInterface typeSms = typeFactory.getFeeType("SMS");

        System.out.println(typeSms.getType());
    }

}

7.运行结果

"C:\Program Files\Java\jdk1.8.0_211\bin\java.exe" "-javaagent:D:\tools\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=57884:D:\tools\IntelliJ IDEA 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_211\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\rt.jar;E:\WorkSpaces\IDEAworkspace\DesignPattern\target\classes" cn.yzstu.abstractfactory.Demo
SMS

Process finished with exit code 0

三、总结

这篇文章写的不好,仅做个人学习使用

写完之后我自己虽然明白了,但是可能看这篇文章的人会觉得这篇文章写得很差很乱。

如果有错误的地方,欢迎指出

正文到此结束