[英]Is this considered as procedural programming (or anemic pattern)?
Let's say there are two classes, one is the user class, which contains the user information;假设有两个类,一个是用户class,包含用户信息; the other one is the payment transaction class. The scenario is simple, if the user's age is > 65, create type A payment transaction;
另一个是支付交易class,场景很简单,如果用户年龄>65,创建A类支付交易; otherwise, create type B payment transaction.
否则,创建 B 类支付交易。
There are several ways to do this:做这件事有很多种方法:
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()
}
}
Then there is a CreateTransactionController method that calls the function like:然后有一个调用 function 的 CreateTransactionController 方法,例如:
func CreateTransactinController(user, transaction) {
user.CreateTransaction()
}
My question is, is the option 1 considered as procedural programming since the logic is actually not owned by any object?我的问题是,选项 1 是否被视为过程编程,因为逻辑实际上不属于任何 object? (Or anemic pattern?) Is the difference between 1 and 2 be just different place to put the logic?
(或贫血模式?)1 和 2 之间的区别是否只是放置逻辑的不同位置?
Thanks!谢谢!
Since you marked this question as DDD, I will answer how a model, driven by the Domain, would implement this.由于您将此问题标记为 DDD,我将回答由域驱动的 model 将如何实现这一点。
The question to answer is whether a Transaction
is enclosed within the User
object. If it is enclosed, it means that you always go through the user's record to fetch transactions (and never access transactions directly).要回答的问题是一个
Transaction
是否包含在User
object之内。如果包含,则意味着你总是通过用户go的记录来获取交易(并且永远不会直接访问交易)。 If a transaction by itself has a lifecycle, can be accessed directly, controls other parts of the domain, and so on, it cannot be enclosed within a User
and is a full-blown aggregate.如果一个事务本身有一个生命周期,可以直接访问,控制域的其他部分,等等,它就不能包含在一个
User
中,而是一个成熟的聚合。
Enclosing the transaction
within the user
would mean that the user owns transaction-related operations, so option 2 would be the right way.将
transaction
包含在user
中意味着用户拥有与事务相关的操作,因此选项 2 是正确的方法。
If transaction
is a different aggregate, you could use a Domain Service
(like your option 1), but it is incorrect because you handle two aggregates ( user
and transaction
) simultaneously.如果
transaction
是不同的聚合,您可以使用Domain Service
(如您的选项 1),但这是不正确的,因为您同时处理两个聚合( user
和transaction
)。 You are better off enclosing this functionality within the Transaction
aggregate.您最好将此功能包含在
Transaction
聚合中。
The next question to address is how you would decide the type of transaction.下一个要解决的问题是您将如何决定交易类型。 One way is:
一种方法是:
This is commonly how you handle changes that depend on attributes from multiple aggregates.这通常是您处理依赖于来自多个聚合的属性的更改的方式。 You go ahead and change the state of the aggregate in the system, but check at a later point in time for the related aggregate data, and reverse the change if things are not congruent.
你提前go,在系统中修改了聚合的state,但稍后及时查看相关的聚合数据,如果不一致则撤销修改。
A better way is to create a Specification
whose explicit task is to derive the right payment type based on the user's age.更好的方法是创建一个
Specification
,其明确的任务是根据用户的年龄得出正确的支付类型。 The specification encloses your business logic (> 65), gives context to the age-driven requirement, and acts as a central place where you would control the logic.该规范包含您的业务逻辑(> 65),为年龄驱动的需求提供上下文,并充当您控制逻辑的中心位置。
You can read more about specifications here: https://martinfowler.com/apsupp/spec.pdf您可以在此处阅读有关规格的更多信息: https://martinfowler.com/apsupp/spec.pdf
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.