我最近对战略模式进行了真实的使用。我发现自己有锤子/钉子综合症,这种模式是我的锤子,其他一切都是钉子。对于踢,我决定尝试通过策略模式实现FizzBuzz。现在,我知道这完全超过了杀戮。我已经看过它的各种Enterprise实现,但这是我自己的实现。
令我惊讶和高兴的是,这个练习提出了一个有趣的问题:是否有标准或其他模式与策略一起使用以帮助您选择使用哪一个?在下面的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";;
}
}
答案 0 :(得分:2)
由于(如你所知)战略模式对于这个问题来说太过分了,很难说什么是“好”或“坏”的设计。然而,我的直觉反应是将策略选择逻辑转移到策略中,如下所示:
class FizzBuzzFormatter : IOutputFormatter
{
public bool Handles(int value) { return value.IsDivisibleBy(15); }
public string Handle(int value) { return "FizzBuzz"; }
}
在可组合性方面,这可能会更好一些,但您仍需要确保按正确的顺序列出IOutputFormatters
。如果这个问题很小,你就可以逃避任何事情。对于一个更大的问题,你需要考虑并自己决定。
答案 1 :(得分: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");
如何设置格式化程序或设置哪个格式化程序可能是另一个对象的责任。