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设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
随机推荐
- ios百度地图不能定位问题
在IOS8中定位功能新增了两个方法: - (void)requestWhenInUseAuthorization __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE ...
- jQuery :lt()选择器
定义和用法 :lt() 选择器选取 index 值小于指定数字的元素.(不包含指定值) index 值从 0 开始.(从0开始计数) 最常见的用法:与其他选择器一起使用,选取指定组合中特定序号之前的元 ...
- C++中的操作符重载
一.什么是操作符重载 操作符重载可以分为两部分:“操作符”和“重载”.说到重载想必都不陌生了吧,这是一种编译时多态,重载实际上可以分为函数重载和操作符重载.运算符重载和函数重载的不同之处在于操作符重载 ...
- python正则表达式基础篇
1.正则表达式基础 1.1简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大 ...
- Android 尺寸 神图
- 前端开发面试题收集 css
什么是CSS盒子模型 页面上的每个元素都被浏览器看做是一个矩形的盒子. 由内容.填充.边框.边界组成. 什么是 css sprite 将多个图片拼接在一个图片中,通过background-positi ...
- Python练习_更改配置文件(3)
学习完成第三阶段,我们来写一个功能:也就是实现对配置文件的backend字段进行增删改查 1.查 输入:www.oldboy.org 获取当前backend下的所有记录 2.新建 输入: arg = ...
- VB MSFlexGrid 用法
http://blog.itpub.net/15453304/viewspace-445608/ 问题一,MSFlexGrid 点击一行,显示背景颜色,然后得到行号 首先,右键单击Msflexgrid ...
- 四轴飞行器1.2.1 RT-Thread 环境搭建
买的飞控板到了,开始写下位机的程序了,本来打算用UCOS的,因为以前用过,比较熟悉,可以很快上手,不过板子的卖家推荐了RT-Thread,以前虽然有接触过,但是没用过,于是去官网看了下,感觉还不错.其 ...
- ubuntu下C编程,编译基础( 转)
buntu下C编程,编译基础 C 编程中相关文件后缀 .a 静态库 (archive) .c C源代码(需要编译预处理) .h C源代码头文件 .i C源代码(不需编译预处理) .o 对象文件 ...