来自previous question的Dr. 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对象维护它自己的状态,然后使用manager类将信息保存到数据库:
Policy policy = new Policy();
policy.Status = Active;
policy.Inactivate();
policyManager.Update(policy);
//method in Policy
public void Inactivate()
{
this.Status = Inactive;
}
答案 0 :(得分:3)
我会做什么:
创建一个保存和检索策略的存储库。 (PolicyRepository)
如果您必须执行复杂的逻辑来激活/停用策略,您可以为此创建服务。如果该服务需要访问数据库,则可以根据需要将PolicyRepository传递给它。 如果不涉及复杂的逻辑,并且激活/停用策略只是将标志设置为false或true,或者只涉及策略类的成员,那么为什么'Activated'不是Policy的简单属性你可以设置为false / true的类吗? 我只会创建服务,如果涉及其他对象,或者需要数据库访问来激活或停用策略。
答案 1 :(得分:1)
出于你提到的原因,我肯定会选择第3种选择:
Policy对象维护它自己 state然后使用manager类 将信息保存到 数据库
另请查看Repository Pattern。它可能会替换您的PolicyManager
。
答案 2 :(得分:1)
作为我原始评论的延续:) ... 目前你最好的选择是第三种选择,但如果事情变得更复杂,你可以选择第二种,同时添加Facade方法来执行预先指定的序列:
Policy policy = new Policy();
policy.Status = Active;
policyManager.InactivateAndUpdate(policy);
//methods in PolicyManager
public void Inactivate(Policy policy)
{
// possibly complex checks and validations might be put there in the future? ...
policy.Status = Inactive;
}
public void InactivateAndUpdate(Policy policy)
{
Inactivate(policy);
Update(policy);
}
InactivateAndUpdate是一种Facade方法,它只是为了使调用代码更整洁,同时仍然允许执行实际工作的方法成为单独的问题(对方法的一种单一责任,但有时你只需要务实!)。我故意在X 和 Y样式中命名这些方法,以使它们在做两件事时脱颖而出。
然后,InactivateAndUpdate方法可以让您自由地开始实施策略模式,或者将实际的实现方法拆分为动态处理的命令对象,或者将来可能采用的其他任何架构。
答案 3 :(得分:0)
如果状态是Policy
类的状态的一部分,那么Policy
也应该具有Inactivate
方法 - 这只是基本的封装。在一个职责中纠缠多个班级至少与给予一个班级多重责任一样糟糕。
或者,可以将状态视为关于 Policy
的元数据,不属于Policy
,而属于PolicyManager
。但是,在这种情况下,Policy
根本不应该知道自己的状态。