1 引例
1.1 引例描述
例题:模拟鸭子
各种颜色,各种不同动作,如飞,叫,游泳
1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;
2)鸭子哪些功能是会根据新需求变化的?叫声、飞行…
类图:
1.2 关键代码
1. 将动作抽象成接口
package simulateDuck.behavior.fly;
public interface FlyBehavior
{
void fly();
}
2. 定义具体动作
package simulateDuck.behavior.fly;
public class GoodFlyBehavior implements FlyBehavior
{
@Override
public void fly()
{
System.out.println("--Good Fly--");
}
}
package simulateDuck.behavior.fly;
public class NoFlyBehavior implements FlyBehavior
{
@Override
public void fly()
{
System.out.println("--No Fly--");
}
}
3. 抽象实体
package simulateDuck.Duck;
import simulateDuck.behavior.fly.FlyBehavior;
import simulateDuck.behavior.quack.QuackBehavior;
public abstract class Duck
{
FlyBehavior m_flyBehavior;
QuackBehavior m_QuackBehavior;
public Duck()
{
}
public void Fly()
{
m_flyBehavior.fly();
}
public void Quack()
{
m_QuackBehavior.quack();
}
public abstract void display();
public void setM_flyBehavior(FlyBehavior m_flyBehavior)
{
this.m_flyBehavior = m_flyBehavior;
}
public void setM_QuackBehavior(QuackBehavior m_QuackBehavior)
{
this.m_QuackBehavior = m_QuackBehavior;
}
public void swim()
{
System.out.println("~~im swim~~");
}
}
4. 具体实体
package simulateDuck.Duck;
import simulateDuck.behavior.fly.GoodFlyBehavior;
import simulateDuck.behavior.quack.GaGaQuackBehavior;
public class GreenHeadDuck extends Duck
{
public GreenHeadDuck()
{
m_flyBehavior=new GoodFlyBehavior();
m_QuackBehavior=new GaGaQuackBehavior();
}
@Override
public void display()
{
System.out.println("**Green Head**");
}
}
5. 入口
package Main;
import simulateDuck.Duck.Duck;
import simulateDuck.Duck.GreenHeadDuck;
import simulateDuck.Duck.RedHeadDuck;
import simulateDuck.behavior.fly.NoFlyBehavior;
import simulateDuck.behavior.quack.NoQuackBehavior;
public class SimulateDuck
{
public static void main(String[] args)
{
Duck greenHeadDuck=new GreenHeadDuck();
Duck redHeadDuck=new RedHeadDuck();
greenHeadDuck.display();
greenHeadDuck.Fly();
greenHeadDuck.Quack();
greenHeadDuck.swim();
System.out.println("****************************");
redHeadDuck.display();
redHeadDuck.Fly();
redHeadDuck.Quack();
redHeadDuck.swim();
System.out.println("******************************");
redHeadDuck.display();
redHeadDuck.setM_flyBehavior(new NoFlyBehavior());
redHeadDuck.Fly();
redHeadDuck.setM_QuackBehavior(new NoQuackBehavior());
redHeadDuck.Quack();
}
}
源码地址:
http://download.csdn.net/detail/kaikai_sk/9872006
2 原理
策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者。
总结一波:
1、分析项目中变化部分与不变部分
2、多用组合少用继承;用行为类组合,而不是行为的继承。更有弹性
3、设计模式有没有相应的库直接使用?有些库或框架本身就用某种设计模式设计的
4、如果找不到适用的模式怎么办
3 范例
用泛型取代条件分支的都可以看作是策略模式。
3.1 Spring Redis 的序列化器
public String addString(String k, String v) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.opsForValue().set(k, v);
}
3.2 java的Comparator接口
同样的排序算法,传入不同的comparator实现策略,会有不同的表现。