Über Designmuster in Symfony2: Decorator-Muster
Wenn keine Entwurfsmuster vorliegen, basiert die Programmierung auf einer bestimmten Implementierung. Schreiben Sie beim Lesen von Datenbanknachrichten direkt eine datenbankbasierte Methode und beim Lesen empfohlener Nachrichten eine XML-basierte Methode Die beiden Methoden Es gab keine Beziehung zwischen ihnen. Zu dieser Zeit hatte ich das Gefühl, dass es nichts Falsches daran war, es auf diese Weise zu realisieren. Sie werden jedoch immer feststellen, dass diese beiden Methoden viele Ähnlichkeiten in der Implementierung aufweisen. Sie lesen beide eine Sammlung von Nachrichtentiteln, um die Datenquelle zu binden, die Methoden zum Abrufen der Datenquelle sind jedoch unterschiedlich. Um die Verwaltung zu erleichtern, können wir eine einheitliche Schnittstelle definieren, um diese beiden Methoden einzuschränken. Dieser Ansatz reicht auch aus, um den Anforderungen zum Lesen von Nachrichten aus unterschiedlichen Medien gerecht zu werden. Aber was ist, wenn Sie beim Lesen von Nachrichten andere Vorgänge ausführen müssen, zum Beispiel: Fügen Sie einen zur Popularität der gelesenen Nachrichten hinzu. Zu diesem Zeitpunkt müssen wir das ursprüngliche Programm ändern, was dem Programmierprinzip „Offen zur Erweiterung, geschlossen zur Änderung“ widerspricht. Wie kann man das Problem lösen? Dann kommt das Dekoratormuster ins Spiel.
Erweitern Sie die Funktionalität eines Objekts dynamisch, ohne die ursprüngliche Klassendatei zu ändern und Vererbung zu verwenden. Es umhüllt das reale Objekt, indem es ein Verpackungsobjekt, also eine Dekoration, erstellt.
Das Dekorationsmuster ordnet jede zu dekorierende Funktion einer separaten Klasse zu und lässt diese Klasse das zu dekorierende Objekt umschließen. Daher kann der Client-Code bei Bedarf die Objekte umschließen Die Dekoration funktioniert konsistent und sequenziell.
Abbildung 1
Nutzungsszenarien
Stellen Sie sich vor, wir müssten einen Schüler mit unterschiedlicher Kleidung für verschiedene Anlässe erstellen, zum Beispiel: Schüler in der Schule müssen Schuluniformen tragen, Schüler bei Tanzveranstaltungen müssen formelle Kleidung tragen, Schüler zu Hause können sich nackt kleiden (etwas pervers). Natürlich kann man von Superman auch lernen, seine Unterwäsche draußen zu tragen. An diesem Punkt stellt sich die Frage: Müssen wir eine Schülerklasse für jeden Anlass anders gekleidet schreiben? Was wäre, wenn unser Kind sich ein Mädchen wünscht, das Schuluniformhosen und ein Oberteil mit freiliegendem Unterteil trägt? StudentWithSchoolUniform, StudentWithFormalWear, StudentWithNaked, StudentWithSchoolUniformAndOutSideUnderWear......... Endlose Klassen~~~ Müde! Ja, wenn dies zu einer Explosion der Kurse führt, wird die Nachfrage steigen und die Anzahl der Kurse wird weiter steigen. Sie können sich vorstellen, wie schwierig es ist, das gesamte System aufrechtzuerhalten.
Zu diesem Zeitpunkt kann der Dekorateurmodus seine Rolle spielen. Unterwäsche, formelle Kleidung, Schuluniformen, Schuhe, Brillen usw. sind allesamt spezifische Dekorateure und die zu dekorierenden Objekte Sowohl abstrakte Klassen als auch Dekoratoren erben dieselbe übergeordnete Klasse. Das Tragen unterschiedlicher Kleidung für die Schüler bedeutet eigentlich, die dekorierte Klasse (die Schüler) mit der dekorierten Klasse (den Schülern) zu umhüllen.
Klassen und Schnittstellen
- Komponente (die Basisklasse des dekorierten Objekts, entsprechend der Person-Klasse des Beispiels)
- ConcreteComponent (spezifisches dekoriertes Objekt, entsprechend der Student-Klasse des Beispiels)
- Dekorateur (Dekorator-Basisklasse, Kostüm entsprechend dem Beispiel)
- ContreteDecorator (spezifische Dekoratorklasse, entsprechend Beispielen für Hosen, Hemden usw.)
Beispiel
Abbildung 2
Person.php


