概括
策略模式 定义了一系列算法,把它们一个个封装起来,并且使他们可相互替换。本模式使得算法可独立于它的客户而变化。
概述
方法是类中最重要的组成部分,一个方法的方法体 由一系列语句构成 即一个方法的方法体是一个算法。在某些设计中,一个类的设计人员经常可能设计这样的问题 由于用户需求的变化,导致经常需要修改类中的某个方法体,即需要不断地改变算法。
如:连队类的实体中有3个人 我们希望调用lineup()方法使连队一从高到矮排列 使连队二从低到高排列 则需要将该方法分割出来 ,面向对象编程有个很好的设计原则“面对抽象编程”,该原则的核心就是将类中经常需要变化的部分分割出来,并将每种可能的变化对应交个抽象类的一个子类或实现接口的一个类去负责,从而让类的设计者不去关心具体实现,避免所涉及的类依赖于具体的实现
面对抽象编程,关键在于:
分割变化
如果每当用户有新的需求,就会导致修改类的某部分代码,那么就应该将这部分代码从该类中分割出去,使其和类中其他稳定的类是松耦合关系。即将每种变化对应交给抽象类的子类或实现接口的类去实现。这是“开-闭原则”的体现面向抽象设计类
即设计接口或抽象类 使其实现类或子类来实现经常需要改变的方法
如有新的需求 只要再加一个实现类或子类去实现对应需求即可。
策略模式是处理算法不同变体的一种成熟模式,策略模式通过接口或抽象类封装算法的标识,即在接口中定义一个抽象方法,实现该接口的类将实现接口中的抽象方法。策略模式把针对一个算法标识的一系列具体算法分别封装在不同的类中,使得个各类给出的具体算法可以相互替换。
UML图
策略模式中的三种角色
- 策略(Strategy):策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法
- 具体策略(ConcreteStrategy):实现策略接口中的类,给出了算法标识中的具体算法
- 上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。
适用情况
许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
优点
- 可以动态的改变对象的行为
- 满足“开-闭原则” 当有新策略加入时 不需要修改上下文的代码
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
- 策略模式将造成产生很多策略类
应用:清理房子
public class MyContext {
private MyStrategy strategy;
public MyContext(MyStrategy strategy) {
// TODO Auto-generated constructor stub
this.strategy = strategy;
}
public void cleanHouse(){
if(strategy != null)
strategy.cleanHouse();
}
public interface MyStrategy {
public void cleanHouse();
}
public class StrategyOne implements MyStrategy{
@Override
public void cleanHouse() {
// TODO Auto-generated method stub
System.out.println("我需要清理窗户");
}
}
public class StrategyTwo implements MyStrategy{
@Override
public void cleanHouse() {
// TODO Auto-generated method stub
System.out.println("我需要清理地板");
}
}
public class Test {
public static void main(String[] args) {
MyContext context1 = new MyContext(new StrategyOne());
MyContext context2 = new MyContext(new StrategyTwo());
context1.cleanHouse();
context2.cleanHouse();
}
}
运行结果:
我需要清理窗户
我需要清理地板