Design mode - decoration mode

 

 

 

  Structure diagram interpretation:

Component can be either an interface or an abstract class. Its purpose is to specify Operation(), that is, what the specification is going to do.
ConcreteComponent is a class that inherits or implements Component. It is the representative of decoration, such as rice and milk tea.
Decorator class is a decoration class. There must be a Component or ConcreteComponent attribute inside, indicating who is used to decorate (extend who).
Concretedecorator a, concretedecorator B, as I understand it, are various decorations (extensions)
 
If there is only one ConcreteComponent but no abstract Component, the Decorator class can be a subclass of ConcreteComponent
 
What is decoration mode?
For example, I now have a bowl of white rice. On this rice, I can put shredded potatoes, cabbage, dried beans and duck legs. This is duck leg rice.
Then I'll put shredded potatoes, cabbage, chicken legs and dried beans. This is chicken leg rice.
Different side dishes are different packages. If I have the following packages on my menu:
Chicken leg rice (chicken leg + green vegetables + dried sesame)
Rice with shredded pork (shredded pork + green vegetables + dried sesame)
Large row rice (large row + green vegetables + dried sesame)
Duck leg rice (duck leg + green vegetables + dried sesame)
Dongpo pilaf (Dongpo + green vegetables + dried parsley)
 
To achieve these goals
First, use the easiest way to realize it. Create a class for each set meal, then there are chicken leg rice, shredded meat rice, large row rice
What do you do if I have chicken leg rice + a big row now?
Are you creating a chicken leg rice + a large row of classes?
What if I want to add another Dongpo meat? What about another duck leg? (this is really rich)
 
Now we find that our implementation is not appropriate.
Let's analyze first. Different packages are actually different side dishes with rice, right? Does it seem like adding something on the basis of rice.
The decoration mode code is implemented as follows
 
/**
 * SX I sell snacks here
 * Chicken leg rice (chicken leg + green vegetables + dried sesame)
 * Rice with shredded pork (shredded pork + green vegetables + dried sesame)
 * Large row rice (large row + green vegetables + dried sesame)
 * Duck leg rice (duck leg + green vegetables + dried sesame)
 * Dongpo pilaf (Dongpo + green vegetables + dried parsley)
 * @author wrj
 * @description
 * @Date 2021/12/1 2:37 afternoon
 */

abstract class Food { public abstract void has(); } //rice class Rice extends Food{ @Override public void has() { System.out.println("There is rice"); } } //Decoration class abstract class FoodDecorator extends Food{ public Food food; public void addFood(Food food){ this.food = food; } @Override public void has() { food.has(); } } //drumsticks class Drumstick extends FoodDecorator{ @Override public void has() { System.out.println("There are chicken legs"); super.has(); } } //shredded meat class ShreddedMeat extends FoodDecorator{ @Override public void has() { System.out.println("Shredded meat"); super.has(); } } //Platoon class PorkRibs extends FoodDecorator{ @Override public void has() { System.out.println("There are large rows"); super.has(); } } //Green vegetables class Vegetable extends FoodDecorator{ @Override public void has() { System.out.println("There are vegetables"); super.has(); } } //Dried tofu class DriedBeanCurd extends FoodDecorator{ @Override public void has() { System.out.println("There are dried beans"); super.has(); } } public class SXFood {
   //Variables written in Chinese are not standard for ease of understanding
public static void main(String[] args) { //Construction process of standard chicken leg rice System.out.println("Rice with Stewed Drumstick:\r\n"); Rice rice = new Rice(); DriedBeanCurd Dried tofu = new DriedBeanCurd(); Vegetable Green vegetables = new Vegetable(); Drumstick drumsticks = new Drumstick(); drumsticks.addFood(Green vegetables); Green vegetables.addFood(Dried tofu); Dried tofu.addFood(rice); drumsticks.has(); //Special needs chicken leg rice+Platoon System.out.println("Rice with Stewed Drumstick+Platoon:\r\n"); Rice Rice 1 = new Rice(); DriedBeanCurd Dried bean 1 = new DriedBeanCurd(); Vegetable Green vegetables 1 = new Vegetable(); Drumstick Drumstick 1 = new Drumstick(); PorkRibs Platoon = new PorkRibs(); Drumstick 1.addFood(Platoon); Platoon.addFood(Green vegetables 1); Green vegetables 1.addFood(Dried bean 1); Dried bean 1.addFood(Rice 1); Drumstick 1.has(); } }

 

Final output:

 

 

This scene is suitable for decoration mode. Look back at the concept of decoration mode:
Dynamically add some additional responsibilities to an object. In terms of adding functionality, the decorator pattern is more flexible than generating subclasses.
The above scenario of chicken leg rice + large row reflects the characteristics of dynamic addition and why it is more flexible than subclasses, because we don't need to generate subclasses all the time, and we can add anything to realize functions
 
You can see that different collocations are finally combined into different packages, so no matter what wonderful needs, there is no need to change the category, just change the content and order of decoration.
This also reflects the opening and closing principle. There is no need to change the basic class, just change the usage method.
 
Attention should be paid to the order of decoration. Different orders will produce different results. This needs attention

Summary:

Decoration mode is a way to dynamically add more functions for existing functions. When the system needs new functions, it is to add new code to the old classes. This new code usually decorates the core responsibilities or main behaviors of the original class.

New fields, new methods and new logic are added to the main class, thus increasing the complexity of the main class. These newly added things are only to meet the needs of some special behaviors that can only be performed under certain circumstances (refer to the scene of chicken leg rice plus a large row).

The decoration pattern provides a very good solution by putting each function to be decorated in a separate class. And let this class wrap the object it wants to decorate. Therefore, when special behaviors need to be performed, the customer code can selectively and sequentially use the decoration function to wrap objects at run time.

Advantages: move the decoration function in the class out of the class and simplify the original class. Effectively distinguish the core responsibilities of classes from decorative functions.

Tags: Design Pattern

Posted on Wed, 01 Dec 2021 17:15:20 -0500 by Crogge