为什么要使用工厂方法

图片描述

和我直接new有什么区别呢?

阅读 6.2k
5 个回答

工厂模式并不仅仅是用来new出一个类的对象的。
简单工厂确实如题主的描述所说,是一个工厂对应一个类的关系。

假设有代码包A和代码包B,代码包B是代码包A的调用者,A向B暴露接口InterfaceA。
在A的内部结构中,实现了InterfaceA的有ClassA1,ClassA2,ClassA3,……ClassA100。
但是B并不关心这些,因为对于B来说,A的功能只有一个,就是InterfaceA。

这个时候,B想要使用一个InterfaceA的实现,想要new一个出来,但又不想与代码包A中的复杂的构造逻辑耦合,怎么办?

只能向代码包A中传递参数,交给代码包A自己选择到底是那个ClassA1还是A100被new出来。
而这个对构造过程进行选择的逻辑,就是工厂。

当然了,我这里举的例子是InterfaceA,你也可以用AbstractClassA之类的。
工厂在这里面起的作用,就是隐藏了创建过程的复杂度,以配合InterfaceA对那一百个子类的复杂度进行隐藏,这样B只要知道上转型之后的InterfaceA即可,简单清晰。

对于调用者其实不关心被调用的实现的关系。降低耦合

• 可以使代码结构清晰,有效地封装变化。调用者只关心接口就可以了,至于具体的实现,调
用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
说白了,就是降低耦合度

直接new的话扩展性比较差,使用工厂模式的话可以将相关类配置到xml等配置文件或者数据库中,这样可以只增加类而无需修改之前的文件,确保稳定性、更易维护

下述文字节选自我自己的博客 怎样写好业务代码——那些年领域建模教会我的东西,其中关于领域建模中 Context 元素的一段描述。工厂模式作为 context 实现的基石,从某种意义上讲,下述优点也是我们在代码中使用工厂模式的初衷:

-----分割线-----

汽车发动机是一种复杂的机械装置,它由数十个零件共同协作来侣行发动机的职责 —
使轴转动。我们可以试着设计一种发动机组,让它自己抓取一组活塞并塞到气缸中,火花塞也可以自己找到插孔并把自己拧进去。但这样组装的复杂机器可能没有我们常见的发动机那样可靠或高效。相反,我们用其他东西来装配发动机。或许是一个机械师,或者是一个工业机器人。无论是机器还是人,实际上都比二者要装配的发动机复杂。装配零件的工作与使轴旋转的工作完全无关。装配者的功能只是在生产汽车时才需要,我们驾驶时并不需要机器人或机械师。由于汽车的装配和驾驶永远不会同事发生。因此将这两种功能合并到同一个机制中是毫无意义的。同理,装配复杂的复合对象的工作也最好与对象要执行的工作分开。

——Eric Evans《领域驱动设计》

与发动机小栗子相类似,代码中我们当然可以通过构造器的方式用到哪个对象再组装哪个对象。不过比较一下这样两段代码:

没有 Context 元素的代码:

@Transactional
public int deleteResRoute(ResIdentify operationRes, boolean protectFlag) {
  ...
  //1.获取需要保存对象的Entity
  OperationRouteResEntity resEntity = new TrsChannelResEntity();
  if(ResSpecConst.isChannelEntity(operationRes.getResSpcId())){
    ComponentsDefined component = new TrsChannelDataOperation();
    resEntity.initResEntityComponent(conponent);
  }
  ...
}

有了 Context 元素以后

@Transactional
public int deleteResRoute(ResIdentify operationRes, boolean protectFlag) {
  ...
  //1.获取需要保存对象的Entity
  OperationRouteResEntity resEntity = context.getResEntity(operationRes,OperationRouteResEntity.class);
  ...
}

······

-----分割线-----

更多介绍请常见本人的博客 怎样写好业务代码——那些年领域建模教会我的东西

工厂方法,主要是封装复杂生产的过程,提高复用性,降低使用难度。

比如,你需要一台电脑上网,你可以选择,自己造一台(1天,容易出错),或者工厂里买一台(1小时,厂家服务完善)。

从工厂里买电脑你使用的时候可以不管生产细节,这就是封装的体现。

如果你爸还要一台电脑打麻将,你是花1天时间造一台还是去工厂里直接买一台?这就是工厂量产带来的复用性。

在编程里的话,比如,你需要用的MySQL Connection之类的,就可以放在工厂里,这样每个model里去查数据就不用自己重新去连数据库。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题