我在上一篇文章中实现了一种工厂模式,但那只是“简单工厂模式”,并不能满足我们的需求。最重要的是,如果我们需要新添加一种计费方式,就需要去修改工厂类,这违反了开闭原则。所以我们在实际工作中就引入了另一种工厂设计理念:抽象工厂
一、抽象工厂
抽象工厂模式(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
三、总结
这篇文章写的不好,仅做个人学习使用
写完之后我自己虽然明白了,但是可能看这篇文章的人会觉得这篇文章写得很差很乱。
如果有错误的地方,欢迎指出