in the absence of contact with the design mode, are for the specific implementation of programming, read the database news directly write a database-based method, read the recommended news and then write an XML-based method, there is no relationship between the two methods. There is nothing wrong with this realization. But you will always find that the two methods in the implementation of a lot of the same place, is to read a collection of news headlines to bind the data source, just take the data source method is different. For ease of management, we can define a unified interface to constrain both methods. This approach is also sufficient to meet the news requirements for reading different carriers. But what if you want to do something else while reading the news? For example: Add one to the popularity of the news read. This time we have to modify the original program, so that there is a "open to the extension, the change off" programming principles. How to solve it? This is the time for the decorator mode to come out.
The ability to dynamically extend an object without having to change the original class file and use inheritance. It is by creating a wrapper object, that is, decorating to wrap the real object.
Decorator mode places each function that is to be decorated in a separate class and lets the class wrap the object it is decorating, so that when special behavior is required, client code can selectively and sequentially use the adornment function to wrap objects as needed at run time.
Figure 1
Usage Scenarios
Imagine if we need to create a student who has a different dress on different occasions, for example: students in school need to wear school uniforms, students in the prom need to wear a dress, students at home can nude (a little sick), of course, you can also learn Superman wear underwear outside. At this point, do we have to write a different kind of student for each occasion? What if our kids ' shoes want a pair of underwear with uniforms and pants and a dress? Studentwithschooluniform, Studentwithformalwear, studentwithnaked, studentwithschooluniformandoutsideunderwear .................. Continuous Endless class ~ ~ ~ Tired! Yes, if this causes the class explosion, the demand increases, the class will continue to increase, the maintenance of the whole system is difficult to imagine.
So at this time, the decorator mode can play its role, underwear, dress, school uniforms, shoes, glasses and so on are specific decorators, students are specific decorative objects, decorated objects and decorators of the abstract class are inherited by the same parent class. For students to wear different clothing, in fact, is to use the Decorator class (clothing) wrapped by the Decorator Class (students), the image of this is a dressing process.
Classes and Interfaces
- Component (the person class for which the object is a base class, corresponding to an example)
- Concretecomponent (specifically decorated object, corresponding example of the student Class)
- Decorator (Decorator base class, corresponding example of costume)
- Contretedecorator (Specific decorator class, corresponding example of pants, shirt, etc.)
Example
Figure 2
person.php
1
2 3 /* 4* 5* 6* * / 7 Abstract class 8 9publicAbstract functionten }
View Code
student.php
1
2 3 /* 4* 5* 6* * / 7 class extends 8 9private$name Tenpublicfunction __construct ($name $this$name15 public function -echo ' I am a student ', $this ++}
View Code
costume.php
1
2 3 /* 4* 5* 6* * / 7 abstractclass extends 8 9 }
View Code
shirt.php
1 !--?
php
2
3
/*
*
4
* shirt.php
5
* Concrete Decorator class
6
*
*/
7
class Shirt
extends
costume{
8
9
private $person ; Ten one public function __construct (person $person ) { all $this ->person = $person ; } + + public function Show () { * + echo $this ->person-> Show (), ', wearing a shirt ' ; } + all }
View Code
pants.php
1
2 3 /* 4* 5* */ 6 class Extends 7 8private $person 9 Ten Public function $person $this $person public function Echo $this->person->show (), ', wearing pants '
View Code
glasses.php
1
2 3 /* 4* 5* */ 6 class Extends 7 8private $person 9 Ten Public function $person $this $person public function Echo $this->person->show (), ', with glasses '
View Code
underwear.php
1
2 3 /* 4* 5* */ 6 class Extends 7 8private $person 9 Ten Public function $person $this $person public function Echo $this->person->show (), ', wearing DK '
View Code
client.php
1
Php2 3 require_once' Person.php '; 4 require_once' Costume.php '; 5 require_once' Student.php '; 6 require_once' Underwear.php '; 7 require_once' Shirt.php '; 8 require_once' Pants.php '; 9 require_once' Glasses.php '; Ten One //student inherit person A $JC=NewStudent (' JC '); - $JC->show ();//I'm a student JC . - Echo'
'; the - //decorate person with underwear class - $underwear=NewUnderwear ($JC); - $underwear->show ();//I'm a student jc, wearing a DK. + Echo'
'; - + //then decorate person with pants class A $pants=NewPants ($underwear); at $pants->show ();//I'm a student jc, wearing a DK, wearing pants . - Echo'
'; - - //then decorate person with shirt class - $shirt=NewShirt ($pants); - $shirt->show ();//I am a student JC , wearing a DK, wearing pants, wearing a shirt in Echo'
'; - to //then decorate person with glasses class + $glasses=NewGlasses ($shirt); - $glasses->show ();//I am a student jc, wearing a DK, wearing pants, wearing a shirt, with glasses the Echo'
';
Figure 3 Output results
Application of Symfony2 Eventdispatch component to decorator mode
Figure 4 Symfony2 Eventdispatch component using decorative mode
Figure 5 Framework Configuration Eventdispatcher
- Symfony\component\eventdispatcher\eventdispatcherinterface is an interface to be decorated
- Symfony\component\eventdispatcher\eventdispatcher and Symfony\component\eventdispatcher\ Containerawareeventdispatcher is a concrete object to be decorated
- Symfony\component\eventdispatcher\debug\traceableeventdispatcherinterface Decorator Interface
- Symfony\component\eventdispatcher\debug\traceableeventdispatcher Decorator base class
- Symfony\component\httpkernel\debug\traceableeventdispatcher Specific Decorator objects
Concrete Decorator Object Symfony\component\httpkernel\debug\traceableeventdispatcher::d Ispatch () method, the core is still called to decorate the specific object symfony\ Component\eventdispatcher\eventdispatcher: Works:d The Ispatch () method, but the adorner object symfony\component\httpkernel\debug\ Traceableeventdispatcher: The:d Ispatch () method adds the appropriate functionality, such as calling Symfony\component\eventdispatcher\eventdispatcher:: The dispatch () method calls Preprocess (), Predispatch (), and Postdispatch (), postprocess () respectively before and after the ():
1 /** 2 * {@inheritdoc}3 */ 4 Public functionDispatch$eventName, Event$event=NULL) 5 { 6 if(NULL===$event) { 7 $event=NewEvent ();8 } 9 Ten //added functionality for adorner objects One $this->preprocess ($eventName); A $this->predispatch ($eventName,$event); - - $e=$this->stopwatch->start ($eventName, ' section '); the - //The core is still called by the specific object being decorated Symfony\component\eventdispatcher\eventdispatcher::d ispatch () method - $this->dispatcher->dispatch ($eventName,$event); - + if($e-isstarted ()) { - $e-stop (); + } A at //added functionality for adorner objects - $this->postdispatch ($eventName,$event); - $this->postprocess ($eventName); - - return $event; -}
Advantages
- The ability to dynamically extend the functionality of an object is achieved by combining rather than inheriting.
- Effectively avoids the use of inheritance to extend the functionality of the object, the flexibility of the sub-class unlimited expansion problem.
- Leverage the strengths and weaknesses of inheritance and composition to find the perfect balance between flexibility and extensibility.
- Although both the decorator and the decorator are of the same type, they are completely independent from each other and can be arbitrarily changed independently of each other.
- Adhere to most grasp principles and common design principles, high cohesion, low coupling.
Disadvantages
- The decoration chain cannot be too long, otherwise it will affect the efficiency.
- Only when necessary to use the decorator mode, otherwise it will increase the complexity of the program, increase the difficulty of system maintenance.
- Both the adorner object and the adorner object inherit component, and if the component changes internally, all subclasses are changed.
The above describes the design patterns in Symfony2: Decorator mode, including the Symfony2, decorator mode content, I hope that the PHP tutorial interested in a friend helpful.