最近几天复习设计模式,首先最熟悉的就是工厂模式了。
平常主要用到了就两种,工厂模式(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!