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设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
随机推荐
- 经典 SQL
经典sql 总结一些经常用到或碰到的SQL语句,希望能与大家分享,同时也希望大家能提供更多的精妙SQL语句..... 1.delete table1 from (select * from tab ...
- xml、txt、config的一些基本用法
先来测试一下xml的读取好了创建了一个student.xml的文件 <?xml version="1.0" encoding="UTF-8"?> & ...
- C++命名准则
总则:命名用英语,单词简单,明了.意义明确.过长的单词可以使用省略.一般是去掉元音字母形成省略.如果有通用的缩写,应该采用通用的缩写. 1.函数命名 1.1:全局函数:采用限定词+动词(+名词的原则) ...
- Android onSaveInstanceState()
我们知道,由于手机的内存问题,很容易造成切换activity之后上一个activity被回收的情况,虽然我们按下back按键的时候,还是能够回到上一个activity,但是此时我们并不是执行的onRe ...
- Maven管理Android项目1
maven-android-plugin网站:https://code.google.com/p/maven-android-plugin/wiki/GettingStarted android ...
- RSA—非对称加密算法
RSA:非对称加密算法加解密原理如下:已知:p,q,n,e,d,m,c其中:p与q互为大质数,n=p*q 公钥Pk(n,e):加密使用,是公开的 私钥Sk(n,d):解密使用,不公开 c:明文 m:密 ...
- 根据群ID和用户Id查询 + string QueryQunByUserIdAndQunId(int userId, int qunId) V1.0
#region 根据群ID和用户Id查询 + string QueryQunByUserIdAndQunId(int userId, int qunId) V1.0 /// <summary ...
- linux第七章《档案与目录管理》重点回顾
- C语言入门(15)——结构体与数据抽象
大多数的计算机运算是对现实世界的模拟,如果想用计算机来模拟现实世界需要用到数据抽象的方法.所谓抽象是从实际的人.物.事和概念中抽取所关心的共同特征,,忽略非本质的细节,吧这些特征用各种概念精确的加以描 ...
- StudentSchema student实例数据库环境搭建
环境搭建 查看默认表空间和临时表空间 select tablespace_name from dba_tablespaces: 创建用户 并给用户设置默认表空间和临时表空间 SQL> creat ...