intentions
Adding additional responsibilities to an object dynamically gives the Decorator pattern more flexibility in terms of adding functionality than subclassing
Alias: Wrapper
The birth of the decorator pattern
Sometimes we want to add functionality to an object rather than the entire class. For example, a GRAPHICAL user interface toolkit allows you to add features, such as borders, to any user interface component.
Using inheritance is an effective way to add functionality, but it’s not flexible because the selection of borders is static and the user has no control over how or when to add borders to components. A more flexible approach is to embed the component in another object with a border, which we call a decorator.
Speaking English is:
[Product] : Development brother, I have a piece of code here, you need to call its functions and supplement the company’s additional functions but do not touch its own content, can you do it?
[Development] : Huh? No way! How can you not change the code and need other functionality, but have additional functionality? Should I write it like this?
void demo (a) {
// Call the original code function
// do();
// Call the company function
// doMine(); } Copy the code
【BOSS】 : Knock big head! Don’t you think it’s low?
[development] : But not so write I how to rewrite?
[BOSS] : If you look at the original code, they all implement the same interface, which is a breakthrough point
[Development] : I go to research….
HeadFirst core code
As a result, we started reading classic books on design patterns
/ * ** Common interface for decorator patterns* /
public interface Component {
String getName(a);
double getSpend(a); } / * ** The original class* / public class ConcreteComponent implements Component { private String name; public ConcreteComponent(String name) { this.name = name; } @Override public String getName(a) { return name; } @Override public double getSpend(a) { return 10; } } / * ** The decorator class notes that it takes advantage of composition, as well as the function implementation part* / public class MilkDecorator implements Component { Component coffe; MilkDecorator(Component coffe) { this.coffe = coffe; } @Override public String getName(a) { return coffe.getName() + , "milk"; } @Override public double getSpend(a) { return coffe.getSpend() + 2D; } } Copy the code
The design idea of decorator mode:
- Component: Defines an object interface, uniform behavior, and parent
- ConcreteComponent: Define an object to which you can add responsibilities (methods)
- Decorator (unnecessary) : Define an interface consistent with Component and constrain the responsibilities (methods) that need to be implemented
- ConcreteDecorator: Enhances the object’s behavior by maintaining a pointer to a Component object and implementing the Component interface
In a nutshell,
- We need an interface to unify the parent and specify the necessary behavior
- The default implementation class implements related functionality
- If additional additions (decorations) are needed, implement the interface and hold a pointer to the interface object, calling and enhancing the pointer object’s methods when implementing interface methods
❝
If it seems a bit ambiguous, after reading this article, visit the Thematic Design Patterns open source project, which has specific code examples, linked at the bottom
❞
Design principles followed
- “Open for extension, closed for modification” : the perfect way to enhance the method without modifying its code
- “Programming for interfaces” : Decorators have the same parent as themselves
What scenarios are suitable for use
Add responsibilities to a single object dynamically and transparently without affecting other objects
Code/ Practical applications in life
The best-known use of the decorator pattern in Java is the various InputStream, Reader, and Writer implementation classes in the java.io package. If we want to read text content from a file, we can use FileReader and FileInputStream;
But if we want to read faster, we need a BufferedReader, and we can do that by changing one line of code
The last
“Attached is a UML diagram of the decorator pattern from GOF:“
Related code links
Making the address
- The examples from HeadFirst and GOF are taken into account
- Friendly reading instructions are provided