head first 设计模式读书笔记 之 策略模式
作为一个php开发者,深知曾经很多程序员都鄙视php,为什么呢?因为他们认为php的语法是dirty的,并且由于开发者水平参差不齐导致php的代码更加乱上加乱,维护起来简直一坨shit一样。随着php加入了面向对象的阵型之后,很多开发者开始使用了oop思想来写代码,php也变得越来越标准,越来越规范。而其中,设计模式起到了不小的作用。最近老大找我谈话,说php这边的开发模块耦合度过高,代码感觉质量不高,想来一次代码重构行动。我对代码重构也是一知半解,而代码重构的基础就是去了解设计模式,于是我翻起了这本<<Head First 设计模式>>(经典书籍),开始学起了曾经认为没啥用的设计模式。
so,今天先来个开胃菜,写一个策略模式的简单笔记以及自己的理解先吧。
1、策略模式到底是个什么鬼
先来个官方解释吧:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。简单的来说吧,其实就是相当一个可以随时切换的类来提供给客户端使用。可能这么说久更抽象了,不要紧,就从例子慢慢来吧。
2、从代码去解释
其实说白了,策略模式可以说是类的一种行为。我们如果有过YII或者其他PHP框架的开发经验,我们可以了解到,这些框架都为我们提供了一个行为机制。何为行为?行为就是一个类可以随时拥有,可以随时删除和改变的东西。如同人的行为,我们的行为可以有打架、吃饭、讨论、跳广场舞,正常来说,这些行为我们并非天生俱来的,而是从外部获得的。反之,类的也是这样。那你可以说,我可以是天生的啊,我继承我的父母祖辈不可以么?好吧,满足你的心愿,我们就先看看继承吧,上代码:
// 父亲
class Father {
public function eat() {}
public function dance() {}
public function sayMyName() {}
} // 儿子1 小明
class Xiaoming {
public function eat() {
echo '喜欢吃西红柿炒鸡蛋';
} public function dance() {
echo '喜欢跳爵士舞';
} public function sayMyName() {
echo '小明';
}
} // 儿子2 小萌
class Xiaomeng {
public function eat() {
echo '喜欢吃土豆炒肉';
} // 抱歉,我不喜欢跳舞
// public function dance() {
// echo '喜欢跳爵士舞';
// } public function sayMyName() {
echo '小萌';
}
} $xiaoming = new Xiaoming();
$xiaomeng = new Xiaomeng(); $xiaoming->eat();
$xiaoming->dance(); $xiaomeng->eat();
$xiaoming->dance(); // 我明明不喜欢跳舞,还是会跳舞
可以明显看到继承的一个缺点就是,有些方法会强行“塞到”一个类之中,这样是不灵活,不健壮的,而且假如有一天小明突然喜欢吃“回锅肉”了,那岂不是又得改动小明类的eat方法,就不能动态去修改?
这个时候,以“组合为先”的策略模式就可以出手了,这个时候我们先写一个EatBehavior和DanceBehavior接口,代码如下:
interface EatBehavior {
public function eat();
}
interface DanceBehavior() {
public function dance();
}
然后,针对这个吃的和跳舞的行为接口,我们去做一系列不同的吃的和跳舞的行为类,代码如下:
class EatXiHongshiBehavior implements EatBehavior {
public function eat() {
echo '西红柿炒鸡蛋';
}
}
class EatTuDouBehavior implements EatBehavior {
public function eat() {
echo '土豆肉片';
}
}
class JuqShiBehavior implements DanceBehavior {
public function dance() {
echo '爵士舞';
}
}
class JieWuBehavior implements DanceBehavior {
public function dance() {
echo '街舞';
}
}
可以看到,我们这里有两个Eat行为和两个Dance行为,这时候,我们就可以去掉Father类的eat()和dance()了,此时,我们的父亲、小明、小萌这三个类就简化成这样了:
// 父亲
class Father {
// public function eat() {}
// public function dance() {}
public function addEatBehavior(EatBehavior $eb) {
$eb.eat();
}
public function addDanceBehavior(DanceBehavior $db) {
$db.dacne();
}
public function sayMyName() {}
} // 儿子1 小明
class Xiaoming { public function sayMyName() {
echo '小明';
}
} // 儿子2 小萌
class Xiaomeng { public function sayMyName() {
echo '小萌';
}
}
我们可以看到,我们的小萌已经不用强行集成跳舞行为了,而是可以有一个添加跳舞行为的方法,这样就自由多了!这个时候,如果我们想要小明学跳爵士舞的话,那么我们久用$xiaoming->addEatBehavior(new JuqShiBehavior()),想转行跳街舞的话我们就可以$xiaoming->addEatBehavior(new JieWuBehavior()),想学其他舞种的话就写多一个类继承DanceBehaivor接口就OK了!
这样做的好处就是灵活且能够动态切换组合类自身需要的功能,而不用硬继承父类的一切方法,细心的朋友发现addEatBehavior还是addDanceBehavior的参数类型都是一个接口类,这样做符合了设计模式的“为接口而编程,而非实现”的原则,这样我们就能多态的传入不同的吃的跳舞的行为类去让类获取这些功能了,这样随意组合拆分会让类和类更加松散。在框架中,我们利用行为就是等于使用了这种设计模式,所以在今后的开发中,我准备多去写写框架的行为类,然后把冗余重复的给提出成为行为,让不同的控制器随意组合,这样就能进一步解耦了。好了,这就是策略模式!
head first 设计模式读书笔记 之 策略模式的更多相关文章
- Head First 设计模式读书笔记(1)-策略模式
一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...
- HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)
策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...
- HeadFirst设计模式读书笔记之策略模式
1. 例子 1. 做一个鸭子模拟器,里面有很多不同的鸭子,有的可以游泳,有的可以睡觉,有的可以呱呱叫,一般套路是定义一个鸭子的超类,在 超类里定义睡觉,游泳,呱呱叫的方法,再让不同的鸭子子类继承这个超 ...
- 《JavaScript设计模式与开发实践》读书笔记之策略模式
1.策略模式 定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换 1.1 传统实现 根据工资基数和年底绩效来发送年终奖 var calculateBonus= function (perfo ...
- HeadFirst设计模式读书笔记(4)-工厂模式
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个.工厂方法让类把实例化推迟到子类. 所有工厂模式都用来封装对象的创建.工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象 ...
- HeadFirst设计模式读书笔记之工厂模式
1. 简单工厂 1. 你开了一家披萨店,点披萨的方法可能是这样: public Pizza orderPizza(String type) { Pizza pizza; if (type.equals ...
- Java 设计模式学习笔记1——策略模式(Duck例子)
0.假设现有工程(Duck)中遇到为类添加功能的问题,如何设计类添加新的功能? 1.利用继承提供的Duck(鸭子)的行为会导致哪些缺点? (1)代码在多个子类中重复 (2)很多男知道所有鸭子的全部行为 ...
- HeadFirst设计模式读书笔记--目录
HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...
- JavaScript设计模式与开发实践 - 策略模式
引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
随机推荐
- Asp.Net实现Http长连接推送
话说最新帮一个朋友搞智能家居方面的东西,做一个云平台.主要作用手机在局域网外环境时对手机客户端和智能网关中命令的互相转发. 目前已经有了一个稳定的Socket版本,但是考虑到以后的扩展和性能指标要改成 ...
- L10 PUtty+SSH 访问vncviewer
在Linux下配置一个VNC服务器,并设置2个用户,要求其中一个用户登录时不需要输入密码.然后在客户端使用ssh+vncview的方式访问. 安装tigervnc: 输入的密码是123456 连接服务 ...
- c#中的数据类型简介(枚举)
C#中的数据类型简介(枚举) 枚举的定义 根据MSDN上给出的定义,枚举是一个指定的常数集,其基础类型可以是除Char外的任何整型. 如果没有显式声明基础类型,则使用 Int32. Enum 是 .N ...
- 解决ul显示不在div中的问题
css样式 #banner { padding: 0px; } #banner ul { list-style: none; margin: 0px; padding: 0px; text-align ...
- Linux 安装Nginx详细图解教程
进入:/usr/java/nginx位置 下载nginx: wget http://nginx.org/download/nginx-1.8.0.tar.gz 下载openssl : wget htt ...
- C++ typedef与const
1.typedef 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间: typedef int INT; ...
- sql server 2008 索引
微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclustered index,也称非聚类索引.非簇集索引) 我们举例来 ...
- Git 操作常用命令
Git使用 1. git pull 更新服务器代码到本地a). git pull origin master是将origin这个版本库的代码更新到本地的master主分支 2. git push ...
- uvalive 6657 GCD XOR
//感觉太长时间没做题 好多基本的能力都丧失了(>_<) 首先大概是这样的,因为gcd(a,b)=c,所以a,b都是c的倍数,所以我们依次枚举a的值为2c 3c 4c......,a xo ...
- Spring、使用注解方式装配对象(@Resource、@Autowired)
使用手工注解方式有两种方式@Resource.@Autowired 首先,引入注解所使用的Jar包 :common-annotations.jar 然后在beans.xml中加入命名空间空间 xml ...