目录
ENTITY FACTORY与VALUE OBJECT FACTORY
模式:FACTORY
当创建一个对象或创建整个AGGREGATE时,如果创建工作很复杂,或者暴露了过多的内部结构,则可以使用FACTORY进行封装。
对象的功能主要体现在其复杂的内部配置以及关联方面。我们应该一直对对象进行提炼,直到所有与其意义或在交互中的角色无关的内容被完全剔除为止。一个对象在它的生命周期中要承担大量职责。如果再让复杂对象负责自身的创建,那么职责过载将会导致问题。
汽车发动机是一种复杂的机械装置,它由数十个零件共同协作来履行发动机的职责——使轴转动。我们可以试着设计一种发动机组,让它自己抓取一组活塞并塞到汽缸中,火花塞也可以自己找到插孔并把自己拧进去。但这样组装的复杂机器可能没有我们常见的发动机那样可靠或高效。相反,我们用其他东西来装配发动机。或许是机械师,或者是工业机器人。无论是机器人还是人,实际上都比二者要装配的发动机复杂。装配零件的工作与使轴旋转的工作完全无关。只是在生产汽车时才需要装配工,我们驾驶时并不需要机器人或机械师。由于汽车的装配和驾驶永远不会同时发生,因此将这两种功能合并到同一个机制中是毫无价值的。同理,装配复杂的复合对象的工作也最好与对象要执行的工作分开。但将职责转交给另一个相关方——应用程序中的客户(client)对象——会产生更严重的问题。客户知道需要完成什么工作,并依靠领域对象来执行必要的计算。如果指望客户来装配它需要的领域对象,那么它必须要了解一些对象的内部结构。为了确保所有应用于领域对象各部分关系的固定规则得到满足,客户必须知道对象的一些规则。甚至调用构造函数也会使客户与所要构建的对象的具体类产生耦合。结果是,对领域对象实现所做的任何修改都要求客户做出相应修改,这使得重构变得更加困难。
当客户负责创建对象时,它会牵涉不必要的复杂性,并将其职责搞得模糊不清。这违背了领域对象及所创建的AGGREGATE的封装要求。更严重的是,如果客户是应用层的一部分,那么职责就会从领域层泄漏到应用层中。应用层与实现细节之间的这种耦合使得领域层抽象的大部分优势荡然无存,而且导致后续更改的代价变得更加高昂。
对象的创建本身可以是一个主要操作,但被创建的对象并不适合承担复杂的装配操作。将这些职责混在一起可能产生难以理解的拙劣设计。让客户直接负责创建对象又会使客户的设计陷入混乱,并且破坏被装配对象或AGGREGATE的封装,而且导致客户与被创建对象的实现之间产生过于紧密的耦合。
复杂的对象创建是领域层的职责,然而这项任务并不属于那些用于表示模型的对象。在有些情况下,对象的创建和装配对应于领域中的重要事件,如“开立银行账户”。但一般情况下,对象的创建和装配在领域中并没有什么意义,它们只不过是实现的一种需要。为了解决这一问题,我们必须在领域设计中增加一种新的构造,它不是ENTITY、VALUE OBJECT,也不是SERVICE。这与前一章的论述相违背,因此把它解释清楚很重要。我们正在向设计中添加一些新元素,但它们不对应于模型中的任何事物,而确实又承担领域层的部分职责。每种面向对象的语言都提供了一种创建对象的机制(例如,Java和C++中的构造函数,Smalltalk中创建实例的类方法),但我们仍然需要一种更加抽象且不与其他对象发生耦合的构造机制。这就是FACTORY,它是一种负责创建其他对象的程序元素。如下图所示。
正如对象的接口应该封装对象的实现一样(从而使客户无需知道对象的工作机理就可以使用对象的功能),FACTORY封装了创建复杂对象或AGGREGATE所需的知识。它提供了反映客户目标的接口,以及被创建对象的抽象视图。
因此:
应该将创建复杂对象的实例和AGGREGATE的职责转移给单独的对象&#x