就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户
--策略模式
在阅读本文之前你应该明白几个问题,不明白的请自行百度。。。
1.什么是组合?
2.什么是继承?
3.组合和继承的区别,以及两者的优势?
设计原则:
多用组合,少用继承
策略模式就是运用这个原则,组合 可以在运行过程中动态的改变对象的行为,而继承的话,对象的行为是编译时刻静态确定的。
了解了组合和继承,下面开始策略模式,首先让我们设想一个场景:大家都知道小狗吧,每只小狗都有几种行为,比如
a.叫声“汪汪~~”;
b.摇尾巴;
c.游泳;
.....
现在公司想开发一款关于小狗的app,让用户能收养各种小狗,类似于养成游戏,小狗的种类包括三大类:宠物狗,机器狗,玩具狗,其中机器狗不会游泳,玩具狗不会叫。
把这个任务交给你了,你会怎么设计它。。。
百分之百你会想到用继承吧,类似下面的类图:
如果是这样的设计,实现功能是没有问题了,但不能动态的改变狗的行为,因为狗的行为在编译时刻静态确定了,如果想让toyDog会叫,就不得不修改代码了,对不对。
那要怎样修改呢,这时候就体现到组合的魔力了,首先根据oo设计原则将可变的部分和不可变的部分分开,dog项目里可变的部分是:叫(bark),游泳(swimming),不变的是摇尾巴(wagTail),那么就将可变的封装成接口,dog类只针对接口编程,而不是针对具体实现(思考一下为什么针对接口编程?)
通过组合让对象可以动态的切换自己的行为,下来看一下具体代码实现
barkInterface接口:
public interface barkInterface
{
void bark();
}
swimmingInterface接口:
public interface swimmingInterface
{
void swimming();
}
//正常的狗叫声“汪汪”
public class barkNomal implements barkInterface
{
@Override
public void bark()
{
System.out.println("汪汪");
}
}
//不会叫的狗的声音
public class barkSilent implements barkInterface
{
@Override
public void bark()
{
System.out.println("无声");
}
}
//具体的狗的类,通过dog实例化狗的对象
public class dog
{
private barkInterface m_bark;
private swimmingInterface m_swimming;
public dog()
{
m_bark = null;
m_swimming = null;
}
public void setBark(barkInterface bark)
{
m_bark = bark;
}
public void setSwimming(swimmingInterface swimming)
{
m_swimming = swimming;
}
public void wagTail()
{
System.out.println("摇尾巴");
}
public void display()
{
if(m_bark != null)
{
m_bark.bark();
}
if(m_swimming != null)
{
m_swimming.swimming();
}
wagTail();
}
}
//现在看一下如何使用
public static void main(String[] args)
{
barkInterface barksilent = new barkSilent();
dog toyDog= new dog();//这就是我们需要的玩具狗,是不会叫的
toyDog.setBark(barksilent);
toyDog.display();
toyDog .setBark(new barkNomal());//动态改变玩具狗的行为,让它会叫
toyDog.display();
}
注:为了控制篇幅长度我只实现barkInterface,swimmingInterface自行实现