这个星期很闲,找了一本电子书head-first设计模式看,放假闲来无事整理一下内容,书很有意思,电子书在我上传的资源中可以下载。
策略模式:定义了算法假装,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
需求:在一个模拟鸭子的游戏中,有各种各样的鸭子
最开始设计:
/**
*鸭子的抽象类,定义了鸭子的一般行为 ,可以游泳,可以呱呱的叫,但是鸭子长得不一样
*因此留到具体的子类中实现
* @author Administrator
*/
public abstract class Duck {
public void quack(){
System.out.println("i can quack!");
}
public void swim(){
System.out.println("i can swim!");
}
public abstract void display();
}
/**
* 红色的鸭子
* @author Administrator
*/
public class RedDuck extends Duck {
@Override
public void display() {
System.out.println("i am redDuck");
}
}
/**
* 蓝色的鸭子
* @author Administrator
*/
public class BlueDuck extends Duck {
@Override
public void display() {
System.out.println("i am blueDuck!");
}
}
但是此时需要添加一种玩具鸭子,鸭子不能呱呱的叫,而只能学小鸡咯咯的叫,那么怎么办呢?
或许我们可以重写quack()方法,改变其行为
public class RubberDuck extends Duck {
@Override
public void quack(){
System.out.println("i can quack!咯咯咯");
}
@Override
public void display() {
System.out.println("i am rubberDuck");
}
}
如果有这么一系列的鸭子都只能咯咯咯的叫唤的话,那么就需要在每个类中重写该方法,造成了代码的重复。
设计原则:找出应用中可能会变化的地方,把他们独立出来,和那些不会变化的代码区别开来。也就是把会变化的部分提取出来单独封装,以便以后可以轻易的改动或扩展而不影响不需要变化的部分。
在本例中会变化的部分是鸭子的鸣叫方式,因此我们把该代码提取出来:
/**
*鸣叫方式
* @author Administrator
*/
public interface QuackBehavior {
void quack();
}
/**
* 咯咯的鸣叫
* @author Administrator
*/
public class QuackAsGeGe implements QuackBehavior{
@Override
public void quack() {
System.out.println("i can quack!咯咯咯");
}
}
/**
* 呱呱呱的鸣叫方式
* @author Administrator
*/
public class QuackAsGuaGua implements QuackBehavior {
@Override
public void quack() {
System.out.println("i can quack! 呱呱呱");
}
}
鸭子将叫唤的行为委托给其他的类进行处理
/**
*鸭子的抽象类,定义了鸭子的一般行为 ,可以游泳,可以叫唤,但是鸭子长得不一样
*因此留到具体的子类中实现
* @author Administrator
*/
public abstract class Duck {
private QuackBehavior quackBehavior;
public void quack(){
quackBehavior.quack();
}
public void swim(){
System.out.println("i can swim!");
}
public abstract void display();
public QuackBehavior getQuackBehavior() {
return quackBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
此时我们可以把鸭子的叫唤行为看做某种算法,我们可以扩展QuackBehaviour接口实现更多的算法,在运行过程中通过setQuackBehaviour()来设置使用的算法,在不改变类的情况下达到替换不同的算法的目的