设计模式之抽象工厂方法和抽象工厂模式

一简单化工厂:

    之前学习的时候做过一个简单化工厂的例子,拿计算器的问题举的例子,这里直接上连接,点击打开链接。为了后续的东西根据清楚我还是在简单的写一遍:

 抽象运算类以及具体实现类如下:

public class Operate{

    public static double numberA;
    public  static double numberB;
  public double getResult(){
 double result=0d;

return result;
}
  public class Add  extends Operate{
  public double getResult(){
double result=numberA+numberB;
return result;
}
  }
  public class Sub  extends Operate{
  public double getResult(){
double result=numberA-numberB;
return result;
}
  }
  public class mul  extends Operate{
  public double getResult(){
double  result=numberA*numberB;
return result;
}
  }
  public class div  extends Operate{
  public double getResult(){
double  result=numberA/numberB;
return result;
}
  }

}


这里面我使用的是内部类的表现形式,所以我放在一个文件。

再创建一个工厂类,代码如下:

public class FactoryCreateOperate{
  public  Operate createOperate(String type){
  Operate o=new Operate();
 switch(type){
   case "+":
   o=new Operate().new Add();//因为我是直接把这些加减乘除写在Operate 内部类里面 ,所以要这样 实例化
    break;
   case "-":
   o=new Operate().new Sub();
    break;
   case "*":
   o=new Operate().new Mul();
    break;
   case "/":
   o=new Operate().new Div();
    break;   
 }
  return o;
  }

}

客户端的调用代码:

Operate o=new FactoryCreateOperate().createOperate(type);
double  result= o.getResult();

 System.out.println( result);

到这里基本上就结束了。这里存在一个不足之处,也是和接下来说的抽象工厂方法最大的区别。

二抽象工厂方法:

   看完了简单化工厂模式,发现上面的工厂类(FactoryCreateOperate)好像是一个具体的类,这样我要新加一个算法,岂不是需要改工厂类,这样违背了封闭原则,换一种思想考虑一下,我们可以使用细节依赖抽象,我们既然可以抽象运算的类,也可以抽象化工厂类。说干就干!! 首先抽象工厂如下:

public  abstract class FactoryCreateOperate{
public abstract Operate createOperate();

}

然后是实例化创建运算算法的类 :

加法运算如下:

public   class FactoryCreateAdd extends FactoryCreateOperate{
public Operate createOperate() {
return new Operate().new Add();
}
}

减法运算如下:

public   class FactoryCreateSub extends FactoryCreateOperate{

public Operate createOperate() {
return new Operate().new Sub();
}
}

客户端调用如下 

FactoryCreateOperate  f= null;
String type= "+";
switch(type){
  case "+":
  f=new FactoryCreateAdd();
   break;
  case "-":
  f=new FactoryCreateSub();
   break;
}
Operate  o= f.createOperate();

o.getResult();

这样抽象化工厂方法的好处,如果我们需要实例化其他的算法类,只需要添加一个工厂子类去实例化算法类,并且继承抽象工厂抽象类。就像之前学习的计算器,加减乘除四个子类继承父抽象类Operate一样。无需改业务层的代码,只需要添加就行。

比如我想加一个乘法,只需要添加一个创建乘法的工厂子类,继承抽象工厂类就行,如:

public   class FactoryCreateMul extends FactoryCreateOperate{


public Operate createOperate() {
return new Operate().new Mul();
}

}

我们只需要创建一个子类FactoryCreateMul 继承FactoryCreateOperate类,就完成了乘法类的实例化。

学习完了 抽象工厂方法和简单化工厂,对比客户端和业务层,我发现这两个模式最大的区别就是,简单化工厂如果要加一个算法需要去改工厂类,也就是修改业务层的代码,抽象工厂方法模式只需要添加一个类就行,把简单化工厂模式内部判断逻辑移到客户端来实现。

换句话说,简单化工厂解除了客户端和业务模块的依赖,但是违背了封闭原则,二抽象化工厂方法解决了这个问题,把工厂类抽象出一个抽象类,解决了这个问题,但是发现客户端又存在判断分支的问题,也就是使用哪个算法的问题。所以这也是他们最大的区别。

工厂方法模式就是简单化工厂的进一步抽象和推广,保存了简单化工厂的优点,克服了简单化工厂的缺点,就是添加一个逻辑,就得新增一个类,增加了代码的开发量。


                                                       图一

三抽象化工厂模式

  学习完了抽象工厂方法模式,我紧接着学习了抽象工厂模式,发现在一般的业务层面,一个业务不可能只创建一种产品,就像刚刚学习的抽象工厂方法中,创建计算器的例子,一个createOperate代表创建一个计算器,工厂方法模式中一个工厂类FactoryCreateOperate只有一个创建计算器(Operate的方法,public abstract Operate createOperate();,如果我们需要创建多个不同的计算器,怎么办?

我对抽象工厂类进行了修改:


public  abstract class FactoryCreateOperate{
public abstract Operate createOperate();//创建计算1
public abstract Operate createOperate1();创建计算2。新增加的创建Operate1类,以前没有
}

计算1和计算2 代表两个不同的产品。也就是两个不同的任务,抽象类改变了,子类工厂类也需要改变

public   class FactoryCreateAdd extends FactoryCreateOperate{

public Operate createOperate() {
return new Operate().new Add();
}

public Operate createOperate1() {//新增加的实例化计算器1中加法的类,以前没有
return  Operate1().new Add();;
}

}

FactoryCreateAdd  创建了两个类,一个类是Operate ,一个类是Operate1。两个是代表不同的产品。

可以这么理解简单化工厂方法是创建一个产品的模式。

抽象化工厂模式是可以创建多个产品的模式。新增加一个Operate1 抽象类和具体实现Operate1 的子类,在抽象化工厂中新增一个创建Operate1 的方法。这这也是我总结他们两的不同之处


                                                     图二

 对比图一和图二, 图一值创建一个产品product,图二中可以看出抽象工厂模式创建两个产品productA和productB。

猜你喜欢

转载自blog.csdn.net/l_mr_l/article/details/80661041