[C + + design mode] Decorator Decorator mode

Source: Internet
Author: User

Example of head first: coffee shops have a variety of coffee drinks, can be added to the coffee in a variety of spices into another drink, if the use of inheritance to design a class for each beverage, the complexity of the code can easily expand, and will inherit all the attributes of the parent class, due to the inheritance of the type introduced static characteristics, The lack of flexibility in this way of scaling, while also falling into another trap, as the expansion function increases, the subclass will increase, the combination of each seed class will cause the expansion of the class, and finally, will be submerged in the class of the ocean.

At this time, the great gods invented the decorator mode, without modifying the existing interface and implementation of the class based on the implementation of the function or state Add.

Decorator (Decorator mode): Dynamically adds some additional 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.


Usage scenarios:

1. Add responsibilities to individual objects in a dynamic, transparent manner without affecting other objects;

2, handling those duties that can be revoked;

3, when the method of generating subclasses cannot be expanded. 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.

Example code:

#include <iostream>using namespace Std;class component{public:virtual void operation () = 0;}; Class Concretecomponent:public Component{public:void operation () {cout<< "I am no decoratored Co     Ncretecomponent "<<endl; }};class decorator:public component{public:decorator (Component *pcomponent): M_pcomponentobj (pComponent) {} VO          ID operation () {if (m_pcomponentobj! = NULL) {m_pcomponentobj->operation (); }}protected:component *m_pcomponentobj;}; Class Concretedecoratora:public Decorator{public:concretedecoratora (Component *pdecorator): Decorator (pdecorator) {          } void operation () {Addedbehavior ();     Decorator::operation (); } void Addedbehavior () {cout<< "This is added behavior A."     <<endl; }};class concretedecoratorb:public Decorator{public:concretedecoratorb (Component *pdecorator): Decorator (PDecorato R) {}    void operation () {Addedbehavior ();     Decorator::operation (); } void Addedbehavior () {cout<< "This is added behavior B."     <<endl;     }};int Main () {Component *pcomponentobj = new Concretecomponent ();     Decorator *PDECORATORAOJB = new Concretedecoratora (pcomponentobj);     Pdecoratoraojb->operation ();     cout<< "=============================================" <<endl;     Decorator *PDECORATORBOJB = new Concretedecoratorb (pcomponentobj);     Pdecoratorbojb->operation ();     cout<< "=============================================" <<endl;     Decorator *PDECORATORBAOJB = new Concretedecoratorb (PDECORATORAOJB);     Pdecoratorbaojb->operation ();     cout<< "=============================================" <<endl;     Delete PDECORATORBAOJB;     PDECORATORBAOJB = NULL;     Delete PDECORATORBOJB;     PDECORATORBOJB = NULL;     Delete PDECORATORAOJB;     PDECORATORAOJB = NULL; Delete PcomponenTobj; Pcomponentobj = NULL;}
Key points of implementation:

1, interface consistency; the interface of the decorative object must be consistent with the interface of the component it decorates, so that all concretedecorator classes must have a common parent class, which is a unified interface for the user;


2, omit abstract decorator class; When you need to add only one responsibility, it is not necessary to define an abstract decorator class. 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;


3, to maintain the simplicity of the component class, in order to ensure the consistency of the interface, 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;


The 4,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 5,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;

6,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";


7, the use of Decorator mode 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 8,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.


9, because of the use of decorative mode, you can use more than the inheritance relationship requires a smaller number of destination classes. 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.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

[C + + design mode] Decorator Decorator mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.