我习惯使用更加数据库驱动的方法来设计我的应用程序,现在我想从模型开始。我有以下要求,并希望得到你的承诺。它基本上是一个带有与之相关的点的活动。
Super 30医生的活动
120医生的活动
与伙伴关系的活动
与后续伙伴关系会议的活动
所以,我试图决定是否在这里为每个活动类型或活动的枚举使用继承层次结构。那么,每个活动是否负责计算他们的积分(但在某些情况下需要知道要决定的总活动数)或者我是否有一些得分者组件知道所有的逻辑。
任何想法都会很棒!
到目前为止我有这个设计,但我不知道在哪里处理Super 30规则:
public abstract class ActivityBase {
public int Id { get; set; }
public DateTime Date { get; set; }
public abstract double CalculatePoints();
}
public class SuperThirtyActivity : ActivityBase {
public bool WithCE { get; set; }
public bool WithLocalAdvocate { get; set; }
public override double CalculatePoints() {
if (Date.Month == 3 && Date.AddDays(7).Month == 4)
return 1;
else if (WithCE || WithLocalAdvocate)
return 2;
else
return 1;
}
}
public class OneTwentyActivity : ActivityBase {
public override double CalculatePoints() {
return .5;
}
}
public class PartnershipActivity : ActivityBase {
public override double CalculatePoints() {
return 2;
}
}
现在要处理Super 30规则,我想介绍下面的课程。但是,一些域逻辑在这里泄漏。这是好的还是其他任何想法?
public class Scorer {
public double CalculateScore(IEnumerable<ActivityBase> activities) {
var score = activities.Select(a => a.CalculatePoints()).Sum();
var count = activities.Count(a => a is SuperThirtyActivity);
if (count < 4)
score--;
else if (count > 6)
score += count;
return score;
}
}
答案 0 :(得分:1)
如果活动基类不包含逻辑,我建议创建一个IActivity接口并创建4个类来实现它而不是继承。 IActivity应该有一个类似CalculatePoints的方法,由每个实现类实现。
如果你不打算在应用程序的任何地方检查活动类型,我的意思是你永远不会有像这样的代码:
if (activity is PartnershipActivity){
//do something
}
else if (activity is FollowUpActivity) {
// do something else
}
如果您确定将来不会在应用程序中引入新的活动类型,那么您可以考虑使用enum字段创建一个Activity类,并执行您在其业务逻辑中提到的所有检查和计算。
答案 1 :(得分:0)
由于某些点基于聚合活动,因此看起来在对象模型ActivityCollection中没有捕获到另一个概念。它在Scorer.CalculateScore的参数中暗示,但可能需要明确。然后,ActivityCollection可以计算得分,因为它保存了所有必要的信息。
另一方面,Scorer对象也可以提供该角色。域逻辑在Scorer对象中是可以的,因为它只是Scorer完成其名称所暗示的必要逻辑。如果您保留Scorer,但将活动类中的点值移动到其中,那么即使不是更好,该结构也可以起作用。