What is Decorator mode
concept
Decorator Pattern is a structural pattern. It dynamically adds some new responsibilities (functions) to this object without changing the existing object structure (code). It is hoped to expand the class by combining objects instead of inheritance.
We know from its name that ornaments, such as the watches we bring, can not affect us, and then give us the ability to see time.
Decorator mode is to add some new functions without changing the core functions. It is very similar to agent mode. After learning how to implement decorator mode, we will make a summary of differentiation.
advantage
- Decorator pattern is an alternative way of inheritance. It completes the function of inheritance through combination, but avoids the invasiveness of inheritance.
- Reduce coupling between classes. Both decorated and decorated classes can develop independently and will not affect each other.
- Comply with the principle of open and closed.
shortcoming
Excessive use of decorator pattern will lead to a large number of classes and increase the complexity of the program.
Although the design pattern is good, don't be greedy.
principle
"+" means compliance, "-" means non-compliance or irrelevant
principle | Open and closed | Single responsibility | Dimitt | Richter substitution | Dependency inversion | Interface isolation | Synthetic multiplexing |
---|---|---|---|---|---|---|---|
+ | + | + | - | + | + | + | |
Applicable scenario (motivation)
- Want to avoid using inheritance to extend functionality.
- Implemented subclasses have different dimensions.
How
To implement the decorator mode, you need the following four things:
- Abstract component interface: an interface that defines a specific component class.
- Concrete component class (decorated class): implement the abstract component interface and create the class to be decorated.
- Decoration abstract class: implement abstract components, specify the methods to be implemented by the implementation class, and combine the objects of the concrete construction class.
- Concrete decoration class: inherit decoration abstract class and implement method.
Upper class graph
Upper code
Abstract Component interface: Component
/** * * Abstract component interface * Simulated human * Created on 2021/6/2. * * @author xuxiaobai */ public interface Component { void say(); void eat(); }
Concrete component class: ConcreteComponent
/** * Specific component class * For example, Cuihua * Created on 2021/6/2. * * @author xuxiaobai */ public class ConcreteComponent implements Component{ @Override public void say() { System.out.println("Hello, my name is Cuihua."); } @Override public void eat() { System.out.println("Really delicious!"); } }
Decoration abstract class: Decorator
/** * Decorative abstract class * Created on 2021/6/2. * * @author xuxiaobai */ public abstract class Decorator implements Component{ Component component=new ConcreteComponent(); @Override public void say() { component.say(); } @Override public void eat() { component.eat(); } /** * read a clock */ public abstract void lookTime(); }
Specific decoration class: ConcreteDecorator
/** * Specific decoration * Emerald flowers with watches * Created on 2021/6/2. * * @author xuxiaobai */ public class ConcreteDecorator extends Decorator{ @Override public void lookTime() { System.out.println("I saw my Xiaomi Bracelet show that it's 09 now:30"); } }
Test:
/** * Created on 2021/6/2. * * @author xuxiaobai */ public class DecoratorTest { public static void main(String[] args) { /** * Emerald flowers without watches */ Component component = new ConcreteComponent(); component.say(); component.eat(); /** * Emerald flowers with watches */ Decorator decorator = new ConcreteDecorator(); decorator.say(); decorator.eat(); decorator.lookTime(); /** * result: * Hello, my name is Cuihua. * Really delicious! * Hello, my name is Cuihua. * Really delicious! * I saw my Xiaomi Bracelet show that it's 09:30 */ } }
Cuihua here can wear a Decorator if she wants to wear a watch or a concrete component if she doesn't want to. It's very flexible.
[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-vlsx8rli-163318163377)( https://gitee.com/xuxiaojian1999/image-bed/raw/master/img/waibaoshibukenengwaibaode.gif )]
summary
Difference from agent mode:
Decorator pattern is very similar to static proxy. Proxy pattern also uses static proxy to implement proxy. What's the difference between them?
Yes, the decorator mode focuses on expanding new methods. Like the above example, Cuihua not only talks and eats, but also expands the method of looking at time; The agent mode is to add new functions to each original method. For example, if Cuihua wants to pack KFC to eat at home, she can go to the store or click on the KFC applet. It is equivalent to that the applet will help you tell the clerk that you order food. What you do is the same as what you do in the store, but you don't need to go to the store now.
I personally think that although the decorator pattern is an alternative to inheritance, when the number of newly extended classes is not very large, you can consider extending directly by inheritance. When the number of extended classes is a little more, reconstruct this pile of classes into the decorator pattern.