转载:https://blog.csdn.net/qq594913801/article/details/89204473
在策略模式中(Strategy pattern)中,一个类的行为或其算法可以在运行时更改。ex:出行旅游可以做飞机或火车、自行车或私家车等,超市可以采用打折、送礼品或积分的方法促销。
意图:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换
主要解决:在多种算法相似的情况下,使用if...else所带来的复杂和难以维护
何时使用:一个系统又许多许多类,而区分它们的只是它们直接的行为
如何解决:将这些算法封装成一个个的类,任意替换
关键代码:实现同一个接口
优点:算法可以自由切换 避免多重条件判断 扩展性好
缺点:策略类会增多 所有策略都要对外暴露
使用场景:如果在一个系统里面有许多类,它们之间的区别仅在与他们的行为,那么使用策略模式可以动态的让一个对象在许多行为中选择一个; 一个系统需要在动态的几种算法中选择一种; 如果一个对象有很多的行为,如果不恰当的模式,这些行为就只好使用多重条件选择语句来实现
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略膨胀的问题
策略模式的主要角色如下:
- 抽象策略类:定义了一个策略的公共接口,各种不同的算法要实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现
- 具体策略:实现了抽象策略定义的接口,提供具体的算法实现
- 环境类:持有一个策略类的引用,最终给客户端调用
实现:
/**
* 策略模式:超时促销的抽象类
*/
public interface SalesMethod {
public void method();
}
/**
* 策略模式:具体促销行为
*/
public class Discount implements SalesMethod {
@Override
public void method() {
System.out.println("打折");
}
}
/**
* 策略模式:具体促销行为
*/
public class SendGoods implements SalesMethod {
@Override
public void method() {
System.out.println("送商品");
}
}
/**
* 策略模式:具体促销行为
*/
public class Integral implements SalesMethod {
@Override
public void method() {
System.out.println("积分");
}
}
public class Test {
public static void main(String[] args) {
SalesMethod dicount = new Discount();//子类对象实列,强转后仍调用子类方法,子类独有的不能调用,出入强转回子类
SalesMethod sendGoods = new SendGoods();
SalesMethod ingegral = new Integral();
SalesContext context = new SalesContext();
context.setSalesMethod(dicount);
context.method();
context.setSalesMethod(sendGoods);
context.method();
context.setSalesMethod(ingegral);
context.method();
}
}
在一个使用策略模式的系统中,当存在的策略很多是时,客户端管理所有的策略算法将变得复杂,如果在环境类中使用策略工厂模式来管理这些策略类将大大减少客户端的工作复杂度。