一、为什么我要学习设计模式。
我的上一个项目是做App接口,由于时间紧,老板催的急,所以到最后项目完工时发现居然写了几万行代码,可想而知代码质量有多糟糕。而且很多时候,调用接口的开发人员来找我说某个接口出错了,我回去调试一看才发现果然粗心写错一句代码,然而有六七个控制器里面我都有同样的语句,这就造成了我要回去查找那六七个文件,然后挨个修改。这下就傻眼,突然发现我真的应该看看设计模式了,这样可以提高代码质量,客户修改需求的时候也不至于让自己咬牙切齿(大家应该都有这种体会,哈哈);
二、策略模式
1.概念
策略模式:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。(概念太难理解)
2.为什么会有策略模式
joe上班的公司做了一套模拟鸭子的游戏,游戏中会出现各种鸭子,有的会呱呱叫,有的会飞。
代码:
<span style="color: #008080;"> 1</span> <span style="color: #000000;">php </span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Duck { </span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> quack(){} </span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> swim(){} </span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> display(){}<br> public function fly(){<br> //会飞了<br> } </span><span style="color: #008080;"> 6</span> <span style="color: #008000;">//</span><span style="color: #008000;">鸭子的其他方法 </span> <span style="color: #008080;"> 7</span> <span style="color: #000000;">} </span><span style="color: #008080;"> 8</span> <span style="color: #008080;"> 9</span> <span style="color: #0000ff;">class</span> MallarDuck <span style="color: #0000ff;">extends</span><span style="color: #000000;"> Duck{ </span><span style="color: #008080;">10</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> display(){ </span><span style="color: #008080;">11</span> <span style="color: #008000;">//</span><span style="color: #008000;">外观是绿头</span> <span style="color: #008080;">12</span> <span style="color: #000000;"> } </span><span style="color: #008080;">13</span> <span style="color: #000000;">} </span><span style="color: #008080;">14</span> <span style="color: #0000ff;">class</span> RedDuck <span style="color: #0000ff;">extends</span><span style="color: #000000;"> Duck{ </span><span style="color: #008080;">15</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> display(){ </span><span style="color: #008080;">16</span> <span style="color: #008000;">//</span><span style="color: #008000;">外观是红头</span> <span style="color: #008080;">17</span> <span style="color: #000000;"> } </span><span style="color: #008080;">18</span> }
这样继承了Duck类的子类都可以实现飞行行为,但是如果玩具鸭就不能有飞行行为的话不是闹笑话了么? 有的人会说,我可以在子类里面重写父类的fly方法,这样就可以针对不同的具体子类给予不同的行为。但是这样的话,不是重复很多代码了吗?相信大家会直接copy,这样如果某一个地方出错,所有地方都要重新更改,而且老板随时改变需求,我们会被直接累趴。
所以设计模式里的原则来了:
1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
2.针对接口编程,而不是针对实现编程。
3.多用组合,少用继承。
三、具体代码
<span style="color: #000000;">php </span><span style="color: #0000ff;">abstract</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Duck { </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$flyBehavior</span>; <span style="color: #008000;">//</span><span style="color: #008000;">飞行行为</span> <span style="color: #0000ff;">public</span> <span style="color: #800080;">$quackBehavior</span>; <span style="color: #008000;">//</span><span style="color: #008000;">叫行为</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> swim(){ </span><span style="color: #0000ff;">echo</span> '鸭子会游泳'<span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> performQuack(){ </span><span style="color: #800080;">$this</span>->quackBehavior-><span style="color: #000000;">quack(); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> performFly(){ </span><span style="color: #800080;">$this</span>->flyBehavior-><span style="color: #000000;">fly(); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setFlyBehavior(FlyBehavior <span style="color: #800080;">$fb</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>->flyBehavior = <span style="color: #800080;">$fb</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setQuackBehavior(QuackBehavior <span style="color: #800080;">$qb</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>->quackBehavior = <span style="color: #800080;">$qb</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">abstract</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> display(); } </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> FlyBehavior { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> fly(); } </span><span style="color: #0000ff;">class</span> FlyWithWings <span style="color: #0000ff;">implements</span><span style="color: #000000;"> FlyBehavior{ </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> fly(){ </span><span style="color: #0000ff;">echo</span> '会飞'<span style="color: #000000;">; } } </span><span style="color: #0000ff;">class</span> FlyNoWay <span style="color: #0000ff;">implements</span><span style="color: #000000;"> FlyBehavior { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> fly(){ </span><span style="color: #0000ff;">echo</span> '不会飞'<span style="color: #000000;">; } } </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> QuackBehavior { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> quack(); } </span><span style="color: #0000ff;">class</span> Quackd <span style="color: #0000ff;">implements</span><span style="color: #000000;"> QuackBehavior { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> quack(){ </span><span style="color: #0000ff;">echo</span> '呱呱叫'<span style="color: #000000;">; } } </span><span style="color: #0000ff;">class</span> Squeak <span style="color: #0000ff;">implements</span><span style="color: #000000;"> QuackBehavior { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> quack(){ </span><span style="color: #0000ff;">echo</span> '吱吱叫'<span style="color: #000000;">; } } </span><span style="color: #0000ff;">class</span> MuteQuack <span style="color: #0000ff;">implements</span><span style="color: #000000;"> QuackBehavior { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> quack(){ </span><span style="color: #0000ff;">echo</span> '不会叫'<span style="color: #000000;">; } } </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 模型鸭类 </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">class</span> ModelDuck <span style="color: #0000ff;">extends</span><span style="color: #000000;"> Duck { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> __construct() { </span><span style="color: #800080;">$this</span>->flyBehavior = <span style="color: #0000ff;">new</span><span style="color: #000000;"> FlyNoWay(); </span><span style="color: #800080;">$this</span>->quackBehavior = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Quackd(); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> display() { </span><span style="color: #0000ff;">echo</span> '模型鸭'<span style="color: #000000;">; } } </span><span style="color: #008000;">//</span><span style="color: #008000;">测试代码</span> <span style="color: #800080;">$m</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> ModelDuck(); </span><span style="color: #800080;">$m</span>-><span style="color: #000000;">display(); </span><span style="color: #800080;">$m</span>-><span style="color: #000000;">performQuack(); </span><span style="color: #800080;">$m</span>-><span style="color: #000000;">performFly(); </span><span style="color: #800080;">$m</span>->setFlyBehavior(<span style="color: #0000ff;">new</span><span style="color: #000000;"> FlyWithWings()); </span><span style="color: #800080;">$m</span>->performFly();
最后,设计模式是一种思想,不必生搬硬套,要不然只能适得其反。