<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span>* Person.php </span><span> 5</span> <span>* 被装饰基类 </span><span> 6</span> <span>*</span><span>*/</span> <span> 7</span> <span>abstract</span> <span>class</span><span> Person{ </span><span> 8</span> <span> 9</span> <span>public</span> <span>abstract</span> <span>function</span><span> show(); </span><span>10</span> <span>11</span> }
Student.php


<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span>* Student.php </span><span> 5</span> <span>* 具体被装饰对象 </span><span> 6</span> <span>*</span><span>*/</span> <span> 7</span> <span>class</span> Student <span>extends</span><span> Person{ </span><span> 8</span> <span> 9</span> <span>private</span> <span>$name</span><span>; </span><span>10</span> <span>11</span> <span>public</span> <span>function</span> __construct(<span>$name</span><span>){ </span><span>12</span> <span>$this</span>->name = <span>$name</span><span>; </span><span>13</span> <span> } </span><span>14</span> <span>15</span> <span>public</span> <span>function</span><span> show(){ </span><span>16</span> <span>echo</span> '我是学生',<span>$this</span>-><span>name; </span><span>17</span> <span> } </span><span>18</span> }
Kostüm.php


<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span>* Costume.php </span><span> 5</span> <span>* 装饰者基类 </span><span> 6</span> <span>*</span><span>*/</span> <span> 7</span> <span>abstract</span> <span>class</span> Costume <span>extends</span><span> Person{ </span><span> 8</span> <span> 9</span> <span>10</span> }
Shirt.php


<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span>* Shirt.php </span><span> 5</span> <span>* 具体的装饰者类 </span><span> 6</span> <span>*</span><span>*/</span> <span> 7</span> <span>class</span> Shirt <span>extends</span><span> Costume{ </span><span> 8</span> <span> 9</span> <span>private</span> <span>$person</span><span>; </span><span>10</span> <span>11</span> <span>public</span> <span>function</span> __construct(Person <span>$person</span><span>){ </span><span>12</span> <span>13</span> <span>$this</span>->person = <span>$person</span><span>; </span><span>14</span> <span>15</span> <span> } </span><span>16</span> <span>17</span> <span>public</span> <span>function</span><span> show(){ </span><span>18</span> <span>19</span> <span>echo</span> <span>$this</span>->person->show(),',穿着衬衫'<span>; </span><span>20</span> <span> } </span><span>21</span> <span>22</span> }
Hosen.php


<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span>* Pants.php </span><span> 5</span> <span>*</span><span>*/</span> <span> 6</span> <span>class</span> Pants <span>extends</span><span> Costume{ </span><span> 7</span> <span> 8</span> <span>private</span> <span>$person</span><span>; </span><span> 9</span> <span>10</span> <span>public</span> <span>function</span> __construct(Person <span>$person</span><span>){ </span><span>11</span> <span>12</span> <span>$this</span>->person = <span>$person</span><span>; </span><span>13</span> <span>14</span> <span> } </span><span>15</span> <span>16</span> <span>public</span> <span>function</span><span> show(){ </span><span>17</span> <span>18</span> <span>echo</span> <span>$this</span>->person->show(),',穿着裤子'<span>; </span><span>19</span> <span> } </span><span>20</span> <span>21</span> }
Glasses.php


<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span>* Glasses.php </span><span> 5</span> <span>*</span><span>*/</span> <span> 6</span> <span>class</span> Glasses <span>extends</span><span> Costume{ </span><span> 7</span> <span> 8</span> <span>private</span> <span>$person</span><span>; </span><span> 9</span> <span>10</span> <span>public</span> <span>function</span> __construct(Person <span>$person</span><span>){ </span><span>11</span> <span>12</span> <span>$this</span>->person = <span>$person</span><span>; </span><span>13</span> <span>14</span> <span> } </span><span>15</span> <span>16</span> <span>public</span> <span>function</span><span> show(){ </span><span>17</span> <span>18</span> <span>echo</span> <span>$this</span>->person->show(),',带着眼镜'<span>; </span><span>19</span> <span> } </span><span>20</span> <span>21</span> }
UnderWear.php


