策略模式定义封装在通常称为Context的驱动程序类中的一系列算法,并使这些算法可互换。 它使算法易于互换,并提供了在特定时间选择适当算法的机制。
算法(策略)在运行时由客户端或上下文选择。 在与客户端交互期间,Context类处理所有数据。
战略模式的主要参与者如下:
- 策略–指定所有算法的接口。 该接口用于调用由ConcreteStrategy定义的算法。
- 上下文–维护对策略对象的引用。
- ConcreteStrategy –根据策略接口实际执行算法
现在,让我们看一下策略模式的具体示例,并查看如何使用lambda表达式对其进行转换。 假设我们有不同类型的税率来计算所得税。 根据提前还是延迟缴税,分别有回扣或罚款。 我们可以将此功能与不同方法封装在同一类中,但是如果将来需要进行其他一些税收计算,则需要对该类进行修改。 这不是一种有效的方法。 更改类的实现应该是最后的选择。
让我们通过使用策略模式来采取最佳方法。 我们将使用基本方法为“税收策略”建立界面:
public interface TaxStrategy {public double calculateTax(double income);
}
现在让我们定义正常所得税的具体策略。
public class PersonalTaxStrategy implements TaxStrategy {public PersonalTaxStrategy() { }@Overridepublic double calculateTax(double income) {System.out.println("PersonalTax");double tax = income * 0.3;return tax;}
}
PersonalTaxStrategy类符合TaxStrategy接口。 同样,让我们为延迟付款定义一种具体的策略,该策略会产生罚款。
public class PersonalTaxPenaltyStrategy implements TaxStrategy {public PersonalTaxPenaltyStrategy() { }@Overridepublic double calculateTax(double income) {System.out.println("PersonalTaxWithPenalty");double tax = income * 0.4;return tax;}
}
接下来,我们为预付税定义具体策略,以实现退税。
public class PersonalTaxRebateStrategy implements TaxStrategy {public PersonalTaxRebateStrategy() { }@Overridepublic double calculateTax(double income) {System.out.println("PersonalTaxWithRebate");double tax = income * 0.2;return tax;}
}
现在,让我们结合定义的所有类和接口,以利用策略模式的强大功能。 让main方法充当不同策略的上下文。 仅查看所有这些类的一个示例相互作用:
import java.util.Arrays;
import java.util.List;public class TaxStrategyMain {public static void main(String [] args) {//Create a List of Tax strategies for different scenariosList<TaxStrategy> taxStrategyList =Arrays.asList(new PersonalTaxStrategy(),new PersonalTaxPenaltyStrategy(),new PersonalTaxRebateStrategy());//Calculate Tax for different scenarios with corresponding strategiesfor (TaxStrategy taxStrategy : taxStrategyList) {System.out.println(taxStrategy.calculateTax(30000.0));}}
}
运行此命令可获得以下输出:
PersonalTax
9000.0
PersonalTaxWithPenalty
12000.0
PersonalTaxWithRebate
6000.0
它清楚地说明了如何通过使用适当的具体策略类别来计算不同的税率。 我试图将所有具体的策略(算法)组合在一个列表中,然后通过遍历该列表来访问它们。
到目前为止,我们所看到的只是标准策略模式,而且已经存在了很长时间。 在这些时候,函数式编程是新的流行语,可以在Java中对lambda表达式的支持下思考,事情可以做得不同吗? 实际上,由于策略接口就像一个功能接口,因此我们可以使用Java中的lambda表达式进行哈希处理。 让我们看看代码的样子:
import java.util.Arrays;
import java.util.List;public class TaxStrategyMainWithLambda {public static void main(String [] args) {//Create a List of Tax strategies for different scenarios with inline logic using LambdaList<TaxStrategy> taxStrategyList =Arrays.asList((income) -> { System.out.println("PersonalTax"); return 0.30 * income; },(income) -> { System.out.println("PersonalTaxWithPenalty"); return 0.40 * income; },(income) -> { System.out.println("PersonalTaxWithRebate"); return 0.20 * income; });//Calculate Tax for different scenarios with corresponding strategiestaxStrategyList.forEach((strategy) -> System.out.println(strategy.calculateTax(30000.0)));}
}
运行此命令可获得类似的输出:
PersonalTax
9000.0
PersonalTaxWithPenalty
12000.0
PersonalTaxWithRebate
6000.0
我们可以看到,使用lambda表达式会使具体策略的其他类变得多余。 您不需要其他课程; 只需使用lambda表达式指定其他行为。
- 可以从我的github存储库访问所有代码片段
翻译自: https://www.javacodegeeks.com/2016/01/java-8-lambda-expression-design-patterns-strategy-design-pattern.html