I. Introduction
In software development, we often want to add different features to a class of objects, such as adding film, cell phone pendants, and cell phone casings to the mobile phone. If inheritance is used for implementation at this time, numerous classes need to be defined, for example, StickerPhone is mobile phone, AccessoriesPhone is a mobile phone, and so on, which will lead to the "subclass explosion" problem. To solve this problem, we can useThe modifier mode dynamically adds additional responsibilities to an object.. Next let's take a look at the modifier mode.
Ii. decorator mode details 2.1 Definition
The modifier mode dynamically attaches more responsibilities to an object in a way that is transparent to the customer. The modifier mode provides more flexibility to add features than the subclass generation.
2.2 decorator mode implementation
Here, the example of mobile phone and mobile phone accessories is used to demonstrate the implementation of the decorator mode. The specific code is as follows:
/// <Summary> // mobile abstract class, that is, the abstract component class in the modifier mode. // </summary> public abstract class Phone {public abstract void Print ();} /// <summary> /// Apple mobile phone, that is, the specific component class in the decorative mode. /// </summary> public class ApplePhone: phone {/// <summary> /// rewrite the base class method /// </summary> public override void Print () {Console. writeLine ("start to execute the specific object-Apple mobile phone") ;}/// <summary> /// abstract class for decoration. To replace abstract components completely, therefore, it must inherit from Photo // </summary> public abstract class De Corator: Phone {private Phone phone; public Decorator (Phone p) {this. phone = p;} public override void Print () {if (phone! = Null) {phone. print () ;}}/// <summary> // film, that is, the specific modifier /// </summary> public class Sticker: decorator {public Sticker (Phone p): base (p) {} public override void Print () {base. print (); // Add a new behavior AddSticker ();} // <summary> // new behavior method // </summary> public void AddSticker () {Console. writeLine ("Apple mobile phone now has a film") ;}/// <summary> /// mobile phone pendant /// </summary> public class Accessories: decorator {public Accessories (Phone p): base (p) {} public override void Print () {base. print (); // Add a new behavior AddAccessories ();} // <summary> // new behavior method // </summary> public void AddAccessories () {Console. writeLine ("Now the iPhone has a pretty pendant ");}}
The client call code is as follows:
Class Customer {static void Main (string [] args) {// I bought an Apple Phone number = new ApplePhone (); // now I want to film Decorator applePhoneWithSticker = new Sticker (phone); // expand the film behavior applePhoneWithSticker. print (); Console. writeLine ("---------------------- \ n"); // now I want to have the Decorator applePhoneWithAccessories = new Accessories (phone); // extend the mobile phone pendant behavior applePhoneWithAccessories. print (); Console. writeLine ("-------------------- \ n"); // now I have Sticker sticker = new Sticker (phone); Accessories identifier = new Accessories (sticker); identifier. print (); Console. readLine ();}
From the client code above, the client can dynamically Add the mobile phone accessories to the mobile phone. To add the mobile phone shell, you only need to add a mobile phone shell class that inherits the Decorator, the modifier mode is also highly scalable.
2.3 decorator pattern class diagram
After the decorator mode is completed, let's take a look at the relationship between classes in the decorator mode. For details, see:
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131229/124425E29-0.png "style =" margin: 0px auto; padding: 0px; border: 0px; "alt =" 17163325-519d76e520154cd98326f55f9dbff8e "/>
In the modifier mode, the roles are:
Abstract component Phone) Role: provides an abstract interface to standardize the objects to accept additional responsibilities.
Specific Component AppPhone) Role: defines a class that will receive additional responsibilities.
Describe Dicorator) Role: Hold a Component) object instance, and define an interface consistent with the abstract Component Interface.
Specific decoration of Sticker and Accessories) Roles: Responsible for attaching "additional responsibilities" to component objects.
Iii. Advantages and disadvantages of the decorator Model
After reading the detailed introduction of the modifier mode, we will continue to analyze its advantages and disadvantages.
Advantages:
Both the decoration mode and the inheritance mode aim to expand the object functions, but the decoration mode is more flexible than the inheritance mode.
By using different decorative classes and the arrangement and combination of these classes, designers can create a combination of many different behaviors.
The modifier mode has good scalability.
Disadvantages: The decorator mode will lead to many small objects in the design. Excessive use will make the program more complex. In addition, more objects may become difficult to make mistakes, especially those objects.
Iv. Use Cases
Next let's take a look at the specific circumstances in which the decorator mode is used. In the following cases, the decorator mode should be used:
You need to expand the functions of a class or add additional responsibilities to a class.
You need to dynamically add functions to an object. These functions can be dynamically revoked.
A large number of functions are generated by the arrangement and combination of some basic functions.
V. Implementation of the modifier mode in. NET
In the. NET class library, there is also the implementation of the modifier mode, which is System. IO. Stream. Let's look at the Stream class structure:
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131229/12442543I-1.png "style =" margin: 0px auto; padding: 0px; border: 0px; "alt =" 17172236-9d9ca054f0904841954571_ef51ab "/>, bufferedStream, CryptoStream, and GZipStream are actually two specific decoration classes. The Decorator mode here skips the abstract decoration role Decorator ). The following shows how the client dynamically adds features to MemoryStream.
MemoryStream memoryStream = new MemoryStream (new byte [] {, 98, 99}); // extended buffer function BufferedStream buffStream = new BufferedStream (memoryStream ); // Add encryption function CryptoStream cryptoStream = new CryptoStream (memoryStream, new AesManaged (). createEncryptor (), CryptoStreamMode. write); // Add the compression function GZipStream gzipStream = new GZipStream (memoryStream, CompressionMode. compress, true );Vi. Summary
Now, the introduction of the decorator mode is over. The decorator mode uses Object combination instead of inheritance to dynamically expand the object function during re-running, in addition, you can expand multiple functions as needed to avoid the "flexibility difference" and "Multi-subclass Derivative Problems" caused by the independent use of inheritance. At the same time, it is well in line with the object-oriented design principles of "preferential use of object combinations rather than inheritance" and "open-closed.
This article is from the "LearningHard" blog, please be sure to keep this source http://learninghard.blog.51cto.com/6146675/1310760