分离此代码关注点的最佳方法是什么?
在 上一个问题来自博士的评论之一Herbie 接受的答案是我的方法正在执行两项职责......更改数据和保存数据。
我试图找出在我的情况下区分这些问题的最佳方法。
继续我的示例,通过 NHibernate 检索一个 Policy 对象......
我当前将策略设置为非活动状态的方式如下:
Policy policy = new Policy();
policy.Status = Active;
policyManager.Inactivate(policy);
//method in PolicyManager which has data access and update responsibility
public void Inactivate(Policy policy)
{
policy.Status = Inactive;
Update(policy);
}
如果我将数据访问和数据更新的责任分开,将会是什么最好的方法是什么?
是让PolicyManager(充当dao的网关)管理Policy对象的状态更好:
Policy policy = new Policy();
policy.Status = Active;
policyManager.Inactivate(policy);
policyManager.Update(policy);
//method in PolicyManager
public void Inactivate(Policy policy)
{
policy.Status = Inactive;
}
还是让Policy对象维护它自己的状态,然后使用管理器类将信息保存到数据库:
Policy policy = new Policy();
policy.Status = Active;
policy.Inactivate();
policyManager.Update(policy);
//method in Policy
public void Inactivate()
{
this.Status = Inactive;
}
In a previous question one of the comments from Dr. Herbie on the accepted answer was that my method was performing two responsibilities..that of changing data and saving data.
What I'm trying to figure out is the best way to separate these concerns in my situation.
Carrying on with my example of having a Policy object which is retrieved via NHibernate....
The way I'm currently setting the policy to inactive is as follows:
Policy policy = new Policy();
policy.Status = Active;
policyManager.Inactivate(policy);
//method in PolicyManager which has data access and update responsibility
public void Inactivate(Policy policy)
{
policy.Status = Inactive;
Update(policy);
}
If I were to separate the responsibility of data access and data update what would be the best way to go about it?
Is it better to have the PolicyManager (which acts as the gateway to the dao) manage the state of the Policy object:
Policy policy = new Policy();
policy.Status = Active;
policyManager.Inactivate(policy);
policyManager.Update(policy);
//method in PolicyManager
public void Inactivate(Policy policy)
{
policy.Status = Inactive;
}
Or to have the Policy object maintain it's own state and then use the manager class to save the information to the database:
Policy policy = new Policy();
policy.Status = Active;
policy.Inactivate();
policyManager.Update(policy);
//method in Policy
public void Inactivate()
{
this.Status = Inactive;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我会做什么:
创建一个保存和检索策略的存储库。 (PolicyRepository)
如果您必须执行复杂的逻辑来激活/停用策略,您可以为此创建一个服务。如果该服务需要访问数据库,那么您可以在必要时将 PolicyRepository 传递给它。
如果不涉及复杂的逻辑,并且激活/停用策略只需将标志设置为 false 或 true,或者仅涉及策略类的成员,那么为什么“激活”不是策略的简单属性您可以将哪个类设置为 false / true ?
如果涉及其他对象,或者需要数据库访问来激活或停用策略,我只会创建一个服务。
What I would do:
Create a repository which saves and retrieves Policies. (PolicyRepository)
If you have complex logic that must be performed to activate / deactivate a policy, you could create a Service for that. If that service needs access to the database, then you can pass a PolicyRepository to it, if necessary.
If no complex logic is involved, and activating / deactivating a policy is just a matter of setting a flag to false or true, or if only members of the policy class are involved, then why is 'Activated' not a simple property of the Policy class which you can set to false / true ?
I would only create a service, if other objects are involved, or if DB access is required to activate or deactivate a policy.
作为我原来评论的延续:) ...
目前你最好的选择是第三个选项,但如果事情变得更复杂,你可以选择第二个,同时添加门面方法来执行预先指定的序列:
InactivateAndUpdate 是一种门面方法,它只是用来进行调用代码更整洁一点,同时仍然允许执行实际工作的方法是单独的关注点(有点打破方法的单一责任,但有时你只需要务实!)。我特意以 XandY 风格命名这些方法,以使它们在做两件事时脱颖而出。
然后,InactivateAndUpdate 方法可以让您开始实现策略模式或将实际的实现方法拆分为用于动态处理的命令对象或将来可能变得可行的任何其他体系结构。
As a continuation of my original comment :) ...
Currently your best bet is the third option, but if things get more complex you could go with the second, while adding facade methods to perform pre-specified sequences:
The InactivateAndUpdate is a kind of facade method, which is just there to make the calling code a little neater, while still allowing the methods doing the actual work to be separate concerns (kind of breaks single responsibility for methods, but sometimes you just have to be pragmatic!). I deliberately name such methods in the style XandY to make them stand out as doing two things.
The InactivateAndUpdate method then frees you up to start implementing strategy patterns or splitting out the actual implementation methods as command objects for dynamic processing or whatever other architecture might become feasible in the future.
由于您提到的原因,我肯定会选择第三种选择:
另请查看存储库模式。它可能会替代您的
PolicyManager
。I would definitely go with the 3rd option for the reasons you mentioned:
Also take a look at the Repository Pattern. It might substitute your
PolicyManager
.如果状态是
Policy
类状态的一部分,那么Policy
还应该具有Inactivate
方法——这只是基本封装。将多个类纠缠在一个职责中至少与赋予单个类多个职责一样糟糕。或者,状态可以被视为关于
Policy
的元数据,不属于Policy
而是属于PolicyManager
。但在这种情况下,Policy
根本不应该知道自己的状态。If the status is part of the state of the
Policy
class, then thePolicy
should also have theInactivate
method -- that's just basic encapsulation. Entangling multiple classes in a single responsibility is at least as bad as giving a single class multiple responsibilities.Alternatively, the status could be considered metadata about the
Policy
, belonging not to thePolicy
but to thePolicyManager
. In that case, though, thePolicy
shouldn't know its own status at all.