Turn: Http://www.jellythink.com/archives/171#prettyPhoto What is decorative mode?
In the book "Design mode: The basis of reusable object-oriented software" in Gof, the decorating mode is said: Dynamically add some extra responsibilities to an object. For added functionality, the decorator mode is more flexible than generating subclasses.
Decorative mode enables the dynamic addition of functions to objects, from the outside of an object to add functionality to the object. It is common to add functionality to an object, either by directly modifying the object to add the appropriate functionality, or by deriving the corresponding subclass to extend, or by using the combination of objects. Obviously, it is not advisable to modify the corresponding class directly. In object-oriented design, we should try to use object composition instead of object inheritance to extend and reuse functionality. Adorner mode is based on the combination of objects, you can be flexible to the object to add the required functionality. The essence of adorner mode is dynamic combination. Dynamic is the means, the combination is the purpose. In short, the decorating pattern is a pattern that simplifies, disperses, and then runs the complex functions as needed to dynamically combine them. It allows us to add some functionality to an object rather than to the entire class.
Component: Defines an object interface that can dynamically add responsibilities to these objects;
Concretecomponent: Defines a specific component, inherits from component, and overrides the virtual function of the component class;
Decorator: Maintains a pointer to a component object that points to the object that needs to be decorated, and defines an interface that is consistent with the component interface;
Concretedecorator: Add responsibilities to the component.
/** * filename:decoratorpatterndemo** author:jelly young** date:2013/12/19** description:more Information, go tohttp://www.jellythink.com*/#include<iostream>using namespacestd;classcomponent{ Public: Virtual voidOperation () =0;};classConcretecomponent: Publiccomponent{ Public: voidoperation () {cout<<"I am no decoratored concretecomponent"<<Endl; }};classDecorator: Publiccomponent{ Public: Decorator (Component*pcomponent): M_pcomponentobj (pcomponent) {}voidoperation () {if(M_pcomponentobj! =NULL) {M_pcomponentobj-operation (); } }protected: Component*m_pcomponentobj;};classConcretedecoratora: Publicdecorator{ Public: Concretedecoratora (Component*pdecorator): Decorator (pdecorator) {}voidoperation () {Addedbehavior (); Decorator::operation (); } voidAddedbehavior () {cout<<"This is added behavior A."<<Endl; }};classConcretedecoratorb: Publicdecorator{ Public: Concretedecoratorb (Component*pdecorator): Decorator (pdecorator) {}voidoperation () {Addedbehavior (); Decorator::operation (); } voidAddedbehavior () {cout<<"This is added behavior B."<<Endl; }};intMain () {Component*pcomponentobj =Newconcretecomponent (); Decorator*PDECORATORAOJB =NewConcretedecoratora (pcomponentobj); PDECORATORAOJB-operation (); cout<<"============================================="<<Endl; Decorator*PDECORATORBOJB =NewConcretedecoratorb (pcomponentobj); PDECORATORBOJB-operation (); cout<<"============================================="<<Endl; Decorator*PDECORATORBAOJB =NewConcretedecoratorb (PDECORATORAOJB); PDECORATORBAOJB-operation (); cout<<"============================================="<<Endl; DeletePDECORATORBAOJB; PDECORATORBAOJB=NULL; DeletePDECORATORBOJB; PDECORATORBOJB=NULL; DeletePDECORATORAOJB; PDECORATORAOJB=NULL; DeletePcomponentobj; Pcomponentobj=NULL;}Use occasions
- Add responsibilities to individual objects in a dynamic, transparent manner without affecting other objects;
- Handle those duties that can be revoked;
- When a method of generating subclasses cannot be used for expansion. One scenario is that there may be a large number of independent extensions that will produce a large number of subclasses to support each combination, resulting in an explosive increase in the number of subclasses. Another situation may be because the class definition is hidden, or the class definition cannot be used to generate subclasses.
Precautions
- Interface consistency, the interface of the adornment object must be consistent with the interface of the component it decorates, so all concretedecorator classes must have a common parent class, so for the user, it is the unified interface;
- Omit the abstract decorator class; It is not necessary to define an abstract decorator class when only one task needs to be added. Because we often have to deal with the existing class hierarchy rather than designing a new system, you can combine the duties of decorator forwarding requests to component into Concretedecorator;
- To maintain the simplicity of the component class, in order to ensure the consistency of the interface, the components and decorations must have a common component class, so it is very important to maintain the simplicity of this component class, so This component class should focus on defining interfaces rather than storing data. The definition of the data representation should be deferred to the subclass, otherwise the component class becomes overly complex and bloated, making it difficult to use heavily. Given the component class too many functions, but also makes the specific subclasses have some of them they do not need the function greatly increased;
Implementation Essentials
- The component class acts as an abstract interface in decorator mode and should not implement specific behavior. And the decorator class should be transparent to the component class, in other words component class does not need to know decorator class, decorator class is the function of extending component class from outside;
- The Decorator class behaves as an inheritance of the "is-a" component on the interface, that is, the decorator class inherits the interfaces that the component class has. But in the implementation of the "HAS-A" component the combination of the relationship , that is, decorator class and another component class used. We can use one or more decorator objects to "decorate" a Component object, and the decorated object is still a Component object;
- Decortor mode is not to solve the problem of "multiple inheritance of multi-subclass", the application of decorator mode is to solve the "expansion function of principal class in multiple directions"--meaning of "decoration";
- The use of the decorator model in practice can be very flexible. If there is only one concretecomponent class and no abstract component class, then the decorator class can be a subclass of Concretecomponent. If there is only one Concretedecorator class, then there is no need to create a separate decorator class, but you can combine the responsibilities of decorator and Concretedecorator into a single class.
- The advantage of the decorator model is that it provides a more flexible extension than inheritance, and can create a combination of many different behaviors by using different decoration classes and arranging combinations of these decorations.
- Because of the use of adornment mode, a smaller number of destination classes are required than using inheritance relationships. The use of fewer classes, of course, makes the design easier to carry out. However, on the other hand, using the adornment pattern produces more objects than using the inheritance relationship. More objects make it difficult to find errors, especially when they look alike.
The difference from bridging mode
Previously summed up the C + + design mode-bridging mode; you will find that both are designed to prevent excessive inheritance, which can lead to the proliferation of subclasses. So what is the main difference between the two? Bridging mode is defined as the separation of abstraction from implementation (in a combination of ways rather than inheritance), so that the two can change independently. You can reduce the growth of derived classes. If light from this point of view, and the decorator is similar, but there are some more important differences between the two:
- The separation in bridging mode refers to the separation of the structure from the implementation (when the structure and the implementation are likely to change) or the property-based behavior, whereas the decorator simply encloses the attribute-based behavior as a separate class to be decorated, that is, extended. For example, the exception class and the exception handling class can use bridging mode to achieve the completion, but not the use of decorative mode to design, if the exception processing needs to be extended, we can add decorator to the exception handling class, to add processing decoration, to achieve exception handling extension, This is a bridging mode and decorative mode collocation;
- The behavior in bridging is the horizontal behavior, the behavior is not related to each other, note that there is no correlation between the behavior, such as exception and exception handling is not the same as the behavior correlation, and the adorner pattern behavior has the superposition, the result is a whole, a result of the combination of each behavior.
Summarize
Decoration mode focuses on decoration, the role of the core function of the decoration; the extension of the subclass in the inheritance is transformed into a combination of functional classes, which will pass the extension of the subclass to the user to make the call combination, how the user can be combined by the user to decide. When I was learning the decorative pattern, I was focusing on the word "decoration", and we all know that decorating is a core function that adds some ancillary functions to make the core function play a bigger role, but ultimately its core functionality cannot be lost. This is just like when we were doing Windows shell development, we were decorating the shell of Windows, which enabled some of the decorative features we needed, but the final feature was done by the Windows shell. This is like, our decoration is to add a layer of the core function of the coat, make it look more beautiful and perfect.
[design mode] 9 Decorator mode Decorator