Heim Backend-Entwicklung PHP-Tutorial php设计模式(三):结构模式

php设计模式(三):结构模式

Jun 20, 2016 pm 12:27 PM

一、什么是结构型模式?
结构型模式是解析类和对象的内部结构和外部组合,通过优化程序结构解决模块之间的耦合问题。

二、结构型模式的种类:
适配器模式
桥接模式
装饰模式
组合模式
外观模式
享元模式
代理模式

1、 适配器模式(Adapter)
将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。
应用场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。

代码实现

  1. /**    
  2.  * 适配器模式    
  3.  */
  4.           
  5.  //老的代码     
  6.  class User {    
  7.     private $name;    
  8.     function __construct($name) {    
  9.         $this->name = $name;    
  10.     }    
  11.     public function getName() {    
  12.         return $this->name;    
  13.     }    
  14.  }    
  15.           
  16.  //新代码,开放平台标准接口    
  17.  interface UserInterface {    
  18.     function getUserName();    
  19.  }    
  20.  class UserInfo implements UserInterface {    
  21.     protected $user;    
  22.     function __construct($user) {    
  23.         $this->user = $user;    
  24.     }    
  25.     public function getUserName() {    
  26.         return $this->user->getName();    
  27.     }    
  28.  }    
  29.             
  30. $olduser = new User('张三');    
  31. echo $olduser->getName()."n";    
  32. $newuser = new UserInfo($olduser);    
  33. echo $newuser->getUserName()."n";    

复制代码

注意点:这里的新接口使用了组合方式,UserInfo内部有一个成员变量保存老接口User对象,模块之间是松耦合的,这种结构其实就是组合模式。不要使用继承,虽然UserInfo继承User也能达到同样的目的,但是耦合度高,相互产生影响。


2、 桥接模式
将抽象部分与它的实现部分分离,使它们都可以独立变化
特点:独立存在,扩展性强
应用:需要不断更换调用对象却执行相同的调用方法,实现扩展功能

代码实现

  1. /**    
  2.  *    
  3.  * 桥接模式    
  4.  *     
  5.  */
  6.               
  7.  abstract class Person {    
  8.     abstract function getJob();    
  9.  }    
  10.               
  11.  class Student extends Person {    
  12.     public function getJob() {    
  13.         return '学生';    
  14.     }    
  15.  }    
  16.               
  17.  class Teacher extends Person {    
  18.     public function getJob() {    
  19.         return '老师';    
  20.     }    
  21.  }    
  22.               
  23.  class BridgeObj {    
  24.     protected $_person;    
  25.               
  26.     public function setPerson($person) {    
  27.         $this->_person = $person;    
  28.     }    
  29.               
  30.     public function getJob() {    
  31.         return $this->_person->getJob();    
  32.     }    
  33.  }    
  34.                   
  35. $obj = new BridgeObj();    
  36. $obj->setPerson(new Student());    
  37. printf("本次桥接对象:%sn", $obj->getJob());    
  38. $obj->setPerson(new Teacher());    
  39. printf("本次桥接对象:%sn", $obj->getJob());

复制代码

3、 装饰模式
动态地给一个对象添加额外的职责。在原有的基础上进行功能增强。
特点:用来增强原有对象功能,依附于原有对象。
应用:用于需要对原有对象增加功能而不是完全覆盖的时候

