帮助战略模式

Ste*_*ers 10 c# design-patterns strategy-pattern

我一直在经历Head First Design Patterns(最近刚刚进入)并且我正在阅读关于策略模式的内容,我想到它可能是一种很好的方式来实现计算税收等的常用方法.我在工作中使用的特定对象,但我有一个问题.

这就是我的想法:

public interface ITax
{
    decimal ProvincialTaxRate { get; set; } // Yes, I'm Canadian :)
    decimal CalculateTax(decimal subtotal);
}

public SaskatchewanTax
{
    public decimal ProvincialTaxRate { get; set; }

    public SaskatchewanTax()
    {
        ProvincialTaxRate = new decimal(0.05f);
    }

    public decimal CalculateTax(subtotal)
    {
        return ProvincialTaxRate * subtotal + FederalTaxRate * subtotal;
    }
}

public OntarioTax
{
    public decimal ProvincialTaxRate { get; set; }

    public OntarioTax()
    {
        ProvincialTaxRate = new decimal(0.08f);
    }

    public decimal CalculateTax(decimal subtotal)
    {
        return ProvincialTaxRate * subtotal + FederalTaxRate * subtotal;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能已经注意到没有FederalTaxRate的声明,这就是我想要问的问题.应该去哪儿?

  • 将其传递给每个具体ITax的构造函数似乎是多余的,并且会允许不正确的行为(所有税务计算器必须共享完全相同的联邦税率).
  • 同样,创建ITax成员也会使它们不一致.

所有的税收计算器是否应该继承静态定义的其他类以及ITax?

public class TaxCalculator
{
    public static decimal FederalTaxRate = new decimal(0.05f);
}
Run Code Online (Sandbox Code Playgroud)

Pab*_*dez 22

我认为这是模式滥用的常见情况.

如果你检查两个"策略",他们确实完全相同.唯一改变的是ProvincialTaxRate.

我会把事情保持干燥并且不要过度使用这种模式(或任何其他模式),这里你获得了一点灵活性,但是你还有2个类别不会拉动他们的重量,可能你不会去需要这种灵活性.

当您学习新技术或洞察力时,这种情况很常见,您希望在任何地方应用它(它发生在我们每个人身上),即使这样做会损害代码的可读性和可维护性.

我的意见:保持简单

问候

编辑(回应作者对我的回答的评论)

我没有试图取笑你或任何人.这是一个常见的错误,我做了很多次,并且很难学习它,不仅是模式,还有花哨的框架,服务器,新的流行语技术,你的名字.

这本书的作者自己警告读者不要过度使用模式,这个答案中的赞成也清楚地表明了一些东西.

但如果由于某种原因你仍然想要实现这种模式,这是我的拙见:

  • 做一个超类两种策略,这会超是抽象的,而且应包含的孩子策略的共享率值(FederalTaxRate)

  • 继承并在每个子类中实现的抽象方法"计算"(在这里你会看到,这两种方法都是一样的,但让我们继续)

  • 尝试使每个具体的策略不变,总是赞成不变性,如约书亚布洛赫所说.为此,删除ProvincialTaxRate的setter并在其构造函数上指定值,或直接在其声明中指定.

  • 最后,我在StrategySuperclass中创建了一些静态工厂方法,以便您将客户端与实现或具体策略分离(现在很可能是受保护的类)

编辑II: 这是一个带有一些(伪)代码的牧师,使解决方案更加清晰

http://pastie.org/441068

希望能帮助到你

问候