OO之策略模式
以下为策略模式详解:
引子:
使用策略就是要实现可扩展性,那么多态是不可少的。何谓可扩展性呢?
比如:我们用面向对象的思想来设计飞机,基类为飞机,飞机可以有很多种,客机,直升机,战斗机等,不同种类的飞机起飞方式和武器都不一样,那么在设计时怎样才能做到支持所有的飞机,每次加入新的种类的飞机时不要去改动之前的代码直接加入呢?
这就是我们使用策略模式要考虑的问题,如果只用继承,显然不行,这样太死板,像客机它是没有武器的,当在基类中加入了使用武器方法后,客机也具有了武器,这不科学,而且直升机和战斗机的武器不同还要强迫每一个子类都复写使用武器方法。只用接口呢?也是不行的,比如写一个武器接口,只面有一个使用武器的方法,谁需要安装武器就实现这个接口,这样好像比继承要好一点,但有没有发现,代码的可重用性太差,重复代码会变多,一样不科学。如果我们在写代码时达到不必知道子类的具体类型,只要系统在使用武器时知道使用何种武器,那么这个问题就可以解决,怎么做到呢?
针对超类型编程,父类的引用指向子类的对像,这样就我们就可以驱动必不可少的多态。
我们可以这样设计:先设置几个接口,轻武器接口,重武器接口,缓冲起飞接口,垂直起飞接口(完整代码在最后在下载地址):
/**
* @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之策略模式的更多相关文章
- 学C#之设计模式系列笔记(1)策略模式
一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...
- [Head First设计模式]策略模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- HeadFirst设计模式之策略模式
什么是策略模式:它定义了一系列算法,可以根据不同的实现调用不同的算法 大多数的设计模式都是为了解决系统中变化部分的问题 一.OO基础 抽象.封装.多态.继承 二.OO原则 1.封装变化,如把FlyBe ...
- Java设计模式(学习整理)---策略模式
1. 模式定义 把会变化的内容取出并封装起来,以便以后可以轻易地改动或扩充部分,而不影响不需要变化的其他部分: 2.模式本质: 少用继承,多用组合,简单地说就是:固定不变的信息 ...
- 【HeadFirst 设计模式总结】1.策略模式
1.书中举了一个鸭子类的设计,有些会飞或者会叫,有些不会飞可能也不会叫,用继承则导致不该有的功能通过继承而继承了下来,使用接口则代码无法做到最大程度的重用.进而引出设计原则1:找出应用中可能需要变化之 ...
- HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)
策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...
- 第21章 策略模式(Strategy Pattern)
原文 第21章 策略模式(Strategy Pattern) 策略模式 导读:策略模式看完之后,大多数人都会感觉有点混了,包括我,感觉策略模式是一种OO思想的体现(纯属个人拙见). 概述: ...
- headfirst设计模式(1)—策略模式
什么是策略模式 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化(摘自百度百科) 关键字:算法封装,相互替换,独立变化 算法封装 ...
- Java的设计模式----strategy(策略模式)
设计模式: 一个程序员对设计模式的理解: “不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开 ...
随机推荐
- angularjs页面传参
例如:路由配置如下: $stateProvider.state('admin.userList', { url: '/listUser?type&role', //参数必须先在 ...
- [改善Java代码]慎用动态编译
建议17: 慎用动态编译 //=========这篇博文暂时理解不透......... 动态编译一直是Java的梦想,从Java 6版本它开始支持动态编译了,可以在运行期直接编译.java文件,执行. ...
- hdu 2709 Sumsets
Sumsets Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- wap测试学习
注意要点 UI元素 修改源码 物理键操作(回车.确认) 焦点 习惯性操作(前进.后退.屏幕翻转和停止) 刷新 重启服务器 重启浏览器 异常关闭 书签 cookies/session 缓存 接口 URL ...
- html5 js os build
1.NodeJS6.6 install https://nodejs.org/en/ c:\nodejs>npm install -g grunt-cliC:\Users\police\Ap ...
- AES加密解密的例子小结
话不多说,先放上代码,一共有两个文件:AES.php(aes算法类文件)和aesDemo.php(应用实例文件),这里只贴出aesDemo.php,其他的看附件吧!aesDemo.php: 例子, ...
- iOS开发——Touch ID 指纹识别
项目中为了安全性,一般使用密码或iPhone手机的指纹识别Touch ID. 第一步,判断系统是否支持,iOS8.0及以上才支持. 第二步,判断手机是否支持,带Touch ID的手机iPhone5s及 ...
- JavaScript学习笔记(12)——JavaScript内置对象
1.Number Javascript只有一种数字类型,可以有小数也可以没有,也可以使用科学计数法. var z=123e-5; // 0.00123 JavaScript 不是类型语言.与许多其他编 ...
- OC6-网址分割
// // HtmlManger.h // OC6-网址分割 // // Created by qianfeng on 15/6/17. // Copyright (c) 2015年 qianfeng ...
- 高性能CSS(二)
避免CSS表达式 CSS表达式是动态设置CSS属性的强大(但危险)方法.Internet Explorer从第5个版本开始支持CSS表达式.下面的例子中,使用CSS表达式可以实现隔一个小时切换一次背景 ...