1

私は最近、ストラテジーパターンを実際に使用しました。私は、このパターンが私のハンマーであり、他のすべてが釘であるハンマー/釘症候群に自分自身を見つけます。キックについては、戦略パターンを介してFizzBu​​zzを実装してみることにしました。今、私はこれが完全に殺し過ぎていることを知っています。さまざまなエンタープライズ実装を見てきましたが、これは私自身の実装です。

驚いたことに、この演習では興味深い質問がありました。使用するものを選択するのに役立つ戦略と組み合わせて機能する標準または別のパターンはありますか?以下のFizzBu​​zzStrategySelectorクラスでは、このロジックをFormat関数に配置しています。

明らかに、この実装は実用的ではありません...しかし、これらのFormatメソッドが実際に分解するための実際のロジックを持っていた場合はそうかもしれません。

ここでの私の基本的な質問はこれです:私はここで戦略パターンを正しく使用していますか?

class Program
{
    static void Main(string[] args)
    {
        FizzBuzzStrategySelector fizzBuzzFormatter = new FizzBuzzStrategySelector();

        for (int i = 1; i < 100; i++)
        {
            fizzBuzzFormatter.Format(i);
        }

        Console.ReadLine();
    }
}

public interface IOutputFormatter
{
    string FormatOutput(int value);
}

public class FizzBuzzStrategySelector
{
    public IOutputFormatter formatStrategy;

    public FizzBuzzStrategySelector() : this(new GeneralFormatter()) { }

    public FizzBuzzStrategySelector(IOutputFormatter fizzBuzzFormatStrategy) 
    {
        this.formatStrategy = fizzBuzzFormatStrategy;
    }

    public void Format(int value)
    {
        //THIS SEEMS LIKE A CODE SMELL. NOT SURE HOW TO WORK 
        //AROUND IT.
        if(value % 15 == 0)
            this.formatStrategy = new FizzBuzzFormatter();
        else if(value % 3 == 0 )
            this.formatStrategy = new FizzFormatter();
        else if(value % 5 == 0)
            this.formatStrategy = new BuzzFormatter();
        else
            this.formatStrategy = new GeneralFormatter();

        Console.WriteLine(this.formatStrategy.FormatOutput(value));
    }
}

public class GeneralFormatter : IOutputFormatter
{
    public string FormatOutput(int value)
    {
        return value.ToString();
    }
}

public class FizzBuzzFormatter : IOutputFormatter
{
    public string FormatOutput(int value)
    {
        return "FizzBuzz";
    }
}

public class BuzzFormatter : IOutputFormatter
{
    public string FormatOutput(int value)
    {
        return "Buzz";
    }
}

public class FizzFormatter : IOutputFormatter
{
    public string FormatOutput(int value)
    {
        return "Fizz";;
    }
}
4

2 に答える 2

2

(ご存知のように)戦略パターンはこの問題に対してやり過ぎなので、「良い」または「悪い」設計が何であるかを言うのは難しいです。ただし、私の直感的な反応は、次のように、戦略選択ロジックを戦略自体に移動することです。

class FizzBuzzFormatter : IOutputFormatter
{
    public bool Handles(int value) { return value.IsDivisibleBy(15); }

    public string Handle(int value) { return "FizzBuzz"; }
}

これは、構成可能性の点では少し優れているかもしれませんが、それでもIOutputFormatters 正しい順序でリストがあることを確認する必要があります。この小さな問題で、あなたは何でも逃げることができます。より大きな問題では、それについて考え、自分で決める必要があります。

于 2013-03-22T19:48:36.547 に答える
0

さまざまな出力フォーマッタは、戦略パターンの一部です。通常、フォーマッタを必要とするオブジェクトがあります。次に、フォーマッタを呼び出すことができます。

class Foo
{
   public IOutputFormatter Formatter {get;set;}
}

var foo = new Foo();
foo.Formatter = new GeneralFormatter();
Console.WriteLine(foo.formatter.FormatValue("one");

foo.Formatter = new FizzBuzzFormatter();
Console.WriteLine(foo.formatter.FormatValue("one");

フォーマッターがどのように設定されるか、またはどのフォーマッターが設定されるかは、別のオブジェクトの責任である可能性があります。

于 2013-03-22T19:54:00.627 に答える