分离此代码的问题的最佳方法是什么?

时间:2009-09-15 07:31:55

标签: c# separation-of-concerns

来自previous questionDr. 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;
}

4 个答案:

答案 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根本不应该知道自己的状态。