- 1. Overview of decoration mode
- 2. Structure and implementation of decoration mode
- 3. Application examples of decoration mode
- 4. Transparent decoration mode and translucent decoration mode
- 5. Advantages, disadvantages and applicable environment of decoration mode
"Github: https://github.com/nateshao/design-demo/tree/main/JavaDesignPatterns/12-decorator
1. Overview of decoration mode
Examples of "decoration" in real life
Analysis of decoration mode
- You can add additional new behavior to an object without changing the function of the object itself
- It is a technology used to replace inheritance. It dynamically adds responsibilities to objects without defining subclasses, and uses the association relationship between objects to replace the inheritance relationship between classes
- The decoration class is introduced. In the decoration class, you can not only call the methods of the original class to be decorated, but also add new methods to expand the functions of the original class
definition
"Decoration pattern: dynamically adding some additional responsibilities to an object. Decoration pattern provides a more flexible alternative to using subclasses in terms of extended functionality.
Object structured pattern
- Dynamically attach more responsibilities to an object in a transparent manner to the customer
- You can extend the functionality of objects without creating more subclasses
Structure of decoration mode
Decoration mode includes the following 4 roles:
- Component (abstract component)
- ConcreteComponent (concrete component)
- Decorator (abstract decoration class)
- ConcreteDecorator (specific decoration)
2. Structure and implementation of decoration mode
Typical code of abstract component class:
public abstract class Component { public abstract void operation(); }
Typical code of specific component class:
public class ConcreteComponent extends Component { public void operation() { //Realize basic functions } }
Typical code of abstract decoration class:
public class Decorator extends Component { private Component component; //Maintain a reference to the abstract component object //Inject an object of abstract component type public Decorator(Component component) { this.component=component; } public void operation() { component.operation(); //Call the original business method } }
Typical code of specific decoration class:
public class ConcreteDecorator extends Decorator { public ConcreteDecorator(Component component) { super(component); } public void operation() { super.operation(); //Call the original business method addedBehavior(); //Call new business method } //New business method public void addedBehavior() { ...... } }
3. Application examples of decoration mode
Example description:
"A software company has developed a set of graphical interface component library visual component based on object-oriented technology. The component library provides a large number of basic components, such as form, text box, list box, etc. when using the component library, users often require to customize some special display effects, such as form with scroll bar, text box with black border, both scroll bar and The list box with black border and so on, so it is often necessary to expand the component library to enhance its function. Now we use decoration mode to design the graphical interface component library.
Instance class diagram
Structure diagram of graphical interface component library
Example code
- Component: abstract interface component class, which acts as an abstract component class
- Window: a form class that acts as a concrete component class
- TextBox: a text box class that acts as a concrete component class
- ListBox: a list box class that acts as a concrete component class
- ComponentDecorator: component decoration class, which acts as an abstract decoration class
- ScrollBarDecorator: scroll bar decoration class, which acts as a concrete decoration class
- BlackBorderDecorator: black border decoration class, which acts as a specific decoration class
- Client: client test class
Component.java
public abstract class Component { public abstract void display(); }
Window.java
public class Window extends Component { public void display() { System.out.println("Show form!"); } }
TextBox.java
public class TextBox extends Component { public void display() { System.out.println("Show text box!"); } }
ListBox.java
public class ListBox extends Component { public void display() { System.out.println("Show list box!"); } }
ComponentDecorator.java
public class ComponentDecorator extends Component { private Component component; //Maintain references to abstract component type objects //Inject objects of abstract component types public ComponentDecorator(Component component) { this.component = component; } public void display() { component.display(); } }
ScrollBarDecorator.java
public class ScrollBarDecorator extends ComponentDecorator { public ScrollBarDecorator(Component component) { super(component); } public void display() { this.setScrollBar(); super.display(); } public void setScrollBar() { System.out.println("Add a scroll bar to the component!"); } }
BlackBorderDecorator.java
public class BlackBorderDecorator extends ComponentDecorator { public BlackBorderDecorator(Component component) { super(component); } public void display() { this.setBlackBorder(); super.display(); } public void setBlackBorder() { System.out.println("Add a black border to the component!"); } }
Client.java
public class Client { public static void main(String args[]) { Component component, componentSB, componentBB; component = new Window(); componentSB = new ScrollBarDecorator(component); componentBB = new BlackBorderDecorator(componentSB); componentBB.display(); } } Add a black border to the component! Add a scroll bar to the component! Show form!
4. Transparent decoration mode and translucent decoration mode
Transparent decoration mode
- Transparent decoration mode: the client is required to program completely against the abstract. The transparency of decoration mode requires that the client program should not declare the object as a specific component type or a specific decoration type, but should declare it as an abstract component type
- For the client, there is no difference between the specific component object and the specific decoration object
- The client can use the objects before and after decoration transparently
- The client can use the object before decoration and the object after decoration transparently without paying attention to their differences
- A decorated object can be decorated many times to get a more complex and powerful object
- The new method addedBehavior() cannot be called separately on the client
...... Component component_o,component_d1,component_d2; //All use abstract component definitions component_o = new ConcreteComponent(); component_d1 = new ConcreteDecorator1(component_o); component_d2 = new ConcreteDecorator2(component_d1); component_d2.operation(); //Component cannot be called alone_ addedBehavior() method of D2 ......
Translucent decoration mode
- Semi transparent decoration mode: the object after decoration is defined by the specific decoration type, while the specific component is defined by the abstract component type
- For the client, the specific component type does not need to be concerned and is transparent; However, the specific decoration type must be specified, which is opaque
- It can bring more flexibility to the system. The design is relatively simple and easy to use
- The client uses the specific decoration type to define the decorated object, so the addedBehavior() method can be called separately
- The biggest disadvantage is that the same object cannot be decorated multiple times, and the client needs to treat the objects before decoration and the objects after decoration differently
...... Component component_o; //Using abstract component type definitions component_o = new ConcreteComponent(); component_o.operation(); ConcreteDecorator component_d; //Use specific decoration type definitions component_d = new ConcreteDecorator(component_o); component_d.operation(); component_d.addedBehavior(); //Call the new business method separately ......
5. Advantages, disadvantages and applicable environment of decoration mode
Mode advantages
- For the function of extending an object, decoration mode is more flexible than inheritance, and will not lead to a sharp increase in the number of classes
- The function of an object can be extended in a dynamic way. Different specific decoration classes can be selected at run time through the configuration file, so as to realize different behaviors
- You can decorate an object multiple times
- Specific component classes and specific decoration classes can be changed independently. Users can add new specific component classes and specific decoration classes as needed, and the original class library code does not need to be changed, which conforms to the opening and closing principle
Mode disadvantages
- When using decoration mode for system design, many small objects will be generated. The generation of a large number of small objects is bound to occupy more system resources and affect the performance of the program to a certain extent
- It is easier to make mistakes than inheritance and more difficult to troubleshoot. For objects decorated many times, finding errors during debugging may require level by level troubleshooting, which is more cumbersome
Mode applicable environment
- Add responsibilities to a single object in a dynamic and transparent manner without affecting other objects
- When the system cannot be extended by inheritance or inheritance is not conducive to system expansion and maintenance, the decoration mode can be used