If you are engaged in object-oriented PHP development, even a short time or simply through the book, you will know that you can change or add a class function through inheritance, which is a basic feature of all object-oriented languages. If a PHP class that already exists lacks some methods, or needs to add more functionality (glamour) to the method, you might just inherit the class to produce a new class--which is built on extra code.
But it is not always possible or appropriate to produce subclasses. What do you do if you want to change the behavior of an already initialized object? Or, what do you want to do with the behavior of many classes? The previous one can only be done at run time, the latter is obviously possible, but may lead to a large number of different classes-terrible things.
Problem
How do you organize your code so that it can easily add basic or some rarely used features, rather than writing directly without extra code inside your class?
Solution
The adorner pattern provides a flexible scheme for changing subclasses. The adorner pattern allows you to modify objects dynamically without causing the number of subclasses to explode, adding attributes.
Adorner mode is more useful when used with a set of subclasses. If you have a family of subclasses (derived from a parent class), you need to add additional features to separate use with subclasses, and you can use adorner patterns to avoid code duplication and increase in the number of specific subclasses. Take a look at the following examples, you can better understand this view. Consider a "form" form library built on the concept of components where you need to create a class for each form control type that you want to represent. This class diagram can be as follows:
The Select and TextInput classes are subclasses of the component classes. If you want to add a "labeled" Tagged component-an input form tells you what to enter. Because any form may need to be marked, you may inherit every specific component like this:
The class diagram above does not look very bad, so let's add some more features here. Form validation phase, you want to be able to indicate whether a form control is legitimate. The code you use for illegal control inherits other components again, so you need to generate a large number of subclasses:
This class doesn't look too bad, so let's add some new features. In structural validation you need to indicate whether the structure is valid. The code you need to validate your validation can also be applied to other parts so that no more subclasses are validated.
Sub-class overflow is not the only problem here. Think of the repetitive code and you need to redesign your entire class hierarchy. There is no better way! Indeed, the adorner pattern is a good way to avoid this situation.
The adorner pattern is structurally similar to the proxy mode (see chap. 2nd). An adorner object retains a reference to the object and faithfully re-establish the public interface of the object being decorated. Adorners can also add methods, extend the interface of the decorated object, arbitrarily overload methods, and even conditionally overloaded methods during script execution.
To explore the adorner pattern, let's take the example of the Form component library discussed earlier and implement the "lable" and "invalidation" two attributes with an adorner pattern instead of inheritance.
Sample code:
What features are included in the component library?
Easy to create form elements
Output a table cell as HTML
Implement simple validation on each element
In this case, we create a form that contains the last name, the name, the email address, and the entry. All areas are required, and e-mail must appear to be a valid e-mail address. In the HTML language, the code for the form looks like the following:
<form action=”formpage.PHP” method=”post”>
<b>First Name:</b> <input type=”text” name=”fname” value=””><br>
<b>Last Name:</b> <input type=”text” name=”lname” value=””><br>
<b>Email:</b> <input type=”text” name=”email” value=””><br>
<input type=”submit” value=”Submit”>
</form>
After adding some CSS styles, the form renders as shown in the following illustration:
To establish a unified API, we create a basic component class (if this is an example of php5, this might use an interface). Since all components (form elements) must render some output, the build class can have only one paint () method.
class Widget {
function paint() {
return $this->_asHtml();
}
}