这是我在想什么:
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; } }
你可能已经注意到没有关于FederalTaxRate的声明,这就是我想要的.那应该去哪里?
>将其传递给每个具体ITax的构造函数似乎是多余的,并且将允许错误的行为(所有税务计算器必须共享完全相同的联邦税率).
>同样,创建ITax的成员也将使它们不一致.
所有税收计算器是否都继承自其他类别的静态定义以及ITax?
public class TaxCalculator { public static decimal FederalTaxRate = new decimal(0.05f); }
解决方法
如果你检查你的两个“策略”,他们做的也是一样的.唯一改变的是ProvincialTaxRate.
我会保持干燥,不要过度使用这种模式(或任何其他),在这里你可以获得一点灵活性,但是你也有2个类别,不会拉他们的重量,可能你不会需要灵活性.
当您学习新技术或洞察力时,您可以随时随地应用它(这是我们每个人都可以使用的),这是很常见的,即使这样做会损害代码的可读性和可维护性.
我的意见:保持简单
问候
我没有试图让你或任何人玩乐.这是一个常见的错误,我做了很多次,并且学到了难点,不仅仅是模式,而且还有花哨的框架,服务器,新的流行语技术,你命名它.
这本书的作者自己警告读者不要过度使用模式,而这个答案中的upvote也清楚地表明了一些.
但是,如果由于某种原因,你仍然想实现这种模式,这是我的谦虚的观点:
>为这两种策略制定一个超类,这个超类将是抽象的,应包含其子策略的共享速率值(FederalTaxRate)
>在每个子类中继承并实现抽象方法“Calculate”(这里你会看到两种方法都是一样的,但是让我们继续)
>尝试使每个具体的策略是不可变的,总是喜欢不变性,如Joshua Bloch所说.为此,请删除ProvitcialTaxRate的setter,并在其声明中直接指定其构造函数的值.
>最后,我将在StrategySuperclass中创建一些静态工厂方法,以便将客户端与实现或具体策略(可以非常好地保护类)脱钩,
希望有帮助
问候