策略模式
感觉类似于桥接模式,只是具体区别还需要再研究
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,关系图如下
Strategy:策略(算法)抽象ConcreteStrategy: 各种策略的具体实现Context:策略的外部封装类,或者说策略的容器类,根据不同的策略执行不同的行为 ,策略是由外部环境决定的。
优点:1提供了管理相关算法的办法,策略类的等级结构定义了一个算法或行为族,恰当的用继承 可以把公共的代码转移到父类里面避免重复代码。 2 提供了可以替换继承关系的办法,继承可以处理多种算法或行为,如果不用策略模式,那么使用算法或者行为的环境就可能会有一些子类。每个子类提供 一个不同的算法或行为,但是这样一来算法或行为使用者就和算法本身混在一起。决定 使用哪种算法或算法蔡旭哪一种行为的逻辑就和算法逻辑混在一起,从而不吭呢再独立演化。继承使动态改变算法或行为变成不可能。 3 避免使用多重条件转移语句缺点: 1 客户端必须知道所有的策略类,并自行决定使用哪个策略类,这就意味着客户端必须理解这些算法区别,以便适时选择 恰当的算法类,换言之,策略模式只适用于客户端知道所有算法或行为的额情况 2策略模式会造成很多策略类,有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的。这样策略类实例可以被不同的客户端使用 换言之,可以使用享元模式来减少对象的使用
三个实例
实例一代码:
策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
一个接口 public interface ICalculator { public int calculate(String exp); } *****************************************************************************8 三个实现类: /** * 减法 */ public class Minus extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"-"); return arrayInt[0]-arrayInt[1]; } } *****************************************************************************8 /** * 加法 */ public class Plus extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"\\+"); return arrayInt[0]+arrayInt[1]; } } *****************************************************************************8 /** * 乘法 */ public class Multiply extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"\\*"); return arrayInt[0]*arrayInt[1]; } } *****************************************************************************8 //抽象类:辅助类 public abstract class AbstractCalculator { public int[] split(String exp,String opt){ String array[] = exp.split(opt); int arrayInt[] = new int[2]; arrayInt[0] = Integer.parseInt(array[0]); arrayInt[1] = Integer.parseInt(array[1]); return arrayInt; } } *****************************************************************************8 /** * 策略模式的决定权在用户,系统本身提供不同算法的实现, *新增或者删除算法,对各种算法做封装。 *因此,策略模式多用在算法决策系统中, *外部用户只需要决定用哪个算法即可。 */ public class MainCLass { public static void main(String[] args) { String exp = "2+8"; ICalculator iCalculator = new Plus(); int result = iCalculator.calculate(exp); System.out.println(result); } } 测试结果: 10
实例二:
public interface Strategy { //加密算法 public void encrypt(); } **************************************************** public class MdD5Strategy implements Strategy { @Override public void encrypt() { System.out.println("使用MD5加密"); } } **************************************************** public class AESStrategy implements Strategy { @Override public void encrypt() { System.out.println("使用AES加密"); } } **************************************************** public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void encrypt() { strategy.encrypt(); } } **************************************************** /** * 根据传入不同的算法去执行不同的算法 * */ public class MainClass { public static void main(String[] args) { //具体实现从这里new出来传进去,然后执行具体实现的策略 Strategy strategy = new MdD5Strategy(); Context context = new Context(strategy); context.encrypt(); Strategy strategy1 = new AESStrategy(); Context context1 = new Context(strategy1); context1.encrypt(); } } **************************************************** 测试结果: 使用MD5加密 使用AES加密实例三:
public interface Strategy { public double coust(double num); } ************************************************* /** * 打八折 * */ public class StrategyA implements Strategy{ @Override public double coust(double num) { return num*0.8; } } ************************************************* /** * 满200减50活动 */ public class StrategyB implements Strategy{ @Override public double coust(double num) { if(num >= 200){ return num -50; } return num; } } ************************************************* public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public double con(double num){ return strategy.coust(num); } } ************************************************* 测试结果: 160.0 /** * 根据不同的价格执行不同的促销活动 * */ public class MainCLass { public static void main(String[] args) { Strategy strategy = new StrategyA(); //实际策略是从这里传进去的 Context context = new Context(strategy); double result = context.con(200); System.out.println(result); } }
总结:
在接口实现中具体实现策略,用接口父类调用,实际执行子类中的代码。
一切的设计模式都是类模式和对象模式,也就是继承或者持有对象引用来达到设计的目的。