<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span>* UnderWear.php </span><span> 5</span> <span>*</span><span>*/</span> <span> 6</span> <span>class</span> UnderWear <span>extends</span><span> Costume{ </span><span> 7</span> <span> 8</span> <span>private</span> <span>$person</span><span>; </span><span> 9</span> <span>10</span> <span>public</span> <span>function</span> __construct(Person <span>$person</span><span>){ </span><span>11</span> <span>12</span> <span>$this</span>->person = <span>$person</span><span>; </span><span>13</span> <span>14</span> <span> } </span><span>15</span> <span>16</span> <span>public</span> <span>function</span><span> show(){ </span><span>17</span> <span>18</span> <span>echo</span> <span>$this</span>->person->show(),',穿着DK'<span>; </span><span>19</span> <span> } </span><span>20</span> <span>21</span> }
Client.php
<span> 1</span> <?<span>php </span><span> 2</span> <span> 3</span> <span>require_once</span> 'Person.php'<span>; </span><span> 4</span> <span>require_once</span> 'Costume.php'<span>; </span><span> 5</span> <span>require_once</span> 'Student.php'<span>; </span><span> 6</span> <span>require_once</span> 'UnderWear.php'<span>; </span><span> 7</span> <span>require_once</span> 'Shirt.php'<span>; </span><span> 8</span> <span>require_once</span> 'Pants.php'<span>; </span><span> 9</span> <span>require_once</span> 'Glasses.php'<span>; </span><span>10</span> <span>11</span> <span>//</span><span> Student继承Person</span> <span>12</span> <span>$jc</span> = <span>new</span> Student('JC'<span>); </span><span>13</span> <span>$jc</span>->show(); <span>//</span><span> 我是学生JC</span> <span>14</span> <span>echo</span> '<br>'<span>; </span><span>15</span> <span>16</span> <span>//</span><span> 用UnderWear类装饰Person</span> <span>17</span> <span>$underwear</span> = <span>new</span> UnderWear(<span>$jc</span><span>); </span><span>18</span> <span>$underwear</span>->show(); <span>//</span><span> 我是学生JC,穿着DK</span> <span>19</span> <span>echo</span> '<br>'<span>; </span><span>20</span> <span>21</span> <span>//</span><span> 再用Pants类装饰Person</span> <span>22</span> <span>$pants</span> = <span>new</span> Pants(<span>$underwear</span><span>); </span><span>23</span> <span>$pants</span>->show(); <span>//</span><span> 我是学生JC,穿着DK,穿着裤子</span> <span>24</span> <span>echo</span> '<br>'<span>; </span><span>25</span> <span>26</span> <span>//</span><span> 再用Shirt类装饰Person</span> <span>27</span> <span>$shirt</span> = <span>new</span> Shirt(<span>$pants</span><span>); </span><span>28</span> <span>$shirt</span>->show(); <span>//</span><span> 我是学生JC,穿着DK,穿着裤子,穿着衬衫</span> <span>29</span> <span>echo</span> '<br>'<span>; </span><span>30</span> <span>31</span> <span>//</span><span> 再用Glasses类装饰Person</span> <span>32</span> <span>$glasses</span> = <span>new</span> Glasses(<span>$shirt</span><span>); </span><span>33</span> <span>$glasses</span>->show(); <span>//</span><span> 我是学生JC,穿着DK,穿着裤子,穿着衬衫,带着眼镜</span> <span>34</span> <span>echo</span> '<br>';
图3 输出结果截图
Symfony2 EventDispatch 组件对装饰者模式的应用
图4 Symfony2 EventDispatch组件使用装饰模式
图5 Framework配置EventDispatcher
- Symfony\Component\EventDispatcher\EventDispatcherInterface 是被装饰的接口
- Symfony\Component\EventDispatcher\EventDispatcher 和 Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher 是被装饰的具体对象
- Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface 装饰者接口
- Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher 装饰者基类
- Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher 具体的装饰者对象
具体装饰者对象Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher::dispatch()方法,核心依旧是调用被装饰的具体对象Symfony\Component\EventDispatcher\EventDispatcher::dispatch()方法进行工作,但是装饰者对象Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher::dispatch()方法添加了相应的功能,例如在调用Symfony\Component\EventDispatcher\EventDispatcher::dispatch()方法前后分别调用了preProcess()、preDispatch()和postDispatch()、postProcess():
<span> 1</span> <span>/*</span><span>* </span><span> 2</span> <span> * {@inheritdoc} </span><span> 3</span> <span>*/</span> <span> 4</span> <span>public</span> <span>function</span> dispatch(<span>$eventName</span>, Event <span>$event</span> = <span>null</span><span>) </span><span> 5</span> <span> { </span><span> 6</span> <span>if</span> (<span>null</span> === <span>$event</span><span>) { </span><span> 7</span> <span>$event</span> = <span>new</span><span> Event(); </span><span> 8</span> <span> } </span><span> 9</span> <span>10</span> <span>//</span><span> 装饰者对象增加的功能</span> <span>11</span> <span>$this</span>->preProcess(<span>$eventName</span><span>); </span><span>12</span> <span>$this</span>->preDispatch(<span>$eventName</span>, <span>$event</span><span>); </span><span>13</span> <span>14</span> <span>$e</span> = <span>$this</span>->stopwatch->start(<span>$eventName</span>, 'section'<span>); </span><span>15</span> <span>16</span> <span>//</span><span> 核心依旧是调用被装饰的具体对象Symfony\Component\EventDispatcher\EventDispatcher::dispatch()方法</span> <span>17</span> <span>$this</span>->dispatcher->dispatch(<span>$eventName</span>, <span>$event</span><span>); </span><span>18</span> <span>19</span> <span>if</span> (<span>$e</span>-><span>isStarted()) { </span><span>20</span> <span>$e</span>-><span>stop(); </span><span>21</span> <span> } </span><span>22</span> <span>23</span> <span>//</span><span> 装饰者对象增加的功能</span> <span>24</span> <span>$this</span>->postDispatch(<span>$eventName</span>, <span>$event</span><span>); </span><span>25</span> <span>$this</span>->postProcess(<span>$eventName</span><span>); </span><span>26</span> <span>27</span> <span>return</span> <span>$event</span><span>; </span><span>28</span> }
优点
- 通过组合而非继承的方式,实现了动态扩展对象的功能的能力。
- 有效避免了使用继承的方式扩展对象功能而带来的灵活性差,子类无限制扩张的问题。
- 充分利用了继承和组合的长处和短处,在灵活性和扩展性之间找到完美的平衡点。
- 装饰者和被装饰者之间虽然都是同一类型,但是它们彼此是完全独立并可以各自独立任意改变的。
- 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点
- 装饰链不能过长,否则会影响效率。
- 只在必要的时候使用装饰者模式,否则会提高程序的复杂性,增加系统维护难度。
- 装饰者对象和被装饰者对象都继承Component,如果Component内部发生变化,所有的子类都要改变。
以上就介绍了关于Symfony2中的设计模式:装饰者模式,包括了Symfony2,装饰者模式方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

Um in cakephp4 mit Datum und Uhrzeit zu arbeiten, verwenden wir die verfügbare FrozenTime-Klasse.

CakePHP ist ein Open-Source-Framework für PHP. Es soll die Entwicklung, Bereitstellung und Wartung von Anwendungen erheblich vereinfachen. CakePHP basiert auf einer MVC-ähnlichen Architektur, die sowohl leistungsstark als auch leicht zu verstehen ist. Modelle, Ansichten und Controller gu

Um am Datei-Upload zu arbeiten, verwenden wir den Formular-Helfer. Hier ist ein Beispiel für den Datei-Upload.

Der Validator kann durch Hinzufügen der folgenden zwei Zeilen im Controller erstellt werden.

Die Anmeldung bei CakePHP ist eine sehr einfache Aufgabe. Sie müssen nur eine Funktion verwenden. Sie können Fehler, Ausnahmen, Benutzeraktivitäten und von Benutzern durchgeführte Aktionen für jeden Hintergrundprozess wie Cronjob protokollieren. Das Protokollieren von Daten in CakePHP ist einfach. Die Funktion log() wird bereitgestellt

Visual Studio Code, auch bekannt als VS Code, ist ein kostenloser Quellcode-Editor – oder eine integrierte Entwicklungsumgebung (IDE) –, die für alle gängigen Betriebssysteme verfügbar ist. Mit einer großen Sammlung von Erweiterungen für viele Programmiersprachen kann VS Code c

CakePHP ist ein Open-Source-MVC-Framework. Es erleichtert die Entwicklung, Bereitstellung und Wartung von Anwendungen erheblich. CakePHP verfügt über eine Reihe von Bibliotheken, um die Überlastung der häufigsten Aufgaben zu reduzieren.
