工厂方法模式指定义一个创建对象的接口,让子类决定实例化哪一个类。
结构关系如下:
可以看到,客户端创建了两个接口,一个AbstractFactory,负责创建产品,一个Product,负责产品的实现。ConcreteFactory1与ConcreteFactory2实现了AbstractFactory的功能,可以分别创建ConcreteProduct1和ConcreteProduct2产品对象,两种产品对象实现了Product。
下面通过具体的案例说明工厂方法模式。
上述情景在实际开发中很常见:通过在选择框中选择相应的选项,系统会做出不同的响应。
从用户层面来说,文本域可以作为我们需要的产品,选择框可以作为工厂。
下面是具体的实现关系图。
我们先看一下工厂接口。
public interface PolicyProducer
{
public AutoInsurance getInsurObj();
}
可以看到,AutoInsurance的实现类中可以通过getInsurObjla拿到产品对象。
再看一下产品接口。
public interface AutoInsurance {
abstract String getInfo();
}
接口当中可以通过getInfo拿到产品的信息。
下面我们看一个产品。
public class BodyInjur implements AutoInsurance {
private String description;
public String getInfo() {
description = " Body Injur Liability: \n\nBodily injury coverage pays for medical bills" +
" lost wages, rehabilitation, treatment and/or" +
" funeral costs for anyone injured or killed " +
" by your car. Such coverage will also pay for" +
" pain and suffering damages when a third " +
" party successfully sues. ";
return description;
}
}
这个类实现了产品的接口,把界面文本域中的信息存储在description中,当工厂创建了这个对象,界面系统就可以通过getInfo拿到文本域中的信息。
下面看一看生产这个产品的工厂。
public class BodyPolicy implements PolicyProducer {
public AutoInsurance getInsurObj() {
return new BodyInjur();
}
}
当需要创建一个产品的时候需要创建它的工厂,在这个工厂当中,通过getInsurObj获取对应的产品对象。
如果现在需要创建一个产品,即在本案例中需要新增一种模式,该怎么做呢?
按照工厂方法模式,需要新增两个类,一个是工厂,一个是产品。
LuxeryCarlnsurance.java
public class LuxeryCarlnsurance implements AutoInsurance{
private String description;
public String getInfo() {
description = " Body Injur Luxery: \n\nBodily injury coverage pays for medical bills" +
" lost wages, rehabilitation, treatment and/or" +
" funeral costs for anyone injured or killed " +
" by your car. Such coverage will also pay for" +
" pain and suffering damages when a third " +
" party successfully sues. ";
return description;
}
}
LuxeryCarPolicy.java
public class LuxeryCarPolicy implements PolicyProducer{
public AutoInsurance getInsurObj() {
return new LuxeryCarlnsurance();
}
}
当需要这种模式的时候,你会打开选择框选择这种模式。
现在选择框里是没有这种模式的,我们就需要向选择框里添加这种模式。
public static final String LUXERY = "Luxery";
这是定义模式的描述信息,也就是我们在选择框里见到的。
对于java的swing编程,只需要在组件中加入文本信息即可,即:
cmbInsuranceType = new JComboBox();
cmbInsuranceType.addItem(BODYINJURE);
cmbInsuranceType.addItem(COLLISION);
cmbInsuranceType.addItem(PERSONINJURE);
cmbInsuranceType.addItem(PROPERTY);
cmbInsuranceType.addItem(COMPREHENSIVE);
cmbInsuranceType.addItem(LUXERY);
现在虽然可以显示了,但目前为止只是更新了GUI界面。
下面直接创建模式对象即可。
if (type.equals(LUXERY)) {
pp = new LuxeryCarPolicy();
}
由此,我们思考一个问题,这种模式与直接创建有什么区别?
如果我直接创建对象而不创建工厂需要怎么做?
那是不是需要每次创建对象后都需要执行一定的操作。
if (type.equals(BODYINJURE)) { pp=new BodyPolicy(); /** * */ } else if (type.equals(COLLISION)) { pp=new CollPolicy(); /** * */ } else if (type.equals(PERSONINJURE)) { pp= new PersonPolicy(); /** * */ } else if (type.equals(PROPERTY)) { pp = new PropPolicy(); /** * */ } else if (type.equals(COMPREHENSIVE)) { pp= new ComPolicy(); /** * */ } else if (type.equals(LUXERY)) { pp = new LuxeryCarPolicy(); /** * */ }
而工厂模式下统一进行了操作。
AutoInsurance ai = pp.getInsurObj();
String desc = ai.getInfo();
txtForInfo.setText(desc);
换句话说把对象的操作抽象成抽象类的方法。
即产品接口:
下面给出工厂模式的优缺点。
主要优点:
- 用户只需要知道具体工厂的名称就可得到想要的产品,无须知道产品的具体创建过程。
- 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
- 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。
主要缺点:
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
- 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。
百度网盘
链接:https://pan.baidu.com/s/1qTt3UV1BN16QFdtcIt_0fA?pwd=3kgh
提取码:3kgh