This article will introduce the decorator pattern (Decorator pattern), which is also known as the wrapper mode (Wrapper pattern), one of the structural patterns that uses a function of dynamically expanding objects in a way that is transparent to the client, It is also one of the alternatives to inheritance, but more flexible than inheritance. In real life can also be seen many examples of decorator patterns, or can be bold to say that the decorator mode everywhere, take a thing, can give it a lot of different layers of shell, but this thing or this thing, Shell is just to expand the function of this thing, this is the decorator mode, The role of the decorator may vary, but the object being decorated is immutable.
Our goal is to allow classes to be scaled uniformly, and to match new behavior without modifying existing code. What are the benefits of achieving such a goal? Such a design is resilient, can cope with changes, and can accept new functions to respond to changing needs, namely the open and closed principles of the OO principle for extended openness and modification closure.
Reprint Please specify source: http://blog.csdn.net/self_study/article/details/51591709.
PS: With the technology of interest in the same shoe plus group 5,446,459,721 Exchange
Total catalog of design patterns
Java/android design mode Learning Notes directory
features
Dynamically adding some additional responsibilities to an object, the adorner pattern is more flexible than generating subclasses, providing a different alternative to inheritance, as far as adding functionality is concerned.
Decorator mode can be static or can be dynamically extended to an object at run time, as needed. The decorators and the many decorators are inherited from an interface, and they have the same behavioral characteristics. Decorator mode is another way of inheriting, which is to add new behavior to the class at compile time, and this change will affect all the original entities of that class, the decorator pattern is different, it provides a function that can choose to run the object at runtime. The difference between decorator mode and inheritance is particularly important in the case of some extended functions, where classes cannot be created at run time in some object-oriented programming languages, and often unpredictable when expansion is required, which means that the class needs to be created in every possible case, So in contrast, the decorator pattern has the advantage that each decorator is an object that is created at run time and can be combined as needed each time it is used.
UML class Diagram
Now let's look at the UML class diagram for decorator mode:
Decorator mode has four main roles:
- Component: Abstract Components
It can be an interface or an abstract class, which acts as the original object that is being decorated, and is used to define the basic behavior of the decorator and the adorned person.
- Concretecomponent: component-specific implementation class
This class is the basic implementation of the Component class, and it is also the specific object we decorate.
- Decorator: Abstract Decorator
Decorates a Component object, which must have a reference to the Component object inside it. In most cases, this class is abstract and requires different specific subclasses to be implemented according to different adornment logic. Of course, if it is a single decoration logic, there is only one case where we can ignore the class directly as a concrete decorator.
- Concretedecoratora and Concretedecoratorb: Decorator Concrete Implementation Class
The concrete implementation of the abstract decorator.
In the existing Component and concretecomponent system, the implementation of decorator mode to extend the functionality of the original system, can be divided into 5 steps
- Inherit or implement Component component, generate a Decorator decorator abstract class;
- In the generated Decorator decorator class, add a Component private member object;
- Pass Concretecomponent or other objects that need to be decorated into the Decorator class and assign values to the Component object in the previous step;
- In the Decorator Decorator class, all operations are replaced by the corresponding operation of the Component object;
- In the Concretedecorator class, overwrite the method that needs to be overridden, as appropriate.
Decorator mode is also used in the source code is very much, in Java and Android can see the decorator pattern Shadow:
decorator mode in Java
The most typical is the Java java.io package under the InputStream and OutputStream related classes, when beginners Java, see these classes, the head is big, in fact, after learning the decorator pattern, then understand these classes is very simple, draw a simple class diagram to represent:
The InputStream class is an abstract component, and the Fileinputstream,stringbufferinputstream and Bytearrayinputstream classes are specific components that can be wrapped by decorators. FilterInputStream is an abstract decorator, so its four sub-categories are decorated by one another.
decorator mode in Android
Second, for Android development engineers, the most important thing is the "God Class" Context and its subclasses, these classes I do not have to explain, the previous class diagram is basically clear:
So for application,activity and Service class, they are just a decorator, are used to decorate Contextimpl This is the decorator class, application is in In the Createbasecontextforactivity method, Createactivitycontext obtains a Contextimpl instance object through the static method of the Contextimpl, and Setoutercontext method to correlate the two, the activity is a Contextimpl instance set by the Handlelaunchactivity method, which gets to an Activity object, In the Performlaunchactivity function will call the activity of the attach method, this method to a Contextimpl object attach to the activity, specifically can see my this blog, in detail to the Activity startup process: Android cannot update UI discussions and analysis in child threads. Other classes here do not introduce, specific people can go online to check the relevant information.
Example and source code
We have a graphical system in the window as an example, the general situation of Windows can be vertical or left and right, so in order to better support the window sliding, to the sliding window plus a ScrollBar is a good way, in order to reuse the code, horizontal sliding window and vertical sliding window we can use decorator mode to process, the basic class diagram is as follows:
Based on the class diagram, we first implement the Window interface:
Iwindow.class
publicinterface IWindow { void draw(); String getDescription();}
Then there is the decorator Simplewindow class, which implements the basic behavior of the window:
Simplewindow.class
publicclass SimpleWindow implements IWindow { @Override publicvoiddraw() { Log.e("shawn""drawing a window"); } @Override publicgetDescription() { return"a window"; }}
Then there is the abstract parent class for the Decorator class role:
Windowdecorator.class
public abstract Span class= "Hljs-class" >class windowdecorator Span class= "Hljs-keyword" >implements iwindow { private iwindow window; public windowdecorator (Iwindow window) {this . window = window; } @Override public void draw () {Window.draw (); } @Override public String getdescription () {return window.getdescription (); }}
Finally, the decorator subclass that implements the decorator's parent class:
Horizontalscrollbardecorator.class
Public class horizontalscrollbardecorator extends windowdecorator { Public Horizontalscrollbardecorator(Iwindow window) {Super(window); }@Override Public void Draw() {Super. Draw (); LOG.E ("Shawn","then drawing the horizontal scroll bar"); }@Override PublicStringgetdescription() {return Super. GetDescription () +"with horizontal scroll bar"; }}
Verticalscrollbardecorator.class
Public class verticalscrollbardecorator extends windowdecorator { Public Verticalscrollbardecorator(Iwindow window) {Super(window); }@Override Public void Draw() {Super. Draw (); LOG.E ("Shawn","then drawing the vertical scroll bar"); }@Override PublicStringgetdescription() {return Super. GetDescription () +"with vertical scroll bar"; }}
Final Test code:
Switch (v. GetId()) {case R. ID. BTN_horizontal_window:iwindow Horizontalwindow = new Horizontalscrollbardecorator (new Simplewindow ());Horizontalwindow. Draw();Log. E("Shawn","window Description:"+ Horizontalwindow. GetDescription()); Break;Case R. ID. BTN_vertical_window:iwindow Verticalwindow = new Verticalscrollbardecorator (new Simplewindow ());Verticalwindow. Draw();Log. E("Shawn","window Description:"+ Verticalwindow. GetDescription()); Break;}
Results:
com. Android. DecoratorpatternE/shawn:drawing a windowcom. Android. DecoratorpatternE/shawn:then drawing the horizontal scroll barcom. Android. DecoratorpatternE/shawn:window description:a window with horizontal scroll barcom. Android. DecoratorpatternE/shawn:drawing a windowcom. Android. DecoratorpatternE/shawn:then drawing the vertical scroll barcom. Android. DecoratorpatternE/shawn:window description:a window with vertical scroll bar
Code at a glance, structure clear.
In fact, every person who wrote the Android program should have used the decorator mode, because each write an Activity, it is equivalent to write a decorator class, inadvertently used the decorator mode, we think is not, haha ~ ~
Summary
Decorator mode and proxy mode is a bit similar, many times need to carefully identify, easy to confuse, not to say that the proxy model as a decorator mode, but will be the decorator mode as a proxy mode. To differentiate, the decorator pattern is designed to transparently extend functionality to client objects, which is an alternative to inheritance, whereas proxy mode provides a proxy object for an object, and the proxy object controls the reference to the original object. The adorner pattern should be enhanced for the adorned object, and the proxy mode imposes control on the agent's objects, but does not enhance the functionality of the object itself.
At the same time, there are several points to mention:
- Inheritance is one of the extension forms, but it is not necessarily the best solution to achieve elastic design;
- In our design, we should try to close the modification, develop the extension without modifying the existing code;
- Combinations and delegates can be used to dynamically add new behavior at run time;
- The decorator can add his or her actions according to the actual situation before and after the act of the decorator, and can replace the behavior of the decorator if necessary;
- Can be used by countless decorators to package a component, that is, the decorator a packaging is decorated B, decorator C re-packaging decorator A, according to the actual situation this behavior can be added to multilayer, popular speaking is a multi-layered shell;
- At the same time, the decorator can also exist multiple, that is to say concretecomponent this role can also be multiple.
The advantage of Decorator mode is its feature: it can be dynamic at runtime, transparent for a component extension function, more flexible than inheritance, the disadvantage is also obvious: it will lead to a lot of small objects in the design, if overused, it will complicate the program.
Source Download
Https://github.com/zhaozepeng/Design-Patterns/tree/master/DecoratorPattern
References
Https://en.wikipedia.org/wiki/Decorator_pattern
http://blog.csdn.net/jason0539/article/details/22713711
Java/android Design Patterns Learning notes (7)---decorator mode