There is an important principle in object-oriented programming, the principle of the Richter substitution: If a software entity is using a parent class, its subclasses must be applied, and it will not recognize the difference between the parent object and the child class object. In other words, in software design, the parent class is replaced with its subclasses, and the behavior of the program does not change. simply put, a subclass type must be able to replace its parent class type.
Like the concept of inheritance, subclasses inherit from the parent class, and the subclass can appear as the parent class. There is such a problem, in object-oriented design, one is a bird, one is a penguin, if the bird can fly, penguins will not fly, then penguins are birds? Can penguins inherit from birds?
Object-oriented design, it means that the subclass has the parent class so non-private properties and behavior, the bird will fly, and the penguin will not, so the penguin is a bird, but it can not inherit from the flying birds above, abstract a higher bird, and then divided into flying birds sub-class, not flying Birds sub-class, The penguin should inherit from the flightless bird subclass.
This is due to the principle of the substitution of the Richter scale, which makes the inheritance reuse possible, only if the subclass can replace the parent class, the function of the Software unit is not affected, the parent class can be really reused, and the subclass may also add new behavior on the basis of the parent class. it is because of the substitution of subclasses that the parent class type module can be extended without modification, which is mentioned earlier, open to extensions, and closed for modification (OCP principle).
Decoration mode
Dress problems, ask to write a system for people to wear different costumes, the kind of clothing and trousers can change a variety of clothing system, such as:
First of all, to exclude such a result design, if I need to add a new Superman costume design, but also to change the person class, it is clearly against the development-closure principle (OCP, open to expansion, closed to the modification). In fact, these costumes are written as sub-class, Code structure:
In this way, you need to increase the Superman's dress, only need to add sub-class. There is no need to modify the existing code. But this is not the best, we need in the controller to open up such as "Broken Shoes", "Down Pants" and other objects, they will be a word of a word display, it is like in the eyes of the naked clothes.
For these, you should optimize them. You can use the adornment mode: dynamically add some extra functions to an object, and the decoration mode is more flexible than adding a subclass for added functionality. Whether it is clothes, shoes, trousers, etc., in fact, we can understand it as the decoration of person, then there is structure:
Code:
Person class:
#import <Foundation/Foundation.h> @interface zyperson:nsobject{ @protected nsstring *_name;} -(Instancetype) Initwithname: (NSString *) name;-(void) display; @end #import "ZYPerson.h" @implementation zyperson-( Instancetype) Initwithname: (NSString *) name{ if (self = [super init]) { _name = name; } return self;} -(void) display{ NSLog (@ "Dress up%@:", _name);} @end
Clothing class:
#import "ZYPerson.h" @interface Zyclothing:zyperson@property (nonatomic, Strong) Zyperson *decorate;-(instancetype) Initwithdecorate: (Zyperson *) decorate; @end #import "ZYClothing.h" @implementation zyclothing-(Instancetype) Initwithdecorate: (Zyperson *) decorate{ if (self = [super init]) { _decorate = decorate; } return self;} -(void) display{ if (self.decorate) { [self.decorate display]; }} @end
Tshirts class:
#import "ZYClothing.h" @interface zytshirts:zyclothing@end#import "ZYTShirts.h" @implementation zytshirts-(void) display{ [super display]; NSLog (@ "big shirt");} @end
Pants class:
#import "ZYClothing.h" @interface zypants:zyclothing@end#import "ZYPants.h" @implementation zypants-(void) display{ [super display]; NSLog (@ "big underwear");} @end
Shoe class:
#import "ZYClothing.h" @interface zyshoe:zyclothing@end#import "ZYShoe.h" @implementation zyshoe-(void) display{ [Super display]; NSLog (@ "broken Shoes");} @end
Viewcontroller inside the code:
#import "ViewController.h" #import "ZYPerson.h" #import "ZYClothing.h" #import "ZYTShirts.h" #import "ZYPants.h" #import "ZYShoe.h" @interface Viewcontroller () @end @implementation viewcontroller-(void) viewdidload { [Super Viewdidload ]; Additional setup after loading the view, typically from a nib. Zyperson *person = [[Zyperson alloc] initwithname:@ "Crystal children's Shoes"]; zyclothing *clothing = [[Zyclothing alloc] Initwithdecorate:person]; Zytshirts *shirts = [[Zytshirts alloc] init]; Zypants *pants = [[Zypants alloc] init]; Zyshoe *shoe = [[Zyshoe alloc] init]; Dress up process, equivalent to wear clothes indoors, the controller does not know how it is in order shirts.decorate = clothing; Pants.decorate = shirts; Shoe.decorate = pants; [shoe display]; Second time dress up pants.decorate = clothing; Shoe.decorate = pants; Shirts.decorate = shoe; [Shirts display];} @end
Run:
Decoration Pattern Summary:
I think the decorating mode is a way to add more versatility to the already functional dynamic. But when exactly do you use it?
In the initial design of this article, when the system needs to add new functionality, it is adding new code to the old class, which often decorates the core functions or the main behavior of the original class. the problem with this design approach is that they add new fields, new methods, and new logic to the main class, increasing the responsibility of the main class. And these new things are just to meet the needs of some particular behavior that will be performed in a given situation.
And the decorating mode provides a very good solution, it puts each function to decorate in a separate class, and lets this class contain it to decorate the object, therefore, when carries on the special behavior, in the Viewcontroller can choose according to the demand, the order uses the adornment function to wrap the object.
So with the code above, I can decorate, get the person to the teeth, or just let him wear a pair of underwear.
Advantages of Decorative mode:
- Remove the adornment function from the class to simplify the original class.
- When effectively separating the core function and the decorative function in the class, you can remove the repetitive decoration logic in the related class.
Decorative mode of design mode (iOS development, code with OBJECTIVE-C)