常见的设计模式总结

来源:互联网 发布:无痕植发的价格 知乎 编辑:程序博客网 时间:2024/06/05 18:29

单例模式

/*含义:作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。单例模式的三个要点:1)需要一个保存类的唯一实例的静态成员变量2)构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义3)必须提供一个访问这个实例的公共的静态方法(通常为getInterface方法),从而返回唯一实例的一个引用为什么要使用单例模式针对单次页面级请求共享同一对象资源应用场合1)应用程序与数据库交互(单例模式可以避免大量的new操作,因为每一次new操作都会消耗内存资源和系统资源)2)控制配置信息(系统中需要用一个类来全局控制某些配置信息)*/class Single{static private $interface = null;final private function __construct(){ }final private function __clone(){ }final static public function getInterface(){if( self::$interface == null ){self::$interface = new Single();}return self::$interface;}}$t1 = Single::getInterface();$t2 = Single::getInterface();echo ($t1===$t2)?'相同':'不同';/*class Single2 extends Single{public function __construct(){}}$t1 = new Single2();$t2 = new Single2();echo ($t1===$t2)?'相同':'不同';*/


工厂模式

/*精髓:根据不同的参数生成不同的类实例工厂模式要点:通常工厂模式有一个关键的构造,即一般被命名为factory的静态方法。这个静态方法可以接受任意数量的参数,并且必须返回一个对象。为什么要使用工厂模式工厂类就是一个专门用来创建其它对象的类,工厂类在多态性编程中非常重要。它允许动态替换类,修改配置,会使应用程序更加灵活。应用场合1)当客户程序不需要知道要使用对象的创建过程。2)客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。*///运算基类abstract class Operation {abstract public function getValue($num1,$num2);}//加class SumOperation extends Operation {public function getValue($num1,$num2){return $num1 + $num2;}}//减class SubOperation extends Operation {public function getValue($num1,$num2){return $num1/$num2;}}//工厂类class Factory {static public function getOp( $op ){$opClassName = $op . 'Operation';return new $opClassName();}}$num1 = 6;$num2 = 3;$Op = Factory::getOp('Sub');echo $Op->getValue($num1,$num2);

观察者模式

/*在观察者模式中,会改变的是主题的状态以及观察者的数目。用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题。——找出程序中会变化的方面,然后将其和固定不变的方面相分离! 主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点! ——针对接口编程,不针对实现编程!观察者模式利用“组合”将许多观察者组合进主题中。对象(观察者——主题)之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。 ——多用组合,少用继承!*/class User {static $observe = [];public function addObserve( $observeObj ){self::$observe[] = $observeObj;}public function register(){//触发当前事件对应的操作//...echo "用户登录了...<br />";//通知观察者、执行观察的对应的操作foreach ( self::$observe as $obs ) {$obs->update();echo "<br />";}}}//以下都是观察者//----------------------------------------------------abstract class UserObserve {abstract public function update();}//日志class UserLog extends UserObserve {public function update(){echo 'UserLog update';}}//积分class IntegralLog extends UserObserve {public function update(){echo 'IntegralLog update';}}$U = new User();$U->addObserve( new UserLog() );$U->addObserve( new IntegralLog() );$U->register();



适配器模式

适配器模式将一个类的换成客户端需要的另一个接口,使原本不兼容的接口能一起工作。一个现实中的例子,假如屋里墙上只有两项插口,而风扇有三个插头,这时需要再拿一个移动插线板,插线板接入墙壁插口的一段是两项插头,插线板另外一段能够提供三项插口给风扇,这时候插线板起到了一个适配器的作用。

在应用中,适配器模式分为类适配器和对象适配器。


类适配器


类适配器中适配器继承原有的Adaptee类,自己实现原类没有的操作。

[php] view plain copy
  1. interface ITarget  
  2. {  
  3.     function operation1();  
  4.     function operation2();  
  5. }  
  6.   
  7. interface IAdaptee  
  8. {  
  9.     function operation1();  
  10. }  
  11.   
  12. class Adaptee extends IAdaptee  
  13. {  
  14.     public  function operation1()  
  15.     {  
  16.         echo "原方法";  
  17.     }  
  18. }  
  19.   
  20. class Adapter extends Adaptee implements IAdaptee, ITarget  
  21. {  
  22.     public  function operation2()  
  23.     {  
  24.         echo "适配方法";  
  25.     }  
  26. }  
  27.   
  28. class Client  
  29. {  
  30.     public  function test()  
  31.     {  
  32.         $adapter = new Adapter();  
  33.         $adapter->operation1();//原方法  
  34.         $adapter->operation2();//适配方法  
  35.     }  
  36. }  


对象配器


类适配器使用的是继承模式,而对象适配器使用的是组合模式,将adaptee作为adapter的一个引用。

[php] view plain copy
  1. interface ITarget  
  2. {  
  3.     function operation1();  
  4.     function operation2();  
  5. }  
  6.   
  7. interface IAdaptee  
  8. {  
  9.     function operation1();  
  10. }  
  11.   
  12. class Adaptee extends IAdaptee  
  13. {  
  14.     public  function operation1()  
  15.     {  
  16.         echo "原方法";  
  17.     }  
  18. }  
  19.   
  20. class Adapter implements  ITarget  
  21. {  
  22.     private $adaptee;  
  23.   
  24.     public function __construct($adaptee)  
  25.     {  
  26.         $this->adaptee = $adaptee;  
  27.     }  
  28.   
  29.     public  function operation1()  
  30.     {  
  31.          return $this->adaptee->operation1();  
  32.     }  
  33.   
  34.     public  function operation2()  
  35.     {  
  36.         echo "适配方法";  
  37.     }  
  38. }  
  39.   
  40.   
  41. class Client  
  42. {  
  43.     public  function test()  
  44.     {  
  45.         $adapter = new Adapter(new Adaptee(null));  
  46.         $adapter->operation1();//原方法  
  47.         $adapter->operation2();//适配方法  
  48.     }  
  49. }  
由于组合在耦合性上小于继承,对象适配器显得更加灵活,当然它的缺点是增加代码量。 需要重写adapee中的方法的数量太大的话,可以考虑在adapter中使用__call方法委托adapee取得客户端调用的方法
[php] view plain copy
  1. public function __call($func$args)  
  2. {  
  3.     if (is_callable(array($this->adaptee, $func))) {  
  4.         return $this->adaptee->$func($args);  
  5.     }  
  6.     trigger_error('*********', E_USER_ERROR);  
  7. }  





















0 0
原创粉丝点击