以下为策略模式详解:

引子:

使用策略就是要实现可扩展性,那么多态是不可少的。何谓可扩展性呢?

比如:我们用面向对象的思想来设计飞机,基类为飞机,飞机可以有很多种,客机,直升机,战斗机等,不同种类的飞机起飞方式和武器都不一样,那么在设计时怎样才能做到支持所有的飞机,每次加入新的种类的飞机时不要去改动之前的代码直接加入呢?

这就是我们使用策略模式要考虑的问题,如果只用继承,显然不行,这样太死板,像客机它是没有武器的,当在基类中加入了使用武器方法后,客机也具有了武器,这不科学,而且直升机和战斗机的武器不同还要强迫每一个子类都复写使用武器方法。只用接口呢?也是不行的,比如写一个武器接口,只面有一个使用武器的方法,谁需要安装武器就实现这个接口,这样好像比继承要好一点,但有没有发现,代码的可重用性太差,重复代码会变多,一样不科学。如果我们在写代码时达到不必知道子类的具体类型,只要系统在使用武器时知道使用何种武器,那么这个问题就可以解决,怎么做到呢?

针对超类型编程,父类的引用指向子类的对像,这样就我们就可以驱动必不可少的多态。

我们可以这样设计:先设置几个接口,轻武器接口,重武器接口,缓冲起飞接口,垂直起飞接口(完整代码在最后在下载地址):

/**
* @author Homg
*/
public interface Weapon {
void fire();
} /**
* @author Homg
*/
public interface TakeOff {
void takeOff();
}

在基类中加入行为变量,申明为对应接口类型,在使用武器和起飞时委托给实例变量引用的对象来具体处理:

private TakeOff takeOff;
private Weapon weapon; public void fire() {
if (weapon != null) {
weapon.fire();
}
} public void takeOff() {
if (takeOff != null) {
takeOff.takeOff();
}
}

然后子类(战斗机或客机)如果需要起飞和使用武器就要给对应的行为变量赋值,也就是实例化这个继承而来的行为变量。还有个问题就是飞机有可能需要灵活的更换武器系统啊,那怎么办?我们可以这样设计:使用set方法来随时,灵活的改变接口类型的实例变量,当要换武器时只需要set一下就好:

public void setTakeOff(TakeOff takeOff) {
this.takeOff = takeOff;
}public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}

入口为这样:

            CopterTakeOff copterTakeOff=new CopterTakeOff();
CopterWeapon copterWeapon =new CopterWeapon(); Plane plane=new Copter();
plane.setTakeOff(copterTakeOff);
plane.setWeapon(copterWeapon);
plane.sayName();
plane.takeOff();
plane.fire();

运行结果:

我是直升机,垂直起飞,使用30毫米机炮开火

入口换成这样:

            PassengerPlaneTakeOff passengerPlaneTakeOff=new PassengerPlaneTakeOff();

            Plane plane2=new PassengerPlane();
plane2.setTakeOff(passengerPlaneTakeOff);
plane2.sayName();
plane2.takeOff();
plane2.fire();

运行结果:
   我是客机,滑动起飞,

客机是没有武器的,所以没有使用武器开火。

类图:

应用:

想一下,java封装的Comparator,是不是也用的策略模式?我们先要实现一个comparator接口,再把他传入Collections.sort(List<T>list,Comparator<? superT> c)中。

还有android中的异步处理(AsyncTask),使用回调接口,这是不是也是策略模式?

总结:

这就是策略模式,定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

分离出可能变化的部分,用一个处理器来处理这些变化,降低系统耦合度,不会牵一发而动全身。

在设计时要多用组合,少用继承,组合建立的系统有很大的弹性,不仅可将算法族封装成类,更可以在运行时动态地改变行为,只要组合的行为对象符合正确的接口标准即可。

完整代码下载地址(也可以留下邮箱发给你):

http://download.csdn.net/detail/homg92/6792431

