0

ビジターパターンで単純な条件を処理する方法はあるのだろうか?

たとえば、次のコードがある場合、ビジター パターンをどのように適用できますか?

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

3 に答える 3

3

たぶん、責任の連鎖パターンを探していますか?

ボーナスを計算する必要があり、このようなものを使用するとしましょう

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;
    }
}
于 2013-01-31T14:09:16.090 に答える
1

Visitor パターンは、特に (抽象) スーパークラスのオブジェクトがあり、具体的な型に応じて特別なことをしたい場合に、さまざまなを区別するためのものです。つまり、キャスト テストで if-then-else の代わりに使用できます (使用する必要があります)。

Visitor パターンは、を区別するためのものではありません。

于 2013-01-30T21:24:33.380 に答える
0

特定の問題を解決するために使用されるパターン。ビジター パターンは、次の問題を解決します。オブジェクトを変更せずに、オブジェクトの (複合) 構造に新しい機能を追加します。それで、あなたの質問を言い換えさせてください-オブジェクトの構造と機能を追加せずに、オブジェクトの構造に新しい機能を追加するにはどうすればよいですか. ヴァイオリンで釘を打つようなものです。

覚えておいてください-最初に問題が発生します。次に、その問題を解決するパターンに進みます。その逆ではありません。

更新して、コードにどのような問題がありますか? コマンドとクエリの分離の原則に従っていません。同じメソッドがアクション (合計の変更) を実行し、呼び出し元に合計を返します。コードをより明確にするために、コマンドとクエリを分離しました。

public int Total { get; set; }

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

    if(x == 2)
    {
       Total = 200;
       return;
    }
}
于 2013-01-30T22:08:14.283 に答える