代码实现

  1. /**   
  2.  *     
  3.  * 装饰模式     
  4.  *     
  5.  */
  6.              
  7.  //产品     
  8.  abstract class Person {     
  9.     abstract function getPermission();     
  10.  }     
  11.  //被装饰者     
  12.  class User extends Person {     
  13.     public function getPermission() {     
  14.         return '公开文档';     
  15.     }     
  16.  }     
  17.  //装饰类     
  18.  class PermUser extends Person {     
  19.     protected $_user;     
  20.     protected $_special = '';     
  21.     function __construct($user) {     
  22.         $this->_user = $user;     
  23.     }     
  24.     public function getPermission() {     
  25.         return $this->_user->getPermission() . $this->_special;     
  26.     }     
  27.  }     
  28.  //装饰类产品     
  29.  class JavaUser extends PermUser {     
  30.     protected $_special = ' java程序';     
  31.  }     
  32.  class CPlusUser extends PermUser {     
  33.     protected $_special = ' c++程序';     
  34.  }     
  35.              
  36.              
  37. $user = new User();     
  38. printf("permission:%sn", $user->getPermission());     
  39. $user = new JavaUser($user);     
  40. printf("permission:%sn", $user->getPermission());     
  41. $user = new CPlusUser($user);     
  42. printf("permission:%sn", $user->getPermission());     

复制代码

大家想想装饰和继承的区别在哪?
如果是上面的例子,如果用继承,是CPlusUser继承JavaUser还是反过来呢?谁也不知道最终使用者需要哪一种。
在多层关系的情况下,装饰是和顺序无关并且随时增加装饰,而继承只能是特定的顺序,所以装饰模式会更加的灵活。

4、组合模式
将对象组合成树形结构表示“部分-整体”的层次结构。
特点:灵活性强
应用:对象的部分-整体的层次结构,模糊组合对象和简单对象处理问题
代码实现

  1. /**     
  2.  * 组合模式     
  3.  *     
  4.  */
  5.              
  6.  //继承模式     
  7.              
  8.  class UserBaseInfo {     
  9.     private $name;     
  10.              
  11.     function __construct($name) {     
  12.         $this->name = $name;     
  13.     }     
  14.     public function getName() {     
  15.         return $this->name;     
  16.     }     
  17.  }     
  18.  class User extends UserBaseInfo {     
  19.     private $login = false;     
  20.                  
  21.     public function setLogin($islogin) {     
  22.         $this->login = $islogin;     
  23.     }     
  24.     public function isLogin() {     
  25.         return $this->login;     
  26.     }     
  27.  }     
  28.              
  29. $user = new User('张三');     
  30. $user->setLogin(true);     
  31.  if ($user->isLogin()) {     
  32.     echo $user->getName()."已经登录了n";     
  33.  } else {     
  34.     echo $user->getName()."还没有登录n";     
  35.  }     
  36.              
  37.              
  38.  //组合模式     
  39.              
  40.  class LoginInfo {     
  41.     protected $user;     
  42.     protected $login = false;     
  43.                  
  44.     public function setLogin($user, $isLogin) {     
  45.         $this->user = $user;     
  46.         $this->login = $isLogin;     
  47.     }     
  48.     public function isLogin() {     
  49.         return $this->login;     
  50.     }     
  51.  }     
  52.              
  53. $user = new User('张三');     
  54. $login = new LoginInfo();     
  55. $login->setLogin($user, true);     
  56.  if ($login->isLogin()) {     
  57.     echo $user->getName()."已经登录了n";     
  58.  } else {     
  59.     echo $user->getName()."还没有登录n";     
  60.  }     
  61.              
  62.  //部分可以更换,用继承则不行     
  63.  class Admin {     
  64.     protected $level;     
  65.     function __construct($level) {     
  66.         $this->level = $level;     
  67.     }     
  68.     function getLevel() {     
  69.         return $this->level;     
  70.     }     
  71.  }     
  72. $admin = new Admin(1);     
  73. $login->setLogin($admin, true);     
  74.  if ($login->isLogin()) {     
  75.     printf("级别为 %d 的管理员已经登录了n", $admin->getLevel());     
  76.  } else {     
  77.     printf("级别为 %d 的管理员还没有登录n", $admin->getLevel());     
  78.  }

复制代码

