设计模式剖析系列之策略模式

By heiry on 2019-08-21 [ in 技术 ]

策略模式定义了一系列算法(算法族),各可以相互替换,客户端可根据实际情况选择使用哪一种算法,算法的变化不会影响使用算法的客户。

策略模式核心结构:

1.抽象策略接口或抽象类 Strategy:具体的策略的规范。

2.具体策略类 Concrete Strategy :抽象策略的实现类。

3. 上下文策略类 Context:持有一个策略类的引用,最终给客户端调用。

UML类图如下:

策略模式UML类图

下面我们以实例来理解策略模式的运用:

中国移动对不同客户群有不同的流量套餐,同样是50元套餐,普通用户可获得流量50G,全球通用户可获得100G,企业用户可获得200G,对,中国移动就是这么黑。营业厅办理业务时,根据用户不同类型,提供不同的流量策略。

 

package net.mosang.strategy;
/**
 * 抽象策略类
 * @author Heiry
 *
 */

public interface Strategy {
  public int getStrategy(int standardDataFlow); //标准手机流量
}
package net.mosang.strategy;
/**
 * 普通用户策略:50G/月
 * @author Heiry
 *
 */
public class standard implements Strategy {
  @Override
  public int getStrategy(int standardDataFlow) {
    System.out.println("普通用户,每月"+standardDataFlow+"流量。");
    return standardDataFlow;
  }
}
package net.mosang.strategy;
/**
 * 全球通用户策略:100G/月
 * @author Heiry
 *
 */
public class GSM implements Strategy {
  @Override
  public int getStrategy(int standardDataFlow) {
    System.out.println("全球通用户,每月"+standardDataFlow*2+"G流量。");
    return standardDataFlow*2;
  }
}
package net.mosang.strategy;
/**
 * 企业用户策略:200G/月
 * @author Heiry
 *
 */
public class Enterprise implements Strategy {
  @Override
  public int getStrategy(int standardDataFlow) {
    System.out.println("企业用户,每月"+standardDataFlow*4+"G流量。");
    return standardDataFlow*4;
  }
}
package net.mosang.strategy;
/**
 * 上下文类,用于策略切换和客户端调用;
 * 通过上下文类,算法与客户端类分离
 * @author Heiry
 *
 */

public class Context {
  private Strategy strategy ; //持有对具体策略的引用
  public void getStrategy(int i) {
    strategy.getStrategy(i); //调用具体策略
  }

  public Context(Strategy strategy) {
    this.strategy = strategy;
  }

  public Strategy getStrategy() {
    return strategy;
  }

  public void setStrategy(Strategy strategy) {
    this.strategy = strategy;
  }
  

}
package net.mosang.strategy;
/**
 * 客户端类
 * @author Heiry
 *
 */
public class Client {
  public static void main(String[] args) {
    int standardFlow = 50 ; //普通基础流量50G
    Strategy s1 = new GSM();
    Strategy s2 = new Enterprise();
    Strategy s3 = new standard();
    Context c1 = new Context(s1);
    c1.getStrategy(standardFlow);
    System.out.println("#####################################");
    Context c2 = new Context(s2);
    c2.getStrategy(standardFlow);
    System.out.println("#####################################");
    Context c3 = new Context(s3);
    c3.getStrategy(standardFlow);
  }
}

输出结果:

全球通用户,每月100G流量。
#####################################
企业用户,每月200G流量。
#####################################
普通用户,每月50流量。

 

通过以上实例,我们看到,策略模式避免了复杂策略而不可避免的庞大而难以维护的if…else判断,可以在不修改原代码的情况下,灵活增加新算法,符合开闭原则。

 >>



© 2009-2024 MOSANG.NET DESIGNED BY HEIRY