`
ihuashao
  • 浏览: 4721334 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论
阅读更多
FACTORY
在程序中,如下写法十分常见:
T2kArea area=new T2kArea(name);
此时,程序依赖于具体类T2kArea,如果具体类发生变化,那么程序中每一处使用如上代码的地方都要修改。所以就要应用Factory模式,使得程序依赖于抽象。
如果具体类是稳定的,那么依赖它就不会出现麻烦。例如创建String对象就不会有问题,应为String不会随时改变。
在软件开发过程中,大多数的类都是会随时改变的,所以程序要依赖于抽象而避免依赖于具体类。
背景:在ipass系统中,Area 对应的是T2k 设备集和N2k子图,因为他们的显示结构不同,又要避免频繁的使用if /else来判断类型,就需要分别建立T2kArea和N2kArea具体类。
1

IArea接口,但还是依赖了T2kAreaN2kArea具体类。

虽然程序是调用
例2

public interface IAreaFactory {
public IArea createT2kArea();
public IArea createN2kArea();
}
public class AreaFactory implements IAreaFactory {
public IArea createN2kArea() {
return new N2kArea();
}
public IArea createT2kArea() {
return new T2kArea();
}
}
上例中,程序完全依赖于抽象,但如果再添加一种M2kArea,就需要在IAreaFactory,AreaFactory中都要添加方法createM2kArea().
例3

public interface IAreaFactory {
public IArea createArea(String type);
}
public class AreaFactory implements IAreaFactory {
public IArea createArea(String type) {
if (type.equals("t2k")) {
return new T2kArea();
} else {
return new N2kArea();
}
}
}
上例中,createArea(String type) 通过相应的输入参数来构造对应的Area。在程序中有时候可能会有参数输入错误的情况,但如果在单元测试充分的条件下,此问题很容易避免。
例4

上例,可以在不同的数据库后台切换,LdapAreaFactory可以将信息保存在Ldap上,OracleAreaFactory可以将信息保存在Oracle数据库上。应用程序并不知道,也不关心正在使用哪一个工厂实现。
例5

有时候,我们希望能够在完全不使用数据库的情况下测试程序与数据库交互的接口。使用Factory模式可以很容易的模仿数据库的行为,欺骗应用程序。而且它还可以模仿多种现实中很难模拟的数据库失败原因。
上图中,使用EmsText程序来测试EmsEmsTest实现LdapFactoryLdap接口。在Ems中保存一个LdapFactory的全局静态变量,在实际使用时,此变量设为LdapFactoryImplementation的引用,在测试时,将此变量设为EmsTest。这样,EmsTest就能欺骗Ems模拟所有的Ldap的操作。(在本例中,可以将Ldap理解为JDBC)。
惨痛的教训:
在ipass系统中,每处连接ldap的地方都是用DirContext ctx=new InitialDirContext();而后,当ipass需要支持多ldap server的时候,需要把每一处这样的代码都改成
DirContext ctx=LDAPContextFactory.getAvailableContext();LDAPContextFactory是用来维护多个ldap的上下文。好在有eclipse的search功能,而且程序各处都是写的DirContext ctx=new InitialDirContext();很容易就批量修改了。
不是任何一个具体类都要应用Factory模式,毕竟一个具体类就要增加一个抽象接口,一个工厂接口,最少一个工厂实现。这样,会使程序的规模成指数级增长。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics