软件设计之工厂方法模式

工厂方法模式指定义一个创建对象的接口,让子类决定实例化哪一个类。

结构关系如下:

软件设计之工厂方法模式_第1张图片

可以看到,客户端创建了两个接口,一个AbstractFactory,负责创建产品,一个Product,负责产品的实现。ConcreteFactory1与ConcreteFactory2实现了AbstractFactory的功能,可以分别创建ConcreteProduct1和ConcreteProduct2产品对象,两种产品对象实现了Product。

下面通过具体的案例说明工厂方法模式。

软件设计之工厂方法模式_第2张图片

上述情景在实际开发中很常见:通过在选择框中选择相应的选项,系统会做出不同的响应。

软件设计之工厂方法模式_第3张图片

从用户层面来说,文本域可以作为我们需要的产品,选择框可以作为工厂。

下面是具体的实现关系图。

软件设计之工厂方法模式_第4张图片

我们先看一下工厂接口。

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();
    }
}

当需要这种模式的时候,你会打开选择框选择这种模式。

软件设计之工厂方法模式_第5张图片

现在选择框里是没有这种模式的,我们就需要向选择框里添加这种模式。

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);

软件设计之工厂方法模式_第6张图片

现在虽然可以显示了,但目前为止只是更新了GUI界面。

下面直接创建模式对象即可。

if (type.equals(LUXERY)) {
     pp = new LuxeryCarPolicy();
}

软件设计之工厂方法模式_第7张图片

由此,我们思考一个问题,这种模式与直接创建有什么区别?

如果我直接创建对象而不创建工厂需要怎么做?

那是不是需要每次创建对象后都需要执行一定的操作。

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);

 换句话说把对象的操作抽象成抽象类的方法。

即产品接口:

软件设计之工厂方法模式_第8张图片

下面给出工厂模式的优缺点。 

主要优点:

  • 用户只需要知道具体工厂的名称就可得到想要的产品,无须知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

主要缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。

 

百度网盘 

链接:https://pan.baidu.com/s/1qTt3UV1BN16QFdtcIt_0fA?pwd=3kgh 
提取码:3kgh

你可能感兴趣的:(开发工具,工厂方法模式)