六年后,这需要进行重大更新。
简单的答案是肯定的。但复杂的答案是否定的。
不,SOA 不需要贫血。但同时,企业系统不需要使用 SOA 编写。同样,架构对于任何代码都不是必需的。这将是一场噩梦,但如果您愿意,您可以将所有功能都打包到一个模块中。
简单地说:OO 最初的定义是它与其前辈的不同之处。更具体地说:C++ 的定义是它与 C 的不同之处。但是 OO 的定义已经改变。我们现在有大量的 OO 原则。
免责声明:其中许多原则部分或全部在 OO 之前创建,并且在 OO 革命期间被简单地声明或更新。另外,我意识到 OO 在 LONG-Before C++ 之前就已经存在,但这并没有改变我的说法:
封装、继承、多态性、关注点分离、持久性无知、高内聚/低耦合、S、O、L、I、D 等等。
不仅如此,如果您在遵循这些原则的同时遵循 DDD 和/或 TDD,您几乎根本不需要架构师。只要遵循这些原则,您自然会得到一个使用贫血域模型的面向服务的架构。
想想看。如果您的 Employee 类带有Save()
, SendMessage()
, 和PayEmployee()
...,那么您就违反了当前 OO 原则的许多规则。
当您分析并将某些职责提取到不同的服务、存储库、命令、工厂等时……您不得不拥有一个空的员工类……有点。
有点?
老实说,您需要牢记价值对象的概念。不仅OO的定义发生了演变,“贫血”的定义也发生了演变。Employee 类当然不应该为空。它可以包含大量的“业务逻辑”。
Employee 类可以有:
- 参数化构造函数,其中参数经过验证
- 计算字段的只读属性
- Employee.ToString()、Employee.TryParse() 和类似的对象方法
- 可能是其他人,特定于员工
从本质上讲,员工仍然是贫血的。领域模型中肯定永远不会有任何算法或代码流逻辑。但不只是一种业务逻辑。
十多年前,当 Martin Fowler 说贫血域模型是一种反模式时,它已经变得越来越可行。他的理由是双重的,而且这两个方面都是旧闻。
他的第一个折叠是他对 OO 的辩护定义是代码和数据是结合的,或者“将数据和过程结合在一起”,这与旧的程序风格相反。不幸的是,这只适用于糟糕的代码。如果我们遵循继承和多态,我们知道函数并不真正存在于类中。它们存在于指针中,因此继承类可以覆盖和移动它们。但是......他们是否存在于代码中以增加可读性?他们当然不应该!它们应该在接口和抽象中定义,并且只在类中实现。抱歉,Martin,尽管您说代码/数据结合是 20 年前 OO 的一个巨大的原始卖点是对的,但现在已经不是手头的问题了。
他的第二个观点是,他认为 SOA 做得不正确,并指出了一些与我们今天所说的 N-Tiered Architecture 非常相似的描述。诚然,我意识到这不是新技术,但这些年来定义发生了变化。
不仅 Martin Fowler,而且他之后的许多其他人都立即引用了他的文章,因此说 SOA 本身就是一种反模式,因为它需要贫血模型,Fowler 说这是一种反模式。
所以我们到了这个...
贫血领域模型并不像人们想象的那样贫血。而且 SOA 是必需的,我们不能打折扣。不幸的是,这只是事情的本来面目。
为什么需要 SOA?- 这太描述性了。但长话短说:在 90 年代,软件在 PC 和服务器上运行……而硬件“插入”这些单体。这些天来,我们周围有数以万亿计的“计算机”。烟雾探测器、冰箱、手表、电话……这些天计算机插入事物。因此,每个想法、部门、CONCERN和对象都是它自己的小领域。我们要求 SOA 将它们写成自己的小服务,甚至是子服务。
因此:应用程序现在插入服务(而不是服务插入应用程序)。要创建 SOA,我们只需遵循 OO 的当前规则,例如 SOLID 和关注点分离。当我们这样做时,我们自然会得到贫血域模型......有点。
所以不,SOA 不需要贫血域模型。它们是遵循现行原则和标准的自然结果。