. Net: A Brief Introduction to the design pattern (the decorator pattern)

Source: Internet
Author: User

In fact, it is a bit difficult to understand the decorator mode, especially for beginners, because its concepts conflict with each other and where conflicts exist.

I keep my consistent writing style and focus on getting started. In my own articleArticleWe will use a more appropriate metaphor to solve the problem. The example is simple but highlights.

Before I wrote this article, I searched some articles on the Internet about the "decorating by mode", but the results were not satisfactory. Either by finding a book or creating a new example of a book. I have read about three or four articles. The author of the article wants to clarify the key points of the problem, but rarelyCodeOn the basis of the above, it is just a matter of fact. If you fail to clearly introduce any part of the pattern code, it may bring new problems to the beginners who read the article, and fail to fully reflect the focus of the article. Next we will start from clarifying our clues.[Wang qingpei has all rights reserved. For more information, please sign it.]

The design pattern is a method to solve a certain problem. A pattern corresponds to a problem. For example, the observer pattern is used to solve one-to-many relationships, which are the function of "moving the whole body.

The design model books we read are a collection of problems and a collection of design patterns. Before we can integrate them, we must understand these ideas separately. When we can master these design patterns, we can design a good system architecture. Patterns are the same, while "Design Principles" are the foundation of model innovation. Most of the models in the book are used to consider some small examples. If they are used in real projects, they need to be combined with the use of the entire design model. So when we learn some small design patterns, we don't need to talk about anything else. First, we need to understand what the real idea of our current model is.

Decorator mode definition:Dynamically attach duties to objects. To expand functions, the decorators provide alternative solutions that are more flexible than inheritance;

This is an official definition of the decorator model. We can basically understand what it means. It is nothing more than dynamically adding functions to the objects to be extended, instead of inheriting but using a combination.This is the first question that comes to our beginners. It is to use combinations instead of inheritance to extend the functions of objects.. When we first came into contact with the decorator model, we kept an eye on this sentence, because we kept an eye on this sentence, so we always carried this theory in the following process of thinking, so I can't understand it. Friends should not remember this theory first, and never remember any theoretical model first. I will use a metaphor to gradually let you understand what the real meaning of the decorator model is.

Please enter my learning mode. Here I will give a metaphor. If I want to decorate my house now, I want to decorate a lamp on the ceiling. We all know that all the lights on the ceiling need to be decorated with lamps. Here we have introduced the concept of decoration, so let's analyze the problem. The bulbs in the lamps remain unchanged, and we have introduced a key concept: the objects to be decorated. The lightbulb is available when we decorate it. The lamps can be replaced at any time. Here we form a prototype of the typical decorating mode. See the figure below:[Wang qingpei has all rights reserved. For more information, please sign it.]

1:

The light bulb inside is the decorator, And the lamps outside are the decorator. We have basically understood the meaning of the Paster mode. Next we will use the code to simulate the Paster mode.

Lightbulb code:

Using system; using system. collections. generic; using system. text; namespace consoleapplication1 {public class bulb {public int bulb model {get {return 10 ;}} Public String light bulb () {return "Bulb lit ";}}}

 

Don't ask why the lightbulb class is not abstract. Here we will not discuss other principles. Let's clarify the decorator mode and I will introduce your confused concepts later.

This is the light bulb code, which is very simple. It represents the properties of the light bulb model and a method for lighting the light bulb. Let's look at the lightbulb decoration code.

Code for rectangular lamps:

