以下是一种方法:
private RiskFactor calculateMotoristRiskFactor()
{
if (motorist.PointsOnLicense > 3
|| motorist.Age < 25)
return RiskFactor.HighRisk;
if (motorist.PointsOnLicense > 0)
return RiskFactor.ModerateRisk;
return RiskFactor.LowRisk;
}
我不想要那些if语句。
我可以使用策略模式来解决这个问题吗? 如果是,那么我也不希望不同多态类中的每个方法都应该包含 If语句。
RiskFactor是一个枚举
有什么更好的方法可以使这更加面向对象而不是程序化?
答案 0 :(得分:5)
好吧,你可以有List<Tuple<Func<Motorist, bool>, RiskFactor>
:
var filters = new List<Tuple<Func<Motorist, bool>, RiskFactor>
{
Tuple.Create(m => m.PointsOnLicense > 3, RiskFactor.HIGH_RISK),
Tuple.Create(m => m.Age < 25, RiskFactor.HIGH_RISK),
Tuple.Create(m => m.PointsOnLicense > 0, RiskFactor.MODERATE_RISK),
};
然后:
var risk = filters.Where(filter => filter.Item1(motorist))
.Select(filter => filter.Item2)
.DefaultIfEmpty(RiskFactor.LOW_RISK)
.First();
至少可以轻松添加额外的检查,它只是按顺序运行它们。它有点繁琐 - 我可能会创建一个自定义Filter
类型而不是Tuple
类型 - 但它应该有用......
答案 1 :(得分:2)
我不认为战略模式应该是这里的答案 - 如果您正在处理的驾驶者的特定类型影响行为,通常会使用策略。
在您的情况下,您只需拥有基于驾驶者属性的标准域逻辑。我认为条件处理非常合适。
答案 2 :(得分:1)
完全取消RiskFactor
功能。而不是该函数的消费代码,将需要其返回值的逻辑封装到以不同方式执行任务的单独类中。
例如,您可以定义由Policy
,LowRiskPolicy
和ModerateRiskPolicy
继承的抽象类HighRiskPolicy
。这些简单地返回根据适当的策略计算的值,消费代码不知道或关心它们是什么类型的策略。所有特定于策略的逻辑都包含在策略中。
答案 3 :(得分:0)
我认为你不需要更加面向对象只是为了更加面向对象。 如果它只存在于您计算风险的代码中,并且我假设根据年龄和许可证点计算出其他数据,我将保留您的代码。
除了可能将Motorist作为参数传递给RiscCalculator类的方法。
以防这里的类似示例为Replace Conditional with Polymorphism
答案 4 :(得分:0)
您将拥有更多代码,但它可以让您将其分解出来。您可以为每种类型的风险因素创建一个策略类,并将它们收集在一起。像这样:
public abstract class RiskPolicy
{
public abstract RiskFactor Risk { get; }
}
public class PointsPolicy : RiskPolicy
{
private readonly int _points;
public PointsPolicy(int points)
{
_points = points;
}
public override RiskFactor Risk
{
get { return _points > 3 ? RiskFactor.HIGH_RISK :
_points > 0 ? RiskFactor.MODERATE_RISK : RiskFactor.LOW_RISK; }
}
}
public class AgePolicy : RiskPolicy
{
private readonly int _age;
public AgePolicy(int age)
{
_age = age;
}
public override RiskFactor Risk
{
get { return _age < 25 ? RiskFactor.HIGH_RISK : RiskFactor.LOW_RISK; }
}
}