OO之策略模式的更多相关文章

  1. 学C#之设计模式系列笔记(1)策略模式

    一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...

  2. [Head First设计模式]策略模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  3. HeadFirst设计模式之策略模式

    什么是策略模式:它定义了一系列算法,可以根据不同的实现调用不同的算法 大多数的设计模式都是为了解决系统中变化部分的问题 一.OO基础 抽象.封装.多态.继承 二.OO原则 1.封装变化,如把FlyBe ...

  4. Java设计模式(学习整理)---策略模式

       1. 模式定义         把会变化的内容取出并封装起来,以便以后可以轻易地改动或扩充部分,而不影响不需要变化的其他部分: 2.模式本质:  少用继承,多用组合,简单地说就是:固定不变的信息 ...

  5. 【HeadFirst 设计模式总结】1.策略模式

    1.书中举了一个鸭子类的设计,有些会飞或者会叫,有些不会飞可能也不会叫,用继承则导致不该有的功能通过继承而继承了下来,使用接口则代码无法做到最大程度的重用.进而引出设计原则1:找出应用中可能需要变化之 ...

  6. HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)

    策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...

  7. 第21章 策略模式(Strategy Pattern)

    原文 第21章 策略模式(Strategy Pattern) 策略模式 导读:策略模式看完之后,大多数人都会感觉有点混了,包括我,感觉策略模式是一种OO思想的体现(纯属个人拙见). 概述:       ...

  8. headfirst设计模式(1)—策略模式

    什么是策略模式 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化(摘自百度百科) 关键字:算法封装,相互替换,独立变化 算法封装 ...

  9. Java的设计模式----strategy(策略模式)

    设计模式: 一个程序员对设计模式的理解: “不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开 ...

随机推荐

  1. 关于JDK中正则表达式

    正则表达式的构造摘要 构造 匹配     字符 x 字符 x \\ 反斜线字符 \0n 带有八进制值 0 的字符 n (0 <= n <= 7) \0nn 带有八进制值 0 的字符 nn ...

  2. C#控制台程序 使用 Server.MapPath,

    (1)添加引用 System.Web. (2)在类中填写 using System.Web 命名空间. (3)写法为: System.Web.HttpContext.Current.Server.Ma ...

  3. link与@import区别

    1. link属于XHTML标签,@import是css提供的. 2.link在页面加载时加载,@import引用的css等到页面被加载完加载. 3.@import只在IE5以上可用,link无兼容问 ...

  4. http协议的总结说明

    关于http协议已经有很多大牛们的讨论,从他们的文章中获益匪浅,作为一个通信专业的学生,还是想从计算机网络的角度谈一下自己的认识.http协议全称超文本传输协议,是一种允许将超文本标记语言(HTML) ...

  5. 【Cocos2d入门教程七】三分钟看懂Cocos2d坐标系

    无论是搞2d还是3d开发,最需要搞清楚的就是坐标系,这部分混乱的话就没啥搞头了.所以玩cocos2d,一上来就需要先把各种与坐标有关的东西搞清楚. 1.OpenGL坐标系 Cocos2d-x使用的是O ...

  6. C# WCF学习笔记(二)终结点地址与WCF寻址(Endpoint Address and WCF Addressing) WCF中的传输协议

    URI的全称是 Uniform Rosource Identifire(统一资源标识),它唯一标识一个确定的网绐资源,同时也表示资源所处的位置及访问的方式(资源访问所用的网络协议). 对于Endpoi ...

  7. C# 中控件 WebBrowser 对 frameset/ iframe 操作和内容获取

    1.获取frame的document HtmlDocument htmlDoc = webBrowser1.Document;  htmlDoc = webBrowser1.Document.Wind ...

  8. iMAC——查看开机关机时间

    每次下班都记不好早上几点打的卡,你是不是也经常有这样的情况:  那就用以下的代码考到Mac电脑的终端中,回车: mac终端输入上面命令行 查看开机时间: last | grep reboot 查看关机 ...

  9. CodeSmith Template Model Output

    背景:上学那会儿就接触CodeSmith,是一款非常优秀的代码自动生成工具.以前写过好些基本模版,可惜早不知道扔到哪儿去了,如今只能重新开始,把它捡回来,加油. 效果:将数据库 DataBase 应用 ...

  10. 【转载】学习C++和编程的几个要点

    1.把C++当成一门新的语言学习(和C没啥关系!真的.):2.看<ThinkingIn C++>,不要看<C++变成死相>:3.看<The C++ Programming ...