Continue to learn about the design model. Today, it is the decorator model. It belongs to the structural model. First, it is the basic concept:
- Decoration mode:
Dynamically add some additional responsibilities to an object. The decorator mode is more flexible than the subclass generation function.
- Applicability:
- Add roles to a single object dynamically and transparently without affecting other objects.
- Handle unrecoverable responsibilities.
- When the subclass generation method cannot be used for expansion. One case is that there may be a large number of independent extensions. To support each combination, a large number of subclasses will be generated, resulting in explosive growth of the number of subclasses. Another scenario is that the class definition is hidden, or the class definition cannot be used to generate a subclass.
- My understanding is:
The decorator mode is like wrapper (wrapper), which packs an Object layer by layer and then returns the packaged object. It is like buying a rice cooker online, then this rice cooker is the most primitive object, and the merchant may make a preliminary packaging during delivery, first wrap the rice cooker with a layer of foam, then load it into a carton, and then hand it to the courier company, then, after receiving this item, the courier company needs to carry out secondary packaging, that is, use the special box of the courier company to pack it (or use sacks to pack it), and then paste it with a tape to start transportation, after receiving the box, the customer unwrapped the box and finally took out the rice cooker. All the things that wrap the rice cooker, such as foam, cartons, boxes, and tape, can be regarded as decorator. After the decorator finishes decorating the original objects, a decorative object is generated to add various decorations to the source object. Therefore, since the decorator depends on the objects to be decorated, the decorator needs to reference a decorated object, after the decoration, the reference will point to the decorated object.
Therefore, the decorator mode must be clear about how to use the decorator.
- In addition, because the decorator can replace the source object, the decorator and the source object must inherit the same parent class in actual implementation (this is different from the actual, in reality, the decorators and source objects are different types of objects, but the design is always the same as the actual one, which requires some flexible processing, in addition, the essence of this design is that the objects and source objects after the decoration belong to the same parent class, just like the rice cooker and the rice cooker packed in the box are the same, but the box is not the rice cooker)
- Another point is that the actual implemented modifier is a method for decorating the source object, which is equivalent to adding or replacing a method of the decorated object with a method without changing the source object.CodeAnd structure, it is equivalent to dynamically changing a function.
Code:
1 // Decorator Interface 2 Public Interface Iproduct 3 { 4 Public Void Transport (); 5 } 6 // Specific decorator 7 Public Class Product Implements Iproduct 8 { 9 Protected String name; 10 Public Product (string name) 11 { 12 This . Name = Name; 13 } 14 Public Void Transport () 15 { 16 System. Out. println ("original product:" + This . Name ); 17 System. Out. println ("transport ..." ); 18 } 19 } 20 // Decorators 21 Public Class Decorator Implements Iproduct 22 { 23 Protected Iproduct product; 24 Protected String name; 25 Public Decorator (iproduct product, string name) 26 { 27 This . Product = Product; 28 This . Name = Name; 29 } 30 Public Void Transport () 31 { 32 System. Out. println ("packaging" ); 33 If ( This . Product! = Null) 34 { 35 This . Product. Transport (); 36 } 37 } 38 } 39 // Specific modifier 1 40 Public Class Decorator1 Extends Decorator 41 { 42 Public Void Decorator1 (iproduct product) 43 { 44 This . Product = Product; 45 This . Name = "bubble" ; 46 } 47 Public Void Transport () 48 { 49 System. Out. println ("use" + This . Name + "packaging" ); 50 If ( This . Pruduct! = Null) 51 { 52 This . Product. Transport (); 53 } 54 } 55 } 56 // Specific modifier 2 57 Public Class Decorator2 Extends Decorator 58 { 59 Public Void Decorator1 (iproduct product) 60 { 61 This . Product = Product; 62 This . Name = "Tray" ; 63 } 64 Public Void Transport () 65 { 66 System. Out. println ("use" + This . Name + "packaging" ); 67 If (Pruduct! = Null) 68 { 69 This . Product. Method1 (); 70 } 71 } 72 } 73 Public Class Test 74 { 75 Public Static Void Main (string argv []) 76 { 77 Iproduct Product = New Product ("rice cooker" ); 78 Product = New Decorator1 (product ); // Packed with foam 79 Product = New Decorator2 (product ); // Packed in cartons 80 /* After that, the product object is the object packaged in the carton and then wrapped in foam. */ 81 Product. Transport (); // Output the package from the outside to the inside until the original product is delivered. 82 } 83 }