结构型模式,适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
确定你需要使用哪种设计模式,是根据你 的目的和需求决定的....在看下面的設計模式時,你會發現許多的設計模式實現過程都是一樣的.
所以你使用的是什麼設計模式,取決於你的實現需求.
只有弄明白這點.才不會混亂
适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。其中对象的适配器模式是各种模式的起源,我们看下面的图:
关键词:Adapter ,Decorator,proxy,Delegate,Facade
一 适配器模式
适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
类的适配器模式 | 对象的适配器模式 | 接口的适配器模式 |
interface TragetInterface{ public function method1() { } public function method2() { } } class Source{ public function method1() { } } class Adapter extends Source implements TragetInterface { public function method1() { parent::method1(); } public function method2() { } } |
interface TragetInterface{ public function method1() { } public function method2() { } } class Source{ public function method1() { } } class Adapter implements TragetInterface { protected $_source; public function __construct(Source $source) { $this->_source = $source } public function method1() { $this->_source->method1(); } public function method2() { } } |
interface SourceInterface{ public function method1() { } public function method2() { } } class InterfaceAdapter implements TragetInterface { public function method1() { } public function method2() { } } /** *事实上我只需要实现method1.所以需要一个抽象类 */ class SourceClass1 extends InterfaceAdapter { public function method1() { } } /** * */ class SourceClass2 extends InterfaceAdapter { public function method2() { } }
|
类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Wrapper类,持有原类的一个实例,在Wrapper类的方法中,调用实例的方法就行。
接口的适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类Wrapper,实现所有方法,我们写别的类的时候,继承抽象类即可。
二 装饰模式
装饰模式是在不必改变原类文件和使用继承的情况下,能对现有对象的内容或功能性稍加修改。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
class Model implements Stroge { public $name = ""; public function save($name) { $this->name = $name; } } class ModelDecorator { protected $_model; public function __construct($model) { $this->_model = $model; } public function upperName() { strtoupper($this->_model->name); } }
装饰器模式的应用场景:
1、需要扩展一个类的功能。
2、动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。)
缺点:产生过多相似的对象,不易排错!
三 代理模式(委托模式)
代理模式 : 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
目的为了去除核心对象的复杂性
可以参见ios开发的app委托了...
<?php /** * 代理模式 * * 为其他对象提供一个代理以控制这个对象的访问 * */ interface Proxy { public function request(); public function display(); } class RealSubject { public function request() { echo "RealSubject request<br />"; } public function display() { echo "RealSubject display<br />"; } } class ProxySubject { private $_subject = null; public function __construct() { $this->_subject = new RealSubject(); } public function request() { $this->_subject->request(); } public function display() { $this->_subject->display(); } } $objProxy = new ProxySubject(); $objProxy->request(); $objProxy->display(); ?>
装饰器模式和代理模式的区别:
装饰器模式关注于在一个对象上动态的添加方法,将原始对象作为一个参数传给装饰者的构造器
代理模式关注于控制对对象的访问。我们常常在一个代理类中创建一个对象的实例。可以对它的客户隐藏一个对象的具体信息
四 外观模式
外观模式是通过在必要的逻辑和方法的集合前创建简单的外观接口,隐藏调用对象的复杂性。
可以参见laravel的Facades部分..就是使用了外观模式
class User { protected $name; protected $age; public function setUserName($name){ return $this->name = $name; } public function setUserAge($age){ return $this->age = $age; } public function getUser(){ echo "姓名:{$this->name} 年龄:{$this->age}"; } } //如果不使用外观模式,调用方法如下: $user = new User(); $user->setUserName("John"); $user->setUserAge(24); $user->getUser(); //使用外观模式,创建一个外观接口 class UserFacade { public static function getUserCall(array $userinfo){ $user = new User; $user->setUserName($userinfo['name']); $user->setUserAge($userinfo['age']); return $user->getUser(); } } $userinfo = array('name'=>'Tom','age'=>25); //只要一个函数就能将调用类简化 UserFacade::getUserCall($userinfo);