[英]Is this considered as procedural programming (or anemic pattern)?
假设有两个类,一个是用户class,包含用户信息; 另一个是支付交易class,场景很简单,如果用户年龄>65,创建A类支付交易; 否则,创建 B 类支付交易。
做这件事有很多种方法:
func CreateTransaction(user, transaction) {
if user.GetAge() > 65:
transaction.CreateA()
else:
transaction.CreateB()
}
class User {
...
func CreateTransaction(transaction) {
if user.GetAge() > 65:
transaction.CreateA()
else:
transaction.CreateB()
}
}
然后有一个调用 function 的 CreateTransactionController 方法,例如:
func CreateTransactinController(user, transaction) {
user.CreateTransaction()
}
我的问题是,选项 1 是否被视为过程编程,因为逻辑实际上不属于任何 object? (或贫血模式?)1 和 2 之间的区别是否只是放置逻辑的不同位置?
谢谢!
由于您将此问题标记为 DDD,我将回答由域驱动的 model 将如何实现这一点。
要回答的问题是一个Transaction
是否包含在User
object之内。如果包含,则意味着你总是通过用户go的记录来获取交易(并且永远不会直接访问交易)。 如果一个事务本身有一个生命周期,可以直接访问,控制域的其他部分,等等,它就不能包含在一个User
中,而是一个成熟的聚合。
将transaction
包含在user
中意味着用户拥有与事务相关的操作,因此选项 2 是正确的方法。
如果transaction
是不同的聚合,您可以使用Domain Service
(如您的选项 1),但这是不正确的,因为您同时处理两个聚合( user
和transaction
)。 您最好将此功能包含在Transaction
聚合中。
下一个要解决的问题是您将如何决定交易类型。 一种方法是:
这通常是您处理依赖于来自多个聚合的属性的更改的方式。 你提前go,在系统中修改了聚合的state,但稍后及时查看相关的聚合数据,如果不一致则撤销修改。
更好的方法是创建一个Specification
,其明确的任务是根据用户的年龄得出正确的支付类型。 该规范包含您的业务逻辑(> 65),为年龄驱动的需求提供上下文,并充当您控制逻辑的中心位置。
您可以在此处阅读有关规格的更多信息: https://martinfowler.com/apsupp/spec.pdf
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.