Java设计模式之工厂模式

262 阅读4分钟

   最近几天复习设计模式,首先最熟悉的就是工厂模式了。

   平常主要用到了就两种,工厂模式(Factory Method)和抽象工厂模式(Abstract Factory 

Method)。这两个模式很相似,但是又有所不同,抽象工厂可以看作是工厂模式的扩展。

   首先来看工厂模式,我们为什么要用到工厂模式?用一种设计模式或者使用一种方法技术之

前我们一定要明白,使用了他能为我们带来什么。先看个简单的例子:

   在不使用工厂模式之前,我们如果要获取A B两个产品的话,需要手动实例化,这个例子还算简单,如果遇到比较多的运算实例要初始化,以及初始化需要很多参数,那么每一次的new就比较繁琐。

//实例化A产品操作
ProductA A = new ProductA(typedef xx1,typedef xx2,typedef xx3);
//实例化B产品操作
ProductB B = new ProductB(typedef xx1,typedef xx2,typedef xx3);

   如果使用工厂模式进行改写,乍一看使用起来差不多,代码量反而增加了。

//准备工作
//首先定义操作接口
public interface Product {

}
//之后让ProductA、ProductB类实现Product接口
public class ProductA implements Product{}
public class ProductB implements Product{}
//之后在工厂类中编写相应的初始化GetInstance方法
public class Factory{
      private Factory() {}
      public static Product getProductB(){
        xx1 = Properties.getKey("xx1");
        xx2 = Properties.getKey("xx2");
        xx3 = Properties.getKey("xx3");  
        return new ProductB(typedef xx1,typedef xx2,typedef xx3);
      }
      public static Product getProductA(){
        xx1 = Properties.getKey("xx1");
        xx2 = Properties.getKey("xx2");
        xx3 = Properties.getKey("xx3"); 
        return new ProductA(typedef xx1,typedef xx2,typedef xx3);
      }
}
//客户端需要使用
@Test
public void testOperation(){
      getProductA getProductA = Factory.getProductA();
      getProductB getProductB = Factory.getProductB();
}

    其实不然,作为使用者,之前每一次生产AB产品都需要初始化三个参数,现在只需要工厂Get一个实例即可,而不用关心A的实例化过程,从而达到一定程度的方便。

    而且使用者方法肩负初始化A和使用A这两种操作的重任,它既要创建对象又要使用对象,增加了代码的耦合度,导致以后修改代码,牵一发而动全身,不利于以后模块化的修改和更新。

之所以使用工厂模式有几个点:

    1,对于对象的初始化需要特别多参数的,例如查询数据库时候需要URl用户名密码等等,不可能每次在Dao中都要初始化一次,所以需要工厂类自动完成实例化返回对象,使用者只需使用即可不必关心其他。

    2,对于一些经常变动的子类,例如经常修改产品A的初始化参数,那么众多使用者不必在修改代码,只需修改工厂类的初始化方法即可。

TIPS:静态工厂类也并不是所有的都需要使用,看情况而定,如果对于参数简单,形式固定,功能固定的类就反而是小题大做了,例如基本变量int,每次在搞一个IntUtil去Get一个实例,就没有必要了。


     说完静态工厂类的众多优点,当然它还是有很多不足之处,

     1,如果一个大项目,很多开发人员都要共同修改一个工厂类显得有点不方便。而且只有一个工厂类,一旦出BUG,整个系统都不能使用,稳定性不高。

     2,如果要新增工厂类方法,必须要修改原有的工厂类,这不符合“开闭原则”,即对扩展开放,对修改关闭。

     3,单一的工厂静态类无法实现继承也不可以被改写。

于是我们用到抽象工厂方法来解决这个问题。其实抽象工厂方法就是让原有的工厂类实现一个

工厂接口。那么就不再是单一工厂类,可以多个工厂类实现同一个接口。

public interface Factory{
     public Product getProduct();
}

public class FactoryA implements Factory{
     @overide
     public Product getProduct(){
        xx1 = Properties.getKey("xx1");
        xx2 = Properties.getKey("xx2");
        xx3 = Properties.getKey("xx3"); 
        return new ProductA(typedef xx1,typedef xx2,typedef xx3);
      }
}
public class FactoryB implements Factory{
     @overide
     public Product getProduct(){
        xx1 = Properties.getKey("xx1");
        xx2 = Properties.getKey("xx2");
        xx3 = Properties.getKey("xx3");  
        return new ProductB(typedef xx1,typedef xx2,typedef xx3);
     }
}

       这样就可以把工厂类分散开来,进行功能上解耦,添加新功能的时候就不必修改原有工厂类,而直接继承接口创建新的工厂类,或者复写即可。


OK! More Coding More Experienced!