C# 如果需要,请使用访问者模式处理else

C# 如果需要,请使用访问者模式处理else,c#,design-patterns,visitor-pattern,C#,Design Patterns,Visitor Pattern,我想知道是否有任何方法可以处理访问者模式的简单条件 例如,如果我们有下面的代码,我们如何将访问者模式应用于它 public class Elseif { private int total; public int Condition(int x) { if(x==1) { total = 100; } else if(x==2) { total

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

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

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);
}

访问者模式用于区分不同的类型,特别是如果您有一个(抽象)超类的对象,并且您希望根据具体类型执行特殊操作。这意味着,您可以(也应该)在铸造测试中使用它,而不是if-then-else


访问者模式不用于区分值。

访问者模式用于区分不同的类型,特别是如果您有一个(抽象)超类的对象,并且希望根据具体类型执行特殊操作。这意味着,您可以(也应该)在铸造测试中使用它,而不是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;
    }
}

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

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

那么,您的代码有什么问题?这不符合原则。同一方法执行一个操作(修改总计)并将总计返回给调用者。我将命令和查询分开,以使代码更清晰:

public int Total { get; set; }

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

    if(x == 2)
    {
       Total = 200;
       return;
    }
}
也许你在寻找图案

假设你必须计算奖金,你使用这样的方法

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;
    }
}
也许你在寻找图案

假设你必须计算奖金,你使用这样的方法

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;
    }
}

这不是
访问者的任务,在我看来这是不可能的。模式-这不是你需要的东西,有必要让它成为它所要求的模式。谢谢,我知道我只是在寻找一种隐藏他人的方法,如果我的方法是单一的,这不是
visitor
模式的任务,在我看来这是不可能的。模式-这不是你需要的东西,这是必要的,使之成为它所要求的模式。谢谢,我知道我只是在寻找一种隐藏elseIf的方法,以使我的方法成为单一负责的方法。在这个例子中,你有什么建议来摆脱elseIf吗?@wikinevis是的,我有-单独的命令和查询。我将在几分钟后添加一些代码,现在它以告诉不要问的方式遵循CQRS,但仍在做两件事。事实上,如果要使用单一负责方法,我正在寻找一种摆脱else的方法。@wikinevis您能指出代码正在做的这两件事吗?谢谢,在本例中,您对摆脱elseif有什么建议吗?@wikinevis是的,我有-单独的命令和查询。我将在几分钟后添加一些代码,现在它以告诉不要问的方式遵循CQRS,但仍在做两件事。事实上,我正在寻找一种方法,如果有一个单一的负责方法,就可以摆脱它。@wikinevis你能指出代码正在做的这两件事吗?