上面的例子分别展示了使用继承和组合来处理新功能,在简单的情况下看似区别不大,但在项目后期越来越复杂的时候组合模式的优势就越来越明显了。
例如上面的登录信息,如果要增加登录次数、最后登录时间、登录ip等信息,登录本身就会变成一个比较复杂的对象。如果以后有新的需求比如好友信息、用户的访问信息等,再要继承的话,用户类就会变得非常庞大,难免各父类之间没有冲突的变量和方法,而外部访问用户类的众多方法也变得很费劲。采用组合模式后,一个类负责一个角色,功能区分非常明显,扩展方便。


5、 外观模式(门面模式)
为了系统中的一组接口提供一个一致的界面
特点:向上抽取,有共性
应用:内部接口众多,由统一的接口来调用

代码实现

  1.           
  2.  class Operation {     
  3.     public function testPlus() {     
  4.         printf("plus: %sn", (1 + 2 == 3 ? 'true' : 'false'));     
  5.     }     
  6.     public function testMinus() {     
  7.         printf("minus: %sn", (3 - 2 == 2 ? 'true' : 'false'));     
  8.     }     
  9.     public function testTimes() {     
  10.         printf("times: %sn", (2 * 3 == 6 ? 'true' : 'false'));     
  11.     }     
  12.  }     
  13.              
  14.  class Tester {     
  15.     protected $_operation;     
  16.     function __construct() {     
  17.         $this->_operation = new Operation();     
  18.     }     
  19.     public function testAll() {     
  20.         $this->_operation->testPlus();     
  21.         $this->_operation->testMinus();     
  22.         $this->_operation->testTimes();     
  23.     }     
  24.  }     
  25.              
  26.  //测试用例,测试全部接口     
  27. $tester = new Tester();     
  28. $tester->testAll();     

复制代码

门面模式估计大家在实际代码中都已经使用到了,接口较多时把相似功能的接口封装成一个接口供外部调用,这就是门面模式。


6、 享元模式
运用共享技术有效地支持大量细粒度对象,采用一个共享来避免大量有相同内容对象的开销。这种开销中最直观的就是内存的损耗。
特点:高效性,共享性
应用:系统底层的设计。例如字符串的创建。如果两个字符串相同,则不会创建第二个字符串,而是第二个的引用直接指向第一个字符串。$str1=”abc”,$str2=”abc”.则内存存储中只会创建一个字符串“abc”而引用$str1.$str2都会指向它。

7、 代理模式
为其他对象提供一个代理来控制对这个对象的访问,就是给某一对象提供代理对象,并由代理对象控制具体对象的引用。能够协调调用者和被调用者,能够在一定程度上降低系统的耦合性。
特点:低耦合性,独立性好,安全性
应用:客户访问不到或者被访问者希望隐藏自己,所以通过代理来访问自己。

代码实现

  1.             
  2.  //内部对象     
  3.  class User {     
  4.     public function getName() {     
  5.         return '张三';     
  6.     }     
  7.     public function getType() {     
  8.         return '付费用户';     
  9.     }     
  10.  }     
  11.              
  12.  //代理接口定义,例如开放平台     
  13.  interface UserInterface {     
  14.     function getName();     
  15.  }     
  16.  //代理对象     
  17.  class UserProxy implements UserInterface {     
  18.     protected $_user;     
  19.     function __construct() {     
  20.         $this->_user = new User();     
  21.     }     
  22.     public function getName() {     
  23.         return $this->_user->getName();     
  24.     }     
  25.  }     
  26.              
  27.  //内部调用     
  28. $user = new User();     
  29. printf("user name:%sn", $user->getName());     
  30. printf("user type:%sn", $user->getType());     
  31.  //外部调用     
  32.  // $user = new UserProxy();     
  33.  // printf("user name:%sn", $user->getName());     
  34.  // printf("user type:%sn", $user->getType()); //不能访问,及时知道内部对象有这个方法

复制代码

三、总结
1、代理模式、适配器模式、门面模式、装饰模式的区别
a、 相同之处:都封装一个内部对象,调用内部对象的方法
b、 不同之处:各自有各自的特性和应用场景,不能相互替代。所以用的时候要仔细分析用那种合适。

2、 关于模式的选用问题
模式的选用要根据实际的业务需求,通过对业务逻辑的仔细分析,再根据模式具有的特性和应用场景进行合理的选择和区分。大部分情况下业务的场景决定了哪种模式,而不是选择哪个模式去实现一个业务,少数情况几种模式确实都能解决问题,那主要就是考虑以后的扩展了。

到这里我们已经了解了7种结构型模式,下一篇我们继续给大家介绍设计模式的行为型模式,先预览一下行为型模式的种类吧:
u 模版方法模式
u 命令模式
u 迭代器模式
u 观察者模式
u 终结者模式
u 备忘录模式
u 解释器模式
u 状态模式
u 策略模式
u 职责链模式
u 访问者模式

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Arbeiten mit Flash -Sitzungsdaten in Laravel Arbeiten mit Flash -Sitzungsdaten in Laravel Mar 12, 2025 pm 05:08 PM

Laravel vereinfacht die Behandlung von temporären Sitzungsdaten mithilfe seiner intuitiven Flash -Methoden. Dies ist perfekt zum Anzeigen von kurzen Nachrichten, Warnungen oder Benachrichtigungen in Ihrer Anwendung. Die Daten bestehen nur für die nachfolgende Anfrage standardmäßig: $ Anfrage-

Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Mar 14, 2025 am 11:42 AM

Die PHP Client -URL -Erweiterung (CURL) ist ein leistungsstarkes Tool für Entwickler, das eine nahtlose Interaktion mit Remote -Servern und REST -APIs ermöglicht. Durch die Nutzung von Libcurl, einer angesehenen Bibliothek mit Multi-Protokoll-Dateien, erleichtert PHP Curl effiziente Execu

Vereinfachte HTTP -Reaktion verspottet in Laravel -Tests Vereinfachte HTTP -Reaktion verspottet in Laravel -Tests Mar 12, 2025 pm 05:09 PM

Laravel bietet eine kurze HTTP -Antwortsimulationssyntax und vereinfache HTTP -Interaktionstests. Dieser Ansatz reduziert die Code -Redundanz erheblich, während Ihre Testsimulation intuitiver wird. Die grundlegende Implementierung bietet eine Vielzahl von Verknüpfungen zum Antworttyp: Verwenden Sie Illuminate \ Support \ facades \ http; Http :: fake ([ 'Google.com' => 'Hallo Welt',, 'github.com' => ['foo' => 'bar'], 'Forge.laravel.com' =>

12 Beste PHP -Chat -Skripte auf Codecanyon 12 Beste PHP -Chat -Skripte auf Codecanyon Mar 13, 2025 pm 12:08 PM

Möchten Sie den dringlichsten Problemen Ihrer Kunden in Echtzeit und Sofortlösungen anbieten? Mit Live-Chat können Sie Echtzeitgespräche mit Kunden führen und ihre Probleme sofort lösen. Sie ermöglichen es Ihnen, Ihrem Brauch einen schnelleren Service zu bieten

Erklären Sie das Konzept der späten statischen Bindung in PHP. Erklären Sie das Konzept der späten statischen Bindung in PHP. Mar 21, 2025 pm 01:33 PM

In Artikel wird die in PHP 5.3 eingeführte LSB -Bindung (LSB) erörtert, die die Laufzeitauflösung der statischen Methode ermöglicht, um eine flexiblere Vererbung zu erfordern. Die praktischen Anwendungen und potenziellen Perfo von LSB

Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Apr 05, 2025 am 12:04 AM

JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

Rahmensicherheitsmerkmale: Schutz vor Schwachstellen. Rahmensicherheitsmerkmale: Schutz vor Schwachstellen. Mar 28, 2025 pm 05:11 PM

In Artikel werden wichtige Sicherheitsfunktionen in Frameworks erörtert, um vor Schwachstellen zu schützen, einschließlich Eingabevalidierung, Authentifizierung und regelmäßigen Aktualisierungen.

See all articles