The decorative mode _c language of C + + design pattern

Source: Internet
Author: User
Tags class definition exception handling explode extend inheritance

Objective

In actual development, have you ever encountered such a problem; develop a class that encapsulates the core operations of an object that are invoked by the customer when the class is used, while some non-core operations may or may not be used; now what?

1. Put these non-core operations all into the class, so that a class contains a lot of core operations and some seemingly relevant, but unrelated operations; This will cause the core class to "explode" phenomenon, so that the core class lost some value, but also the use of core classes of customers in core operations and non-core operations struggle;

2. Use inheritance to extend core classes, the core class object is established directly when the core class is used, and the core class extension object is established when the core class extension class is needed; This seems to be a very effective method; but because inheritance is a static trait introduced by type, it makes this extension inflexible; Another trap has fallen, and as the expansion function increases, so does the subclass, the combination of each seed class, will cause the expansion of the class, and finally, will be submerged in the class of the sea; At this time, I do not need to say, you are not reminded of the bridge mode, bridging mode is to adapt to the changes in multiple dimensions of the sub-class "Explosion" situation, However, bridging patterns are designed to accommodate different abstractions and implementations, and do not apply to what I'm talking about here. So what is the good, this is about the summary of the decoration model today.

What is a decorative pattern?

In Gof's "design pattern: The basics of reusable object-oriented software," This is said in a book about decorating patterns: Dynamically adding additional responsibilities to an object. Decorator mode is more flexible than generating subclasses in terms of adding functionality.

Decorative mode can be implemented dynamically for the object to add functionality, from the outside of an object to add functionality to the object. You usually add functionality to an object, either directly modify the object to add the appropriate functionality, or derive the corresponding subclass to extend it, or use the object combination. Obviously, it is not advisable to modify the corresponding class directly. In object-oriented design, we should also try to use object composition rather than object inheritance to extend and reuse functionality. The adorner pattern is based on the combination of objects, and it is flexible enough to add the required functionality to the object. The essence of the adorner pattern is the dynamic combination. Dynamic is the means, the combination is the purpose. In short, the decorative pattern is a pattern that is dynamically combined as needed by simplifying and dispersing complex functions and then running them. It allows us to add some functionality to an object rather than to an entire class.

UML Class Diagram

Component: Defines an object interface that can dynamically add responsibilities to these objects;

Concretecomponent: Define a concrete component, inherit from Concreatecomponent, rewrite the virtual function of component class;

Decorator: Maintains a pointer to a component object that points to an object that needs to be decorated, and defines an interface that is consistent with the component interface;

Concretedecorator: Add responsibilities to components.

Code implementation:

Copy Code code as follows:

/*
* * Filename:decoratorpatterndemo
* * author:jelly Young
* * DATE:2013/12/19
* * Description:more information, http://www.jb51.net
*/
#include <iostream>
using namespace Std;
Class Component
{
Public
virtual void Operation () = 0;
};
Class Concretecomponent:public Component
{
Public
void Operation ()
{
cout<< "I am no decoratored concretecomponent" <<endl;
}
};
Class Decorator:public Component
{
Public
Decorator (Component *pcomponent): M_pcomponentobj (pcomponent) {}
void 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 (pdecorator) {}
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;
}

Use occasion

1. Add responsibilities to a single object in a dynamic, transparent manner without affecting other objects;
2. Dealing with those functions which can be revoked;
3. When it is not possible to expand using the method of generating subclasses. One scenario is that there may be a large number of independent extensions, and a large number of subclasses will be generated to support each combination, making the number of subclasses explode. Another scenario might be because the class definition is hidden, or the class definition cannot be used to generate subclasses.

Attention matters

1. Interface consistency; The interface of a decorative object must be the same as the component interface it decorates, so all concretedecorator classes must have a common parent class, which is a unified interface for the user;

2. Omit the abstract decorator class; It is not necessary to define an abstract decorator class when only one responsibility needs to be added. Because we often have to deal with the existing class hierarchy rather than designing a new system, we can combine the responsibility of decorator to the component forwarding request into Concretedecorator;

3. Maintain the simplicity of the component class; To ensure interface consistency, components and decorations must have a common component class, so it is important to maintain the simplicity of the component class, so This component class should focus on defining interfaces rather than storing data. The definition of data representation should be deferred to subclasses, otherwise the component class becomes overly complex and bloated, making it difficult to use extensively. Given the component class too many functions, but also make specific subclasses have some of them they do not need to greatly increase the functionality;

Implementation Essentials

The 1.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 classes do not need to know the decorator class, the decorator class is to extend the function of the component class from the outside;

The 2.Decorator class behaves as an inheritance of the "is-a" component on the interface, that is, the decorator class inherits the interface that the component class has. However, in the implementation of the "has-a" component is a combination of relations, that is, decorator class and the use of another component class. We can use one or more decorator objects to "decorate" a Component object, and the decorated object is still a Component object;

3.Decortor mode is not to solve the problem of "multi-subclass-derived multiple inheritance", the key point of the decorator mode is to solve "the extension function of subject class in multiple directions"-----------------"decoration";

4. The application 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 to combine the responsibilities of decorator and Concretedecorator into a single class.

The advantage of 5.Decorator mode is that it provides a more flexible extension than inheritance, and can create a combination of many different behaviors by using different specific decorative classes and the permutations and combinations of these decorative classes.

6. Because of the use of decorative patterns, more than a few target classes are required to use inheritance relationships. Using fewer classes, of course, makes the design easier to do. However, on the other hand, using decorative mode produces more objects than using inheritance relationships. More objects make it difficult to find errors, especially if they look alike.

The difference from bridging mode

Before summarizing the C + + design mode-bridging mode; you will find that both are designed to prevent excessive inheritance, resulting in the spread of subclasses. So what are the main differences between the two? Bridging mode is defined as separating abstraction from implementation (in a combination rather than an inherited way), allowing the two to change independently. You can reduce the growth of your derived classes. If the light from this point of view, and the decoration is similar, but there are some important differences between the two:

1. The separation in the bridging mode, in fact, it means separating the structure from the implementation (when the structure and implementation are likely to change) or attributes being separated from the property based behavior, while the decorator simply closes the property based behavior into a separate class to decorate it, that is, to extend it. For example: The exception class and the exception handling class can use the bridge pattern to accomplish, but cannot use the adornment pattern to carry on the design; if we need to extend the handling of the exception, we can add decorator to the exception handling class to add the processing decoration to the extension of exception handling. This is a bridge mode and decorative mode of collocation;

2. The behavior in bridging is horizontal behavior, the behavior is not related to each other, note that there is no correlation between the behavior here, for example, there is no behavioral association between exception and exception handling, and the behavior in the decorator pattern is additive, and the result is a whole, a result of the combination of each behavior.

Summarize

The

Decorative mode focuses on decoration, the decorative function of the core functions; Converts the extension of the subclass in inheritance into a combination of functional classes, thus passing on the extension of the subclass to the user to make the invocation combination, and how the user is to be grouped by the user. When I study the decoration mode, I focus on analyzing the word "decoration", we all know that decoration is a core function to add some ancillary functions, so that the core function to play a greater role, but ultimately its core functions can not be lost. This is like when we were doing Windows shell development, we were decorating the shell of windows to achieve 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, make it look more beautiful and perfect.

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.