设计模式-策略模式

1.策略模式(Strategy Pattern)的适用场景

    策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

2.策略模式的特点

(1)策略模式是一种定义一系列算法的方法,从概念上看,所有的这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

(2)策略模式简化的单元测试,因每个算法都有自己的类,可以通过自己的接口单独测试。

(3)该模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到适用算法的客户。

3.策略模式适用注意

(1)分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。
原则就是:分离变化部分,封装接口,基于接口变编程实现各种功能。
(2)策略模式的注意点
a-分析项目中的变化部分与不变部分

b-多用组合少用继承,用行为类组合,而不是行为的继承,更有弹性

4.举例说明--模拟鸭子项目

(1)OO设计方式

需求分析:鸭子会叫、会游泳,但外观不一样

(2)新需求:要求鸭子会飞(可扩展性)


问题来了:超类的修改使得所有的鸭子都会飞,与实际不符(如:煮熟的鸭子不会飞)

继承带来的问题:对超类的局部改动,会影响其他部分,影响会有溢出效应

OO解决方式:子类中复写fly()方法-->工作量大,代码重复量大,不是一种好的设计方式

(3)策略模式-应对项目的扩展性,降低复杂度

**提取项目的变化部分,抽象成接口+实现

鸭子的哪些功能会根据需求变化?叫声、飞行...


Duck类:

package com.qiuyang.duck;

import com.qiuyang.strategy.behaviorInter.FlyBehavior;
import com.qiuyang.strategy.behaviorInter.QuackBehavior;
import com.qiuyang.strategy.behaviorInter.SwimBehavior;

public abstract class Duck {
	protected FlyBehavior flyBehavior;
	protected QuackBehavior quackBehavior;
	protected SwimBehavior swimBehavior;
	
	public void fly(){
		flyBehavior.fly();
	}
	public void quack(){
		quackBehavior.quack();
	}
	public void swim(){
		swimBehavior.swim();
	}
	public abstract void display();
}
Duck的子类:
package com.qiuyang.duck;

import com.qiuyang.strategy.behaviorImpl.FastSwimBehavior;
import com.qiuyang.strategy.behaviorImpl.FlyOKBehavior;
import com.qiuyang.strategy.behaviorImpl.GoodQuackBehavior;


public class GreenHeadDuck extends Duck{

	public GreenHeadDuck(){
		this.flyBehavior = new FlyOKBehavior();
		this.swimBehavior = new FastSwimBehavior();
		this.quackBehavior = new GoodQuackBehavior();
	}
	
	@Override
	public void display() {
		System.out.println("green head duck!");
	}
	
}

Main类:

package com.qiuyang.main;

import com.qiuyang.duck.Duck;
import com.qiuyang.duck.GreenHeadDuck;
import com.qiuyang.duck.RedHeadDuck;

public class Main {

	public static void main(String[] args) {
		Duck gd = new GreenHeadDuck();
		Duck rd = new RedHeadDuck();
		
		gd.fly();
		gd.swim();
		gd.quack();
		
		rd.fly();
		rd.swim();
		rd.quack();
	}

}

优点:新增行为简单,行为类更好的复用,组合更方便。如fly()方法各种鸭子表现不同,但又只有会飞和不会飞两种,故将行为fly抽象为借口,用两个实现类来表示会飞与不会飞,Duck类持有借口的引用,其子类GreenHeadDuck将超类中的引用实例化为会飞。新增一个子行为飞得慢,只需要再增加一个子类SlowFlyBehavior即可,以后新类(老鸭)在初始化flyBehavior引用时用new SlowFlyBehavior()即可,不会影响原来Duck/GreenHeadDuck/RedHeadDuck等类(添加fly的具体下属方式(飞的快慢)不会影响这些类,添加一个行为如跳跃这些会带来一点影响)。

5.模式总结

创建一个定义活动的 Strategy 接口和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。
StrategyPatternDemo,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化


public interface Strategy {
   public int doOperation(int num1, int num2);
}
//***********************************
public class OperationAdd implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 + num2;
   }
}

//**********************************
public class OperationSubstract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}

//*********************************
public class OperationMultiply implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 * num2;
   }
}

//********************************
public class Context {
   private Strategy strategy;

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

   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}

//使用 Context 来查看当它改变策略 //Strategy 时的行为变化。
//StrategyPatternDemo.java
//************************************
public class StrategyPatternDemo {
   public static void main(String[] args) {
      Context context = new Context(new OperationAdd());        
      System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

      context = new Context(new OperationSubstract());        
      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

      context = new Context(new OperationMultiply());        
      System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
   }
}

//*********************************
//输出:
//10 + 5 = 15
//10 - 5 = 5
//10 * 5 = 50


阅读更多
个人分类: 设计模式
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

设计模式-策略模式

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