Demand:
Give people a different outfit
Code version One
#-*-encoding:utf-8-*-classPerson attr_accessor:namedefInitialize (name) @name=Name EnddefWear_t_shirts puts'Large T-shirt'EnddefWear_big_trouser puts'Pants'EnddefWear_sneakers puts'Broken Sneakers'EnddefWear_suit puts'Suits'EnddefWear_tie puts'Tie'EnddefWear_leather_shoes puts'Leather Shoes'EnddefShow puts"* * * * Dress up the #{name}\n\n"ENDENDXC=person.new ('Side Dishes') puts"****** the first kind of dress up"xc.wear_t_shirtsxc.wear_big_trouserxc.wear_sneakersxc.showputs"****** second dress up"Xc.wear_suitxc.wear_tiexc.wear_leather_shoesxc.show
In this case, the function is realized, the problem is that if you add "Superman" dress, you need to modify the person class, violating the open-closed principle.
Code version Two
#-*-encoding:utf-8-*-classPerson attr_accessor:namedefInitialize (name) @name=Name EnddefShow puts"* * * * Dress up the #{name}\n\n"EndEndclassFinerydefShow EndEndclassTshirts <FinerydefShow puts'Large T-shirt'EndEndclassBigtrouser <FinerydefShow puts'Pants'EndEndclassSneakers <FinerydefShow puts'Broken Sneakers'EndEndclassSuit <FinerydefShow puts'Suits'EndEndclassTie <FinerydefShow puts'Tie'EndEndclassLeathershoes <FinerydefShow puts'Leather Shoes'ENDENDXC=person.new ('Side Dishes') TS=TSHIRTS.NEWBT=Bigtrouser.newsk=sneakers.newputs"****** the first kind of dress up"Ts.showbt.showsk.showxc.showsuit=Suit.newtie=tie.newls=leathershoes.newputs"****** second dress up"Suit.showtie.showls.showxc.show
After this change, if you add Superman dress, do not need to modify the person class. The problem is that all kinds of clothes are independent, and exposed to the outside, is a piece of wear, no order, no control.
Code version Three
#-*-encoding:utf-8-*-classPerson attr_accessor:namedefInitialize (name=nil) @name=Name EnddefShow puts"* * * * Dress up the #{name}\n\n"EndEndclassFinery <Person attr_accessor:componetdefDecorate (componet) @componet=Componet EnddefShow Componet.showifcomponet endendclassTshirts <FinerydefShow Super puts'Large T-shirt'EndEndclassBigtrouser <FinerydefShow Super puts'Pants'EndEndclassSneakers <FinerydefShow Super puts'Broken Sneakers'EndEndclassSuit <FinerydefShow Super puts'Suits'EndEndclassTie <FinerydefShow Super puts'Tie'EndEndclassLeathershoes <FinerydefShow Super puts'Leather Shoes'ENDENDXC=person.new ('Side Dishes') TS=TSHIRTS.NEWBT=Bigtrouser.newsk=sneakers.newputs"****** the first kind of dress up"ts.decorate xcbt.decorate tssk.decorate btsk.showsuit=Suit.newtie=tie.newls=leathershoes.newputs"****** second dress up"suit.decorate xctie.decorate suitls.decorate btls.show
Each wear a dress, will give the current object's componet assignment, the value is already person or its subclass, so, the last subclass of the Show method, will follow the order of the call, print out every garment.
Decorating mode is a way to dynamically add a lot of functionality to an existing feature.
When new functionality is required, new code is added to the old class, which usually modifies the core responsibilities or main behavior of the original class. New fields, new methods, and new logic are added to the main class, increasing the complexity of the main class. These newly added things are just to meet the needs of some special behavior that will only be performed under certain circumstances.
Decoration mode provides a very good solution to each of the decorative
Functions are placed in a separate class and let the class wrap the objects it modifies, so that when special behavior is required, the customer code can be run with a selective, sequential use of the Adornment object function to wrap the object.
Advantages
The decoration function in the class is removed from the class and the original class is simplified. Effectively separates the core functions of the class from the decorative functions, and removes the repetitive decoration logic from the related classes.
"Big talk design mode" Ruby version code: Decorative Mode