今天要写的是策略模式:
应用场景:算法不断变化,此模式会让算法的变化不影响到使用算法的客户,比如说商场系统,打折,促销,满减等等,算法非常多的场景。
应该记住的关键句子:
1.策略模式封住了变化(业技术封装了算法)
2.只要在分析过程中听到需要在不同的时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性
3.在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象
4.策略模式能减少算法类和使用类之间的耦合
结构图:
模式组成:
环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。
具体实现:
有这么一个场景:一个战士要上战场打仗,他用什么兵器呢?刀,剑,大炮?都可以,这样我们就可以将Strategy类抽象成武器类,这个类是抽象类(is的关系),刀,剑,大炮都是武器的子类,他们都有战斗的用途,而Context就是战士,他根据武器传递过来的Strategy类来战斗,具体传递进入哪个就是客户端的选择了,这样有一个缺点就是客户端要知道所有的算法(在这里就是所有的武器),不管怎么样,这点缺点不能掩盖策略模式的优点,好了下面上代码:
1.抽象策略类
/**
* 定义抽象策略类
*
*/
public abstract class IStrategy {
abstract void fighting();
}
2.具体策略类
大炮类:
public class Gun extends IStrategy{
@Override
void fighting() {
System.out.println("用炮在战斗!!!");
}
}
刀类:
public class Knife extends IStrategy{
@Override
void fighting() {
System.out.println("用刀在战斗!!!");
}
}
剑类:
public class Sward extends IStrategy{
@Override
void fighting() {
System.out.println("用剑在战斗!!!");
}
}
环境类(上下文类):
public class ContextStrategy {
IStrategy strategy;
public ContextStrategy(IStrategy strategy){
this.strategy = strategy;
}
public void contentInterface(){
strategy.fighting();
}
}
测试类:
public class StrategyTest {
public static void main(String[] args){
ContextStrategy cs = new ContextStrategy(new Gun());
cs.contentInterface();
ContextStrategy css = new ContextStrategy(new Knife());
css.contentInterface();
ContextStrategy csss= new ContextStrategy(new Sward());
csss.contentInterface();
}
}
测试结果:
用炮在战斗!!!
用刀在战斗!!!
用剑在战斗!!!