Using system; using system. collections. generic; using system. text; namespace consoleapplication1 {public class rectangular luminaire {// <summary> // reference of the lightbulb /// </Summary> private lightbulb dengpaoobject; /// <summary> /// since it is a lamp decoration, it must be able to accommodate the light bulb, therefore, the lightbulb must reference the lightbulb. // </Summary> // <Param name = "D"> lightbulb instance </param> Public void) {dengpaoobject = D ;} /// <summary> /// open the feeling of a rectangle-mounted luminaire /// </Summary> /// <returns> added after decoration </returns> Public String effect of opening a rectangular luminaire () {return dengpaoobject. light bulb () + ", the light emitted by a rectangular luminaire ";}}}

Polygon luminaire code:

Using system; using system. collections. generic; using system. text; namespace consoleapplication1 {public class polygon luminaire {//< summary> /// reference of the lightbulb /// </Summary> private lightbulb dengpaoobject; /// <summary> /// since it is a lamp decoration, it must be able to accommodate the light bulb, therefore, the lightbulb must reference the lightbulb. // </Summary> // <Param name = "D"> lightbulb instance </param> Public void) {dengpaoobject = D ;} /// <summary> /// open the feeling of a rectangle-mounted luminaire /// </Summary> /// <returns> added after decoration </returns> Public String turn on the effect of a polygon luminaire () {return dengpaoobject. light bulb () + ", the light emitted by a polygon lamp ";}}}

 

Rectangular shadow lamps:

Using system; using system. collections. generic; using system. text; namespace consoleapplication1 {public class rectangular shadow luminaire {// <summary> // reference of the lightbulb /// </Summary> private lightbulb dengpaoobject; /// <summary> /// since it is a lamp decoration, it must be able to accommodate the light bulb, therefore, the lightbulb must reference the lightbulb. // </Summary> // <Param name = "D"> lightbulb instance </param> Public void) {dengpaoobject = D ;} /// <summary> /// open the feeling of a rectangle-mounted luminaire /// </Summary> /// <returns> added after decoration </returns> Public String turn on the effect of a polygon luminaire () {return dengpaoobject. light bulb () + ", the light emitted by a rectangular shadow lamp ";}}}

 

Don't ask why the decorative lamps do not inherit the above bulbs. The reason why I explain this is to bypass the trap that brings us confusion in understanding. Continue to read it and you will be able to fully understand it.

There is no inheritance between the decorator and the decorator. The official explanation of the "decorator mode" means that it only expands the object's responsibilities through combination. Under normal circumstances, we must use inheritance to solve the decoration problem of lamps. How many lamps inherit from the lightbulb class, however, this inclusion method bypasses the coupling problem caused by inheritance. The above code is far from complete. Let's look at what problems will happen later.

 Effect of model lamps:

Using system; using system. collections. generic; using system. text; namespace consoleapplication1 {class program {static void main (string [] ARGs) {bulbs dengpao = new bulbs (); rectangular lamps juxingdengju = New Rectangular lamps (); juxingdengju. add the decorative lightbulb (dengpao); console. writeline (juxingdengju. turn on the effect of the rectangular luminaire (); console. readline (); polygon luminaire duobianxingdengju = new polygon luminaire (); duobianxingdengju. add the decorative lightbulb (dengpao); console. writeline (duobianxingdengju. open the effect of the polygon luminaire (); console. readline (); rectangular shadow lamps yinyingdengju = new rectangular shadow lamps (); yinyingdengju. add the decorative lightbulb (dengpao); console. writeline (yinyingdengju. open the effect of the polygon luminaire (); console. readline ();}}}

2:

From the above lighting examples, we have basically finished the simulation of the modifier mode. However, such code has poor scalability,Interface-Oriented ProgrammingBut we do not seem to see the interface here. All the code in this example is directly using the object name, which must be coupled. We will continue to extend the problem to solve the dilemma of your first article, where are the abstract classes, interfaces, and inheritance. I always think the example code is too simple. What is the design pattern. Don't rush to continue the discussion. The design model is originally an ideological theory and requires patient research.

Our lightbulb is a solid class rather than an abstract class. This shows that our lightbulb design is unreasonable. If the light bulb is a semi-finished product, this semi-finished product cannot be used directly, any modifier must be modified before it can be used. Therefore, our lightbulb class is abstract;

So why do we need to use the decorator to inherit the decorator? In fact, the simple reason is that there is no unified interface. We assume that the light bulb can only be opened in one way, and no lamp can modify this unified interface without authorization. This interface is defined by the lightbulb manufacturer. For example, some current, voltage, and line principles cannot be directly modified. Only the object inherited from the decorator Can I use the decorator's conventions, such as the name of a method and the name of an attribute. When we use it, we use the method of the decorator, which breaks the agreement.

There is also why we don't use interfaces, so we can extend the use of interfaces. If a lamp can be decorated with many kinds of bulbs, a unified interface is required to constrain these essential conditions. For example, a lamp can only be decorated with a large light bulb or a type of light bulb;

I will give a rough description of the above issues. Next we will make some modifications to the Code to make it look like the "modifier mode ".

The changed lightbulb code:

 
Using system;
Using system. Collections. Generic;
Using system. text;
Namespace consoleapplication1
{
Public interface lightbulb Series
{
Int bulb model {Get ;}
String turn on the light ();
}
Public abstract class lightbulb: lightbulb Series
{
Public int bulb Model
{
Get {return 10 ;}
}
Public Virtual string turn on the light ()
{
Return "the light bulb has been lit ";
}
}
Public class red light bulb: light bulb
{
Public int bulb Model
{
Get {return 10 ;}
}
Public override string turn on the light ()
{
Return "red light bulb ";
}
}
}

Code of the changed rectangle lamp:

 
Using system;
Using system. Collections. Generic;
Using system. text;
Namespace consoleapplication1
{
Public class rectangular lamps: bulbs
{
/// <Summary>
/// Lightbulb reference
/// </Summary>
Private bulb series dengpaoobject;
/// <Summary>
/// Since it is a lamp decoration, it must be able to accommodate the light bulb, so the lamp must reference the light bulb
/// </Summary>
/// <Param name = "D"> lightbulb instance </param>
Public void: Add a lightbulb for decoration (bulb D)
{
Dengpaoobject = D;
}
Public override string turn on the light ()
{
Return dengpaoobject. Turn on the light () + ", plus the rectangular Lighting Effect ";
}
}
}

I will not post the code of the other lamps.

Call code:

Using system; using system. collections. generic; using system. text; namespace consoleapplication1 {class program {static void main (string [] ARGs) {red bulb reddengpao = new red bulb (); // bulb rectangular luminaire juxingdengju = New Rectangular luminaire (); // decorative polygon luminaire duobianxingdengju = new polygon luminaire (); // decorative duobianxingdengju. add the decorated bulb (reddengpao); juxingdengju. add the decorated lightbulb (duobianxingdengju); console. writeline (juxingdengju. turn on the light (); console. readline ();}}}

3:

The modifier mode is similar. Interfaces, inheritance, and polymorphism are used to eliminate coupling between classes and inherit objects, polymorphism is used to dynamically add responsibilities to lamps. Some features in the mode vary with the environment, and sometimes interfaces are not required at all, but interface programming is required for multi-type extension.

Summary: I personally think there are not many occasions for the modifier mode. inheritance is to take object behavior and then reference an instance of an object separately, in this way, the memory of an object is wasted. Simple decorators do not need to inherit objects. If they need to be called in a unified manner, they need to inherit objects. interfaces are only used to indicate that the decorators can not only decorate a certain object, but also a certain type of objects. You can modify the mode as needed to adapt to the current environment.

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.