使用访客模式来处理其他如果

本文关键字:处理 其他 如果 模式 访客 | 更新日期: 2023-09-27 17:56:39

我想知道是否有任何方法可以使用访问者模式处理简单的条件?

例如,如果我们有下面的代码,我们如何将访问者模式应用于它?

public class Elseif
{
    private int total;
    public int Condition(int x)
    {
        if(x==1)
        {
            total = 100;
        }
        else if(x==2)
        {
            total = 200;
        }
        return total;
    }
}

换句话说,你想如何编写IVisitor接口的重载?

public interface IVisitor
{
    int Visitor(int x);
}

使用访客模式来处理其他如果

也许您正在寻找责任链模式?

假设您必须计算奖金,并且您使用类似的东西

public double GetBonusRate(int workingDays, int numberOfSales)
{
    if(numberOfSales > 20)
    {
      return 1.5;
    }
    if(workingDays >= 20 && numberOfSales > 10)
    {
      return 1.2;
    }
    if(numberOfSales > 5)
    {
      return 1.0;
    }
    if(workingDays > 10)
    {
      return 0.1;
    }
    return 0;
}
您期望,条件

的数量会增加,并且您意识到,在错误的位置添加新条件会导致错误。
责任链为您提供了另一种方法。

var chain = new PerfectBonusRate();
chain.RegisterNext(new GoodBonusRate())
    .RegisterNext(new StandartBonusRate())
    .RegisterNext(new LazyBonusRate())
    .RegisterNext(new NoBonusRate());
var bonusRate = chain.GetBonusRate(10, 20);

实现

abstract class ChainElement
{
    ChainElement _next;
    public ChainElement RegisterNext(ChainElement next)
    {
        _next = next;
        return next;
    }
    public double GetBonusRate(int workingDays, int numberOfSales)
    {
        if(IsMatched(workingDays, numberOfSales))
        {
            return GetBonusValue();
        }
        return _next.GetBonusRate(workingDays, numberOfSales);
    }
    protected abstract bool IsMatched(int workingDays, int numberOfSales);
    protected abstract int GetBonusValue();
}
class PerfectBonusRate : ChainElement
{
    protected override bool IsMatched(int workingDays, int numberOfSales)
    {
        return numberOfSales > 20;
    }
    protected override double GetBonusValue()
    {
        return 1.5;
    }
}
class GoodBonusRate : ChainElement
{
    protected override bool IsMatched(int workingDays, int numberOfSales)
    {
        return workingDays >= 20 && numberOfSales > 10;
    }
    protected override double GetBonusValue()
    {
        return 1.2;
    }
}
//and the same for StandartBonusRate, LazyBonusRate...
class NoBonusRate : ChainElement
{
    protected override bool IsMatched(int workingDays, int numberOfSales)
    {
        return true;
    }
    protected override double GetBonusValue()
    {
        return 0.0;
    }
}

访客模式用于区分不同的类型,特别是如果你有一个(抽象)超类的对象,并且你想根据具体类型做特殊的事情。这意味着,您可以(并且应该)使用它来代替带有铸造测试的if-then-else。

访客模式不用于区分

用于解决某些特定问题的模式。访客模式解决了以下问题 - 在不更改这些对象的情况下向对象的(复合)结构添加新功能。因此,让我改写您的问题 - 如何在不添加对象结构和功能的情况下向对象结构添加新功能。这就像用小提琴敲钉子一样。

记住 - 首先是问题。然后是解决这个问题的模式。反之亦然。

更新 那么,你的代码有什么问题?它不遵循命令-查询分离原则。相同的方法执行操作(修改总计)并将总计返回给调用方。我将命令和查询分开,以使您的代码更清晰:

public int Total { get; set; }
public void DoSomething(int x)
{
    if(x == 1)
    {
        Total = 100;
        return;
    }
    if(x == 2)
    {
       Total = 200;
       return;
    }
}