这是使用FizzBuzz练习的策略模式的正确实现吗?

本文关键字:实现 模式 策略 FizzBuzz 练习 | 更新日期: 2023-09-27 18:05:27

我最近在实际中使用了Strategy模式。我发现自己有锤子/钉子综合症,这个模式是我的锤子,其他的都是钉子。为了刺激,我决定尝试通过策略模式实现FizzBuzz。现在,我知道这完全是过度杀戮。我见过它的各种企业实现,但这是我自己的实现。

令我惊讶和高兴的是,这个练习提出了一个有趣的问题:是否有一个标准或另一个模式与策略相结合,帮助你选择使用哪一个?在下面的FizzBuzzStrategySelector类中,我将此逻辑放入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";;
    }
}

这是使用FizzBuzz练习的策略模式的正确实现吗?

因为(正如你所知道的)策略模式对于这个问题来说是过度的,所以很难说什么是"好"或"坏"的设计。然而,我的直觉反应是将策略选择逻辑转移到策略本身,就像这样:

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

就可组合性而言,这可能稍微好一点,但是您仍然需要确保IOutputFormatters 的列表以正确的顺序排列。对于这么小的问题,你可以逃避任何事情。对于更大的问题,你需要考虑一下,然后自己决定。

不同的输出格式化程序是策略模式的一部分。通常会有一个对象需要格式化程序。然后你可以调用格式化器。

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

如何设置格式化器,或者设置哪个格式化器可以由另一个对象负责。