丁某 發表於 2019-7-4 09:14:00

PHP常用的 五种设计模式及应用场景

<p><strong>设计模式六大原则</strong></p>
<p>开放封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。</p>
<p>里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象.</p>
<p>依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。</p>
<p>单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。</p>
<p>接口隔离原则:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。</p>
<p>迪米特法则:一个对象应该对其他对象保持最少的了解。</p>
<p>&nbsp;</p>
<p>1.单例设计模式</p>
<p>所谓单例模式,即在应用程序中最多只有该类的一个实例存在,一旦创建,就会一直存在于内存中!</p>
<p>单例设计模式常应用于数据库类设计,采用单例模式,只连接一次数据库,防止打开多个数据库连接。</p>
<p>一个单例类应具备以下特点:</p>
<p>单例类不能直接实例化创建,而是只能由类本身实例化。因此,要获得这样的限制效果,构造函数必须标记为private,从而防止类被实例化。</p>
<p>需要一个私有静态成员变量来保存类实例和公开一个能访问到实例的公开静态方法。</p>
<p>在PHP中,为了防止他人对单例类实例克隆,通常还为其提供一个空的私有<code>__clone()</code>方法。</p>
<h4>使用场景:只实例化一次,内部实例化,对外只有一个开放方法,只能通过调取该方法进行调取实例化对象。数据库连接</h4>
<p>单例模式的例子:</p>
<pre><code><span><span>&lt;?php&nbsp;&nbsp;<br><br><span>/**&nbsp;<br>*&nbsp;Singleton&nbsp;of&nbsp;Database&nbsp;<br>*/&nbsp;&nbsp;<br><span><span>class&nbsp;<span>Database&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>//&nbsp;We&nbsp;need&nbsp;a&nbsp;static&nbsp;private&nbsp;variable&nbsp;to&nbsp;store&nbsp;a&nbsp;Database&nbsp;instance.&nbsp;&nbsp;<br>&nbsp;&nbsp;private static&nbsp;$instance;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>//&nbsp;Mark&nbsp;as&nbsp;private&nbsp;to&nbsp;prevent&nbsp;it&nbsp;from&nbsp;being&nbsp;instanced.&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>private&nbsp;function__construct()&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>//&nbsp;Do&nbsp;nothing.&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>private&nbsp;function__clone()&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>//&nbsp;Do&nbsp;nothing.&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span>static&nbsp;<span><span>function&nbsp;<span>getInstance<span>()&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>if&nbsp;(!(<span>self::$instance&nbsp;instanceof&nbsp;self))&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>self::$instance&nbsp;=&nbsp;<span>new&nbsp;<span>self();&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;<span>self::$instance;&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br>$a&nbsp;= Database::getInstance();&nbsp;&nbsp;<br>$b&nbsp;= Database::getInstance();&nbsp;&nbsp;<br><br><span>//&nbsp;true&nbsp;&nbsp;<br>var_dump($a&nbsp;===&nbsp;$b);&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<h1>2.工厂设计模式</h1>
<p>工厂模式是另一种非常常用的模式,正如其名字所示:确实是对象实例的生产工厂。某些意义上,工厂模式提供了通用的方法有助于我们去获取对象,而不需要关心其具体的内在的实现</p>
<p>使用场景:使用方法 new实例化类,每次实例化只需调用工厂类中的方法实例化即可。</p>
<p>我们举例子,假设矩形、圆都有同样的一个方法,那么我们用基类提供的API来创建实例时,通过传参数来自动创建对应的类的实例,他们都有获取周长和面积的功能。</p>
<pre><code><span><span>&lt;?php&nbsp;&nbsp;<br><br><span><span>interface&nbsp;<span>InterfaceShape&nbsp;&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;<span><span>function&nbsp;<span>getArea<span>();&nbsp;&nbsp;<br>&nbsp;<span><span>function&nbsp;<span>getCircumference<span>();&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>/**&nbsp;<br>*&nbsp;矩形&nbsp;<br>*/&nbsp;&nbsp;<br><span><span>class&nbsp;<span>Rectangle&nbsp;<span>implements&nbsp;<span>InterfaceShape&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>private&nbsp;$width;&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>private&nbsp;$height;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>__construct<span>($width,&nbsp;$height)&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;width&nbsp;=&nbsp;$width;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;height&nbsp;=&nbsp;$height;&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>getArea<span>()&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;<span>$this-&gt;width*&nbsp;<span>$this-&gt;height;&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>getCircumference<span>()&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;<span>2&nbsp;*&nbsp;<span>$this-&gt;width&nbsp;+&nbsp;<span>2&nbsp;*&nbsp;<span>$this-&gt;height;&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>/**&nbsp;<br>*&nbsp;圆形&nbsp;<br>*/&nbsp;&nbsp;<br><span><span>class&nbsp;<span>Circle&nbsp;<span>implements&nbsp;<span>InterfaceShape&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>private&nbsp;$radius;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span><span>function&nbsp;<span>__construct<span>($radius)&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;radius&nbsp;=&nbsp;$radius;&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>getArea<span>()&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;M_PI&nbsp;*&nbsp;pow(<span>$this-&gt;radius,&nbsp;<span>2);&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>getCircumference<span>()&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;<span>2&nbsp;*&nbsp;M_PI&nbsp;*&nbsp;<span>$this-&gt;radius;&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>/**&nbsp;<br>*&nbsp;形状工厂类&nbsp;<br>*/&nbsp;&nbsp;<br><span><span>class&nbsp;<span>FactoryShape&nbsp;&nbsp;&nbsp;<br>{&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>public&nbsp;<span>static&nbsp;<span><span>function&nbsp;<span>create<span>()&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>switch&nbsp;(func_num_args())&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case1:&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;newCircle(func_get_arg(<span>0));&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case2:&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;newRectangle(func_get_arg(<span>0),&nbsp;func_get_arg(<span>1));&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>default:&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;code...&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>break;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br>$rect&nbsp;=FactoryShape::create(<span>5,&nbsp;<span>5);&nbsp;&nbsp;<br><span>//&nbsp;object(Rectangle)#1&nbsp;(2)&nbsp;{&nbsp;["width":"Rectangle":private]=&gt;&nbsp;int(5)&nbsp;["height":"Rectangle":private]=&gt;&nbsp;int(5)&nbsp;}&nbsp;&nbsp;<br>var_dump($rect);&nbsp;&nbsp;<br><span>echo&nbsp;<span>"&lt;br&gt;";&nbsp;&nbsp;<br><br><span>//&nbsp;object(Circle)#2&nbsp;(1)&nbsp;{&nbsp;["radius":"Circle":private]=&gt;&nbsp;int(4)&nbsp;}&nbsp;&nbsp;<br>$circle&nbsp;=FactoryShape::create(<span>4);&nbsp;&nbsp;<br>var_dump($circle);&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<p>3.观察者设计模式</p>
<p>观察者模式是挺常见的一种设计模式,使用得当会给程序带来非常大的便利,使用得不当,会给后来人一种难以维护的想法。</p>
<p>什么是观察者模式?一个对象通过提供方法允许另一个对象即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。观察者模式是一种事件系统,意味着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间紧密耦。看下面例子你就明白了</p>
<p>使用场景:用户登录,需要写日志,送积分,参与活动 等</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 使用消息队列,把用户和日志,积分,活动之间解耦合</p>
<pre><code><span><span>&lt;?php&nbsp;&nbsp;<br><br><span>/*&nbsp;<br>观察者接口&nbsp;<br>*/&nbsp;&nbsp;<br><span><span>interface&nbsp;<span>InterfaceObserver&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span><span>function&nbsp;<span>onListen<span>($sender,&nbsp;$args);&nbsp;&nbsp;<br>&nbsp;&nbsp;<span><span>function&nbsp;<span>getObserverName<span>();&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>//&nbsp;可被观察者接口&nbsp;&nbsp;<br><span><span>interface&nbsp;<span>InterfaceObservable&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span><span>function&nbsp;<span>addObserver<span>($observer);&nbsp;&nbsp;<br>&nbsp;&nbsp;<span><span>function&nbsp;<span>removeObserver<span>($observer_name);&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>//&nbsp;观察者抽象类&nbsp;&nbsp;<br><span>abstract&nbsp;<span><span>class&nbsp;<span>Observer&nbsp;<span>implements&nbsp;<span>InterfaceObserver&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>protected&nbsp;$observer_name;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span><span>function&nbsp;<span>getObserverName<span>()&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;<span>$this-&gt;observer_name;&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span><span>function&nbsp;<span>onListen<span>($sender,&nbsp;$args)&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br><br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>//&nbsp;可被观察类&nbsp;&nbsp;<br><span>abstract&nbsp;<span><span>class&nbsp;<span>Observable&nbsp;<span>implements&nbsp;<span>InterfaceObservable&nbsp;&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>protected&nbsp;$observers&nbsp;=&nbsp;<span>array();&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>addObserver<span>($observer)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>if&nbsp;($observerinstanceofInterfaceObserver)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;observers[]&nbsp;=&nbsp;$observer;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>removeObserver<span>($observer_name)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>foreach&nbsp;(<span>$this-&gt;observersas&nbsp;$index&nbsp;=&gt;&nbsp;$observer)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if&nbsp;($observer-&gt;getObserverName()&nbsp;===&nbsp;$observer_name)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array_splice(<span>$this-&gt;observers,&nbsp;$index,&nbsp;<span>1);&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>//&nbsp;模拟一个可以被观察的类&nbsp;&nbsp;<br><span><span>class&nbsp;<span>A&nbsp;<span>extends&nbsp;<span>Observable&nbsp;&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>addListener<span>($listener)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>foreach&nbsp;(<span>$this-&gt;observersas&nbsp;$observer)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$observer-&gt;onListen(<span>$this,&nbsp;$listener);&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>//&nbsp;模拟一个观察者类&nbsp;&nbsp;<br><span><span>class&nbsp;<span>B&nbsp;<span>extends&nbsp;<span>Observer&nbsp;&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>protected&nbsp;$observer_name&nbsp;=&nbsp;<span>'B';&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>onListen<span>($sender,&nbsp;$args)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;var_dump($sender);&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"&lt;br&gt;";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;var_dump($args);&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"&lt;br&gt;";&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span>//&nbsp;模拟另外一个观察者类&nbsp;&nbsp;<br><span><span>class&nbsp;<span>C&nbsp;<span>extends&nbsp;<span>Observer&nbsp;&nbsp;&nbsp;<br>{&nbsp;&nbsp;<br>&nbsp;&nbsp;<span>protected&nbsp;$observer_name&nbsp;=&nbsp;<span>'C';&nbsp;&nbsp;<br><br>&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>onListen<span>($sender,&nbsp;$args)&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;var_dump($sender);&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"&lt;br&gt;";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;var_dump($args);&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"&lt;br&gt;";&nbsp;&nbsp;<br>&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br>$a&nbsp;=&nbsp;<span>new&nbsp;A();&nbsp;&nbsp;<br><span>//&nbsp;注入观察者&nbsp;&nbsp;<br>$a-&gt;addObserver(<span>new&nbsp;B());&nbsp;&nbsp;<br>$a-&gt;addObserver(<span>new&nbsp;C());&nbsp;&nbsp;<br><br><span>//&nbsp;可以看到观察到的信息&nbsp;&nbsp;<br>$a-&gt;addListener(<span>'D');&nbsp;&nbsp;<br><br><span>//&nbsp;移除观察者&nbsp;&nbsp;<br>$a-&gt;removeObserver(<span>'B');&nbsp;&nbsp;<br><br><span>//&nbsp;打印的信息:&nbsp;&nbsp;<br><span>//&nbsp;object(A)#1&nbsp;(1)&nbsp;{&nbsp;["observers":protected]=&gt;&nbsp;array(2)&nbsp;{&nbsp;=&gt;&nbsp;object(B)#2&nbsp;(1)&nbsp;{&nbsp;["observer_name":protected]=&gt;&nbsp;string(1)&nbsp;"B"&nbsp;}&nbsp;=&gt;&nbsp;object(C)#3&nbsp;(1)&nbsp;{&nbsp;["observer_name":protected]=&gt;&nbsp;string(1)&nbsp;"C"&nbsp;}&nbsp;}&nbsp;}&nbsp;&nbsp;<br><span>//&nbsp;string(1)&nbsp;"D"&nbsp;&nbsp;<br><span>//&nbsp;object(A)#1&nbsp;(1)&nbsp;{&nbsp;["observers":protected]=&gt;&nbsp;array(2)&nbsp;{&nbsp;=&gt;&nbsp;object(B)#2&nbsp;(1)&nbsp;{&nbsp;["observer_name":protected]=&gt;&nbsp;string(1)&nbsp;"B"&nbsp;}&nbsp;=&gt;&nbsp;object(C)#3&nbsp;(1)&nbsp;{&nbsp;["observer_name":protected]=&gt;&nbsp;string(1)&nbsp;"C"&nbsp;}&nbsp;}&nbsp;}&nbsp;&nbsp;<br><span>//&nbsp;string(1)&nbsp;"D"&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<p>4.适配器模式</p>
<p>将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。<br>应用场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。例如:php连接数据库的方法:mysql,,mysqli,pdo,可以用适配器统一</p>
<pre><code><span>//老的代码&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><span><span>class&nbsp;<span>User&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span>private&nbsp;$name;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>__construct<span>($name)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;name&nbsp;=&nbsp;$name;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>getName<span>()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;<span>$this-&gt;name;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><span>//新代码,开放平台标准接口&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><span><span>interface&nbsp;<span>UserInterface&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>getUserName<span>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><span><span>class&nbsp;<span>UserInfo&nbsp;<span>implements&nbsp;<span>UserInterface&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span>protected&nbsp;$user;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>__construct<span>($user)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;user&nbsp;=&nbsp;$user;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>getUserName<span>()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;<span>$this-&gt;user-&gt;getName();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>$olduser&nbsp;=&nbsp;<span>new&nbsp;User(<span>'张三');&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><span>echo&nbsp;$olduser-&gt;getName().<span>"n";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>$newuser&nbsp;=&nbsp;<span>new&nbsp;UserInfo($olduser);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><span>echo&nbsp;$newuser-&gt;getUserName().<span>"n";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<p>5.策略模式</p>
<p>将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。</p>
<p>例如:一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有广告位展示不同的广告</p>
<p>MaleUserStrategy.php</p>
<pre><code><span><span>&lt;?php&nbsp;&nbsp;&nbsp;<br><span>namespace&nbsp;<span>IMooc;&nbsp;&nbsp;<br><span><span>class&nbsp;<span>MaleUserStrategy&nbsp;<span>implements&nbsp;<span>UserStrategy&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>showAd<span>()&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"IPhone6";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>showCategory<span>()&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"电子产品";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<p>FemaleUserStrategy.php</p>
<pre><code><span><span>&lt;?php&nbsp;&nbsp;&nbsp;<br><span>namespace&nbsp;<span>IMooc;&nbsp;&nbsp;<br><span><span>class&nbsp;<span>FemaleUserStrategy&nbsp;<span>implements&nbsp;<span>UserStrategy&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>showAd<span>()&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"2017新款女装";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>showCategory<span>()&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"女装";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<p>UserStrategy.php</p>
<pre><code><span><span>&lt;?php&nbsp;&nbsp;&nbsp;<br><span>namespace&nbsp;<span>IMooc;&nbsp;&nbsp;<br><span><span>interface&nbsp;<span>UserStrategy&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>showAd<span>();&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span><span>function&nbsp;<span>showCategory<span>();&nbsp;&nbsp;<br>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><strong>&nbsp;</strong></p>
<pre><code><span><span>&lt;?php&nbsp;&nbsp;<br><span><span>interface&nbsp;<span>FlyBehavior{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>fly<span>();&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span><span>class&nbsp;<span>FlyWithWings&nbsp;<span>implements&nbsp;<span>FlyBehavior{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>fly<span>(){&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"Fly&nbsp;With&nbsp;Wings&nbsp;\n";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span><span>class&nbsp;<span>FlyWithNo&nbsp;<span>implements&nbsp;<span>FlyBehavior{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>fly<span>(){&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>echo&nbsp;<span>"Fly&nbsp;With&nbsp;No&nbsp;Wings&nbsp;\n";&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><span><span>class&nbsp;<span>Duck{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>private&nbsp;$_flyBehavior;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>performFly<span>(){&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;_flyBehavior-&gt;fly();&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;<span><span>function&nbsp;<span>setFlyBehavior<span>(FlyBehavior&nbsp;$behavior){&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>$this-&gt;_flyBehavior&nbsp;=&nbsp;$behavior;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br><span><span>class&nbsp;<span>RubberDuck&nbsp;<span>extends&nbsp;<span>Duck{&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><span>//&nbsp;Test&nbsp;Case&nbsp;&nbsp;<br>$duck&nbsp;=&nbsp;<span>new&nbsp;RubberDuck();&nbsp;&nbsp;<br><br><span>/*&nbsp;&nbsp;想让鸭子用翅膀飞行&nbsp;*/&nbsp;&nbsp;<br>$duck-&gt;setFlyBehavior(<span>new&nbsp;FlyWithWings());&nbsp;&nbsp;<br>$duck-&gt;performFly();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><span>/*&nbsp;&nbsp;想让鸭子不用翅膀飞行&nbsp;*/&nbsp;&nbsp;<br>$duck-&gt;setFlyBehavior(<span>new&nbsp;FlyWithNo());&nbsp;&nbsp;<br>$duck-&gt;performFly();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><span>&nbsp;</span></p><br><br>
来源:https://www.cnblogs.com/kinwing/p/11130335.html
頁: [1]
查看完整版本: PHP常用的 五种设计模式及应用场景