我们可以用C#中的对象替换if语句吗?

时间:2011-07-28 19:49:43

标签: c# oop refactoring

以下是一种方法:

  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是一个枚举

有什么更好的方法可以使这更加面向对象而不是程序化?

5 个答案:

答案 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功能。而不是该函数的消费代码,将需要其返回值的逻辑封装到以不同方式执行任务的单独类中。

例如,您可以定义由PolicyLowRiskPolicyModerateRiskPolicy继承的抽象类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; }
        }
    }