First, Decorator mode introduction:
Decorator mode-Dynamically adding additional responsibilities to an object in a transparent manner to the client, implementing the ability to dynamically expand the object's functionality when it is re-run, in a way that combines objects rather than inheritance, and provides more flexibility in increasing functionality than generating subclasses, as well as extending multiple functions as needed. Avoids the flexibility of using inheritance alone and the multi-subclass derivation problem. At the same time, it conforms well to the principle of object-oriented design, which is "preferential use of object combination rather than inheritance" and "open-closed".
Second, the background:
In software development, we often want to add different functions to a class of objects, such as to add a film to the notebook, notebook peripheral keyboard, auxiliary fan, etc., if the use of inheritance at this time to achieve, you need to define a myriad of classes, such as Foil notebook class Stickernotebook, Notebook Peripheral Class Peripheralsnotebook and so on, this will lead to the "sub-class explosion" problem, in order to solve this problem, decorator mode appeared.
Iii. individual roles in decorator mode:
- Abstract component (NoteBook) role: An abstract interface is given to standardize the objects that are prepared to accept additional responsibilities.
- Concrete Component (Appnotebook) Role: Defines a class that will receive additional responsibilities.
- Decoration (dicorator) Role: Holds an instance of a component (Component) object and defines an interface that is consistent with the abstract component interface.
- Specific decorations (sticker and peripherals) roles: Responsible for attaching additional responsibilities to the component objects.
Third, the relevant code:
1. Abstract component (NoteBook) role
/// <summary> /// Abstract class in Notebook abstract, which is an abstraction component class in decorator mode /// </summary> Public Abstract class NoteBook { publicabstractvoid SayHello (); }
2. Specific component (Appnotebook) role
/// <summary> /// Lenovo notebooks, which are decorated with specific component classes in the pattern /// </summary> Public class Lenovonotebook:notebook { publicoverridevoid SayHello () { Console.WriteLine ( " I am a Lenovo notebook ");} }
3. Decoration (dicorator) role
/// <summary> ///decorative abstract class, to let the decoration completely replace the abstract components, so must inherit from notebook/// </summary> Public Abstract classDecorator:notebook {PrivateNoteBook NoteBook; PublicDecorator (NoteBook N) { This. Notebook =N; } Public Override voidSayHello () {if(notebook!=NULL) {Notebook. SayHello (); } } }
4. Specific decorations (sticker and peripherals) roles
/// <summary> ///foil, that is, the specific decorator/// </summary> Public classSticker:decorator { PublicSticker (NoteBook N):Base(n) {} Public Override voidSayHello () {Base. SayHello (); //Add new BehaviorAddsticker (); } /// <summary> ///new ways of behaving/// </summary> Public voidAddsticker () {Console.WriteLine ("foil for Lenovo Notebook"); } }
/// <summary> ///peripherals, another specific decorator/// </summary> Public classPeripherals:decorator { PublicPeripherals (NoteBook N):Base(n) {} Public Override voidSayHello () {Base. SayHello (); //Add new Behavioraddperipherals (); } /// <summary> ///new ways of behaving/// </summary> Public voidAddperipherals () {Console.WriteLine ("add peripherals to Lenovo notebooks"); } }
5. Call
Static voidMain (string[] args) { //Create a Lenovo notebook objectNoteBook NoteBook =NewLenovonotebook (); //Extended Foil BehaviorDecorator Lenovowithsticker =Newsticker (notebook); Lenovowithsticker. SayHello (); Console.WriteLine ("======================="); //scaling increases peripheral behaviorDecorator lenovowithperipherals =NewPeripherals (notebook); Lenovowithperipherals. SayHello (); Console.WriteLine ("======================="); //simultaneously expands the foil and increases peripheral behaviorSticker sticker =Newsticker (notebook); Peripherals Peripherals=NewPeripherals (sticker); Peripherals. SayHello (); Console.readkey (); }
If you need to add an auxiliary fan, you only need to add an auxiliary fan that inherits decorator, so the decorator mode is very extensible.
Four, the use of the scene:
- You need to extend the functionality of a class or add additional responsibilities to a class.
- You need to dynamically add functionality to an object that can be revoked dynamically.
- Need to increase the amount of functionality that arises from the combination of some basic functions
Five, Summary:
Advantages :
- Decoration This mode and inheritance are intended to extend the functionality of objects, but decorator mode is more flexible than inheritance
- By using different decorative classes and permutations of these classes, designers can create combinations of many different behaviors.
- Decorator mode is well scalable
Disadvantages :
- Decorator mode causes many small objects to appear in the design, and if overused, it makes the program more complex. And more objects are going to make mistakes that are difficult, especially when these objects look alike.
C # Design Pattern-Decorator mode