反复看了《Head First 设计模式》中的策越模式,终于对该模式有了些许了解。现将我对该模式的理解用文字表达如下:
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式的变化独立于使用算法的客户。它遵循了‘针对接口编程,而不是针对实现编程’、‘多用组合,少用继承’设计原则。策略模式十分有利于系统的扩展性,我们不用担心遇到任何改变,我们不需要修改代码中不需要变化部分,我们只需添加实现新功能的类即可。下面模拟鸭子应用来说明‘策略模式’:
首先对模拟鸭子应用进行分析,由于鸭子Duck是一个具体类,他有自己自己的属性和方法,但是不同的鸭子具有不同属性和方法。我们需要做的是找出鸭子中变化的部分抽取出来,即把变化部分独立出来、不要和那些不需要变化的代码混合在一起。
我们知道可以是各种类型的鸭子,比如绿头鸭子、红头鸭子、橡皮鸭、模型鸭,不同的鸭子类型的鸭子可以具有不同的行为,这里我们说绿头鸭子、红头鸭子会‘呱呱叫’、橡皮鸭会‘吱吱叫’、模型鸭会‘嘎嘎叫’,绿头鸭子、红头鸭子会扇着翅膀飞、橡皮鸭不会飞、也不会其他飞行技术、但会像小汽车一样跑,模型鸭会‘火箭式飞行’。有上述可见:鸭子的行为是会根据需求改变而改变的,因此我们需要把鸭子的行为抽取出来形成独立的一份。下面开始模拟鸭子应用:
package com.lfn.duck;
public abstract class Duck {
//飞行接口
FlyBehavior flyBehavoir;
//鸭子鸣叫接口
QuackBehavoir quackBehavoir;
//设置飞行值
public void setFlyBehavoir(FlyBehavior flyBehavoir) {
this.flyBehavoir = flyBehavoir;
}
//设置鸣叫值
public void setQuackBehavoir(QuackBehavoir quackBehavoir) {
this.quackBehavoir = quackBehavoir;
}
//鸭子构造方法
public Duck(){
}
//鸭子外观抽象方法
public abstract void display();
//鸭子鸣叫委托方法
public void performQuack(){
quackBehavoir.quack();
}
//鸭子飞行委托方法
public void performFly(){
flyBehavoir.fly();
}
//所有鸭子都会游泳
public void swim(){
System.out.println("All ducks float,even decoys!");
}
}
此类之所以这样设计是因为:鸭子的行为是动态的,假如把鸭子行为的具体实现放在鸭子类中,当鸭子行为发生改变的时候则必须修改鸭子类飞行、鸣叫方法的代码,会造成维护上的不方便,而且因为代码的修改还有可能引发新错误。因此在Duck 类中两个引用,并分别一鸭子行为接口、鸭子鸣叫接口声明。而特定的鸭子具有不同的外观,所以将它定义为一个抽象方法,每个继承Duck类的特定鸭子都会去实现外观方法,即display();
下面来编写鸭子的飞行接口FlyBehavior
public interface FlyBehavior{
//鸭子飞行方法
public void fly();
}
这样所有飞行类都会去实现这个飞行接口,而且由于已经实现了的飞行类是一个独立的类,所以可以被很好的复用。
//不会飞行的
public class FlyNoway implements FlyBehavoir{
public void fly(){
System.out.println("我是一只不会飞的鸭子!");
}
//会飞行的
public class FlyWithWings implements FlyBehavior{
public void fly(){
System.out.println("我是一只会飞的鸭子!");
}
}
//火箭式飞行
public class FlyRocketPowered implements FlyBehavior{
public void fly(){
System.out.println("我会火箭式飞行!");
}
}
..........
飞行行为实现类暂时告一段落,下面开始鸣叫行为实现,先创建鸣叫接口:
//鸣叫接口
public interface QuackBehavoir {
public void quack();
}
开始各种各样的鸣叫:
//鸭子“呱呱叫”叫
public class Quck implements QuackBehavoir {
public void quack() {
System.out.println("呱呱叫!");
}
}
//鸭子’吱吱叫‘
public class Squeak implements QuackBehavoir {
public void quack() {
System.out.println("吱吱叫!");
}
}
//鸭子’嘎嘎叫‘
public class CallQuck implements QuackBehavoir{
public void quack() {
System.out.println(" 嘎嘎叫! ");
}
}
.........
鸭子鸣叫种类暂时告一段落
下面我们来看具体的鸭子类吧
//绿头鸭
public class GreenDuck extends Duck{
public void display(){
System.out.println("我是绿头鸭");
}
}
//红头鸭
public class RedDuck extends Duck{
public void display(){
System.out.println("我是红头鸭");
}
}
//橡皮鸭
public class MDuck extends Duck{
public void display(){
System.out.println("我是橡皮鸭");
}
}
//模型鸭
public class ModelDuck extends Duck{
public void display(){
System.out.println("我是模型鸭");
}
}
........
下面我们测试鸭子的功能,以模型鸭为例:
public class Test{
public static void main(String args[])
{
Duck d = new ModelDuck();
//鸭子外观
d.display();
//设置鸭子飞行行为值
d.setFlyBehavoir(new FlyRocketPowered());
//鸭子正式飞行
d.performFly();
//设置鸭子鸣叫行为值
d.setQuackBehavoir(new CallQuck());
//鸭子会叫了
d.performQuack();
//鸭子在游泳
d.swim();
}
}
此文到此结束。请大家多多指教。
参考《Head First 设计模式》-------策略模式。