这是使用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";;
}
}
因为(正如你所知道的)策略模式对于这个问题来说是过度的,所以很难说什么是"好"或"坏"的设计。然而,我的直觉反应是将策略选择逻辑转移到策略本身,就像这样:
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");
如何设置格式化器,或者设置哪个格式化器可以由另一个对象负责。