一、概述
涉及多种算法,传统常用的方法是按硬编码,即将所有算法集中在一个类中,提供多个方法,每一个方法对应一个具体的算法;或者将算法封装在统一方法中,再通过if…else进行选择。对于维护代码及其不友好。
策略模式用于算法的自由切换与扩展。定义一系列的算法,将每一个算法封装起来,并让它们可以相互替换,同时让算法可以独立于使用它的客户而变化。简而言之,策略模式就是定义一些独立的类来封装不同的算法,并提供一个这些算法的抽象类来让使用时具有一致性。
二、结构与实现
- 结构
(1)AbstractStrategy:
抽象策略类,声明抽象方法。
(2)ConcreteStrategy :
具体策略类实现抽象策略类的方法。
(3)Context:
环境类是使用算法的角色,它在解决某个问题时可以采用多种策略,在环境类中维持一个对抽象策略类的引用实例。
- 实现
public abstract class AbstractStrategy{
public abstract void algorithm();
}
public class ConcreteStrategy(){
public void algorithm(){
//算法A
}
}
public class Context{
private AbstractStrategy strategy;
public void setStrategy(AbstractStrategy strategy){
this.strategy=strategy;
}
//调用策略类中的算法
public void algorihm(){
strategy.algorihm();
}
}
三、应用案例
- 分析
MovieTicket充当环境类角色,Discount充当抽象策略角色,StudentDiscount、ChildrenDiscount、VIPDiscount充当具体策略角色。
-
类图
-
代码实现
public class client {
public static void main(String[] args) {
MovieTicket ticket = new MovieTicket();
ticket.setPrice(100.00);
ticket.setDiscount(new StudentDiscount());
System.out.println("票价:"+ticket.getPrice());
}
}
abstract class Discount{
public abstract double calculate(double price);
}
class StudentDiscount extends Discount{
private final double DISCOUNT=0.8;
@Override
public double calculate(double price) {
System.out.println("学生票:");
return price*DISCOUNT;
}
}
class ChildrenDiscount extends Discount{
private final double DISCOUNT=10;
@Override
public double calculate(double price) {
System.out.println("儿童票:");
if(price>20){
return price-DISCOUNT;
}else {
return price;
}
}
}
class VIPDiscount extends Discount{
private final double DISCOUNT=0.5;
@Override
public double calculate(double price) {
System.out.println("VIP票:");
System.out.println("增加积分!");
return price*DISCOUNT;
}
}
class MovieTicket{
private double price;
public void setPrice(double price) {
this.price = price;
}
private Discount discount;
public void setDiscount(Discount discount){
this.discount=discount;
}
public double getPrice(){
return discount.calculate(price);
}
}
四、总结
- 策略模式用于算法的自由切换和扩展。对应于解决某一问题的一个算法族,允许用户从该算法族中任选一个算法来解决某一问题,同时可以方便地更换算法或者增加新的算法,只要涉及算法地封装、复用和切换都可以考虑。
- 环境类维护一个对抽象策略类的引用,以方便调用具体策略者的方法。