当前位置:网站首页>Necessary decorator mode for 3 years' work
Necessary decorator mode for 3 years' work
2022-06-26 16:57:00 【Tianweichang】
Focus on “Java Back end technology stack ”
reply “000” Access to a lot of e-books
Hello everyone , I'm Lao Tian , Starting today , This official account is given to you every week Give benefits , What do you give ? It must be a technical book , There are not so many fancy things , The way of participation is shown at the end of the article .
All right. , Enter our theme , Today I'd like to share with you Decorator mode . With the right life story , And design patterns in real project scenarios , Finally, I want to summarize this design pattern with one sentence .
Design pattern series , We've shared :
3 Necessary for annual work Facade mode
3 Necessary for annual work The singleton pattern
3 Necessary for annual work The strategy pattern
3 Necessary for annual work Template method pattern
The story
The old saying goes well : People depend on clothes and horses on saddles . Let's get familiar with the background of this sentence :
A man depends on his clothes and a horse on his saddle , The joy of dogs running with bells comes from Shen Zijin 《 The story of Wanghu Pavilion 》 The tenth :“ Even so , Buddha relies on gold. , Clothes are for men. , It's also important to dress up .”《 Wake up to the world 》 Volume one ‧ Two county magistrates compete to marry an orphan girl :” As the saying goes :’ Buddha is gold , People are clothes , There are many shallow eyes in the world , Only skin , There's no bone .’” As the saying goes, men depend on clothes and horses on saddles .
This classic story , It reminds me of a design pattern : Decorator mode .
What is decorator mode ? Please listen to Lao Tian's words .
An overview of decorator patterns
Decorator mode (Decorator Pattern) It's also called wrapper mode (Wrapper Pattern), On the basis of not changing the original object , Dynamically add some additional responsibilities to an object . In terms of adding functionality , Decorator mode is more flexible than subclassing , It belongs to structural design mode .
english :
Attach additional responsibilities to an object dynamicallykeeping the same interface.Decorators provide a flexible alternativeto subclassing for extending functionality.
The decorator pattern provides a more flexible alternative than inheritance ( Extend the function of the original object ) Attach functions to objects . therefore , The core of decorator mode is function extension . Using the decorator pattern, you can extend the functions of a class transparently and dynamically .
Cases in life
A blank room , Before the decoration , It looks very ugly , But just a little renovation , That would be much more beautiful , And can take a bath 、 sleep 、 Cooking, etc , But the essence is the house .
A car , Originally, it was a vehicle for people to walk , But Mary is , Configuration upgrade , And then it became a luxury car , But in essence, it's still a car to go .
A girl , It used to be very ordinary , Looks average , But after a bit of make-up , Put on some nice clothes , Then she became the goddess in many people's hearts .
All in all , After a little decoration , It's just different , Features enhanced .
Decorator pattern common code implementation
Let's use code to implement a , Programmers like to start with demo, And then slowly study .
// Abstract components
public abstract class Component {
public abstract void operation();
}
// Specific components
public class ConcreteComponent extends Component {
@Override
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
// Decorator abstraction
public abstract class Decorator extends Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
// Specific ornaments
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void operation() {
System.out.println(" Do something before you start ");
super.operation();
System.out.println(" Do something after it's over ");
}
}
// test
public class Client {
public static void main(String[] args) {
Component component = new ConcreteDecorator(new ConcreteComponent());
component.operation();
}
}
Running results :
Do something before you start
ConcreteComponent operation
Do something after it's over
The above is the common code implementation of decorator pattern , Let's analyze .
Decorator mode UML chart

from UML You can see on the way , The role
Characters in decorator mode
Abstract components (Component): It can be an interface or an abstract class , Act as the original object of the decorated class , Specifies the behavior of the decorated object .
Specific components (ConcreteComponent): Realization / Inherit Component A specific object of , That is, the object to be decorated .
Abstract decorator (Decorator): General decoration ConcreteComponent The decorator , There must be an attribute inside it pointing to Component; Its implementation is generally an abstract class , The main purpose is to let its subclass pass in a Component, It's mandatory universal behavior . If the decoration logic in the system is single , You don't need to implement many decorators , This class can be omitted directly , And directly implement a specific decorator .
Specific ornaments (ConcreteDecorator):Decorator Implementation class of , Theoretically , Every ConcreteDecorator It's all expanded Component A function of an object .
Summary
The role assignment of decorator pattern is in accordance with Richter's substitution principle of design pattern 、 The principle of Dependence Inversion , So it has strong expansibility , Finally, the open close principle is satisfied .
The implementation principle of decorator mode is , Let the decorator implement with the decorated class ( for example ConcreteComponent) Same interface ( for example Component), Make the decorator consistent with the extended class type , And pass in the interface object in the constructor , Then add new functionality to the existing functionality of the wrapped class object that implements this interface . Because the decorator and the packaged class belong to the same type ( Are all Component), And the parameter of the constructor is its implementation interface class (Component), Therefore, decorator pattern has nested extension function , In this way, the decorator pattern can be used to extend the functions of the underlying packaged classes layer by layer .
actual combat
In actual development , There will be calls between systems , If we have a payment function now , Now everything is OK , however At this time, we need to check the request parameters before payment and the corresponding parameters after payment . To carry out a unified treatment , The original function remains unchanged , It's just an extension of the original function ( enhance ).
The old function code is as follows :
/**
* @author Mr. Tian
* @date 2021-06-02
*
* Welcome to the official account :java Back end technology stack
*/
public interface IOrderPayService {
String payment(Long orderId, BigDecimal amount);
}
public class OrderPayServiceImpl implements IOrderPayService {
@Override
public String payment(Long orderId, BigDecimal amount) {
// Call balance first to check whether it is enough
System.out.println(" Initiate payment , The order number :" + orderId + ", Pay the amount :" + amount.toString());
// Call the payment system
String result = " Order id=" + orderId + " Pay to complete ";
System.out.println(" Payment result :" + result);
return result;
}
}
public class OrderClient {
public static void main(String[] args) {
IOrderPayService orderPayService = new OrderPayServiceImpl();
orderPayService.payment(10001L,new BigDecimal("5000"));
}
}
Operation output :
Initiate payment , The order number :10001, Pay the amount :5000
Payment result : Order id=10001 Pay to complete
The new demand , These request parameters and corresponding results need to be collected and processed separately , At this time, in order not to affect the original function , So we can enhance it .
/**
* @author Mr. Tian
* @date 2021-06-02
*
* Welcome to the official account :java Back end technology stack
*/
public class OrderPayDecorator implements IOrderPayService {
private IOrderPayService orderPayService;
public OrderPayDecorator(IOrderPayService orderPayService) {
this.orderPayService = orderPayService;
}
@Override
public String payment(Long orderId, BigDecimal amount) {
System.out.println(" Send this order information ( Initiate payment )" + " Order id=" + orderId + " Pay the amount =" + amount.toString() + " 【 Send to MQ】");
String result = orderPayService.payment(orderId, amount);
System.out.println(" Send the order payment result information " + result + " 【 Send to MQ】");
return result;
}
}
public class OrderClient {
public static void main(String[] args) {
IOrderPayService orderPayService =new OrderPayDecorator(new OrderPayServiceImpl());
orderPayService.payment(10001L,new BigDecimal("5000"));
}
}
Operation output :
Send this order information ( Initiate payment ) Order id=10001 Pay the amount =5000 【 Send to MQ】
Initiate payment , The order number :10001, Pay the amount :5000
Payment result : Order id=10001 Pay to complete
Send order payment result information to order id=10001 Pay to complete 【 Send to MQ】
The whole process , Have you noticed that , We didn't move the original code , It's just an enhancement .
Decorator mode will not be used in new projects , Usually used in old projects , Because the existing functions remain unchanged , Just a few enhancements .
How the gods use it
Decorator design pattern in JDK Source code 、Spring Source code and Mybatis Source code has .
JDK Source code
The classic application of decorator mode is JDK Medium java.io It's a bag ,InputStream、OuputStream、Reader、Writer And their subclasses .
With InputStream For example
FileInputStream yes InputStream Subclasses of , Used to read file byte stream
BufferedInputStream yes InputStream Subclasses of subclasses of , Cacheable byte stream
DataInputStream It's also InputStream Subclasses of subclasses of , Direct reading Java Basic type of byte stream
UML chart

DataInputStream The constructor's input parameter is its own parent class (InputStream).

If you want to provide a file that can be read + Cacheable byte stream , Use inheritance , You need to derive FileBufferedInputStream;
If you want to provide a file that can be read + Read the basic type of byte stream directly , Use inheritance , You need to derive FileDataInputStream.
Byte stream enhancements also include support for pipelines pipe、 Byte array bytearray、 Byte object object、 Conversion of byte stream and character stream Equal dimension , If by inheritance , There will be so many levels and types of that kind of explosion .
To solve the problem , Here we use the decorator mode .
Spring Source code
stay Spring in , We can try to understand TransactionAwareCacheDecorator class , This class is mainly used for transaction caching , The code is as follows .
public class TransactionAwareCacheDecorator implements Cache {
private final Cache targetCache;
// The input parameter type of construction method is its own parent class ( Interface type )
public TransactionAwareCacheDecorator(Cache targetCache) {
Assert.notNull(targetCache, "Target Cache must not be null");
this.targetCache = targetCache;
}
public Cache getTargetCache() {
return this.targetCache;
}
//...
}
TransactionAwareCacheDecorator That's right Cache A package of , therefore , The decorator mode is also used here .
Mybatis Source code
MyBatis About China Cache and CachingExecutor Interface implementation classes also use decorator design patterns .Executor yes MyBatis actuator , yes MyBatis The core of scheduling , be responsible for SQL Statement generation and query cache maintenance ;CachingExecutor It's a Executor The decorator , Give me a Executor Added the function of cache . This can be seen as right Executor An enhancement of class , So it is appropriate to use decorator mode .
stay CachingExecutor in
public class CachingExecutor implements Executor {
// Holding component objects
private Executor delegate;
private TransactionalCacheManager tcm = new TransactionalCacheManager();
// Construction method , Pass in the component object
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
@Override
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
// Forward request to component object , You can perform additional actions before and after forwarding
flushCacheIfRequired(ms);
return delegate.update(ms, parameterObject);
}
//...
}
summary
After watching decorator mode , Do you feel , Decorator mode is very similar to proxy mode , Let's make a comparison .
1. Decorator pattern can be understood as a special proxy pattern .
2. Decorator mode emphasizes its own function expansion , Transparent extension ( That is, users can enhance whatever functions they want to enhance ), Dynamic customizable extensions .
3. Agent mode emphasizes the control of agent process .
advantage
Ornaments are a powerful complement to inheritance , More flexible than inheritance , Without changing the original object , Dynamically extend functions to an object , Plug and play .
Through the use of different decoration classes and the arrangement and combination of these decoration classes , Different effects can be achieved .
Decorator mode fully follows the opening and closing principle .
shortcoming
There will be more code 、 More classes , Increase the complexity of the program .
Dynamic decoration is more complicated in multi-layer decoration .
Okay , That's the end of today's sharing , I hope you can master the decorator mode thoroughly , If there is any doubt , Or technical discussions , Welcome to wechat , To discuss .

Last , One sentence summary decorator mode :
His big uncle, second uncle, third uncle, little uncle , It's all his uncle
Welfare password
Enter the following official account , Send a reply 20210602, You can get the way to participate .
Previous recommendation
121 Distributed interview questions and answers ,25K Proper
Don't be incredulous ,98% All programmers are like this
Will know RabbitMQ Interview questions 33 Avenue ( Answer attached )
use 21 Pictures , hold Git The working principle is completely clear
边栏推荐
- JS tutorial electron JS is a good tool for designing powerful multi platform desktop applications
- 数字藏品与NFT到底有何区别
- LeetCode Algorithm 24. Exchange the nodes in the linked list in pairs
- day10每日3题(2):统计最大组的数目
- 无需人工先验!港大&同济&LunarAI&旷视提出基于语义分组的自监督视觉表征学习,显著提升目标检测、实例分割和语义分割任务!...
- Count the number of words in a line of string and take it as the return value of the function
- Niuke programming problem -- dynamic programming of must brush 101 (a thorough understanding of dynamic programming)
- Turtle cartography
- C语言所有知识点小结
- Find all primes less than or equal to Lim, store them in AA array, and return the number of primes
猜你喜欢

Leetcode 1170. Frequency of occurrence of the minimum letter of the comparison string (yes, solved)

The first open source MySQL HTAP database in China will be released soon, and the three highlights will be notified in advance

Decentralized NFT transaction protocol will defeat opensea

When a programmer is disturbed 10 times a day, the consequences are amazing!

Web3 decentralized storage ecological landscape

内存分区模型

Leetcode 1169. 查询无效交易(如果数据量不大,这种题还是得暴力枚举解决)

进军AR领域,这一次罗永浩能成吗?

Pybullet robot simulation environment construction 5 Robot pose visualization

无需人工先验!港大&同济&LunarAI&旷视提出基于语义分组的自监督视觉表征学习,显著提升目标检测、实例分割和语义分割任务!...
随机推荐
Cuckoo filter for Chang'an chain transaction
TCP congestion control details | 1 summary
Find all primes less than or equal to Lim, store them in AA array, and return the number of primes
No manual prior is required! HKU & Tongji & lunarai & Kuangshi proposed self supervised visual representation learning based on semantic grouping, which significantly improved the tasks of target dete
Learn about common functional interfaces
进军AR领域,这一次罗永浩能成吗?
Apache APIs IX has the risk of rewriting the x-real-ip header (cve-2022-24112)
Leetcode 1170. Frequency of occurrence of the minimum letter of the comparison string (yes, solved)
JS tutorial - printing stickers / labels using the electronjs desktop application
Decentralized NFT transaction protocol will defeat opensea
Swap two numbers
Stm32f103c8t6 realize breathing lamp code
Introduction to minimal API
Redis overview
Day10 daily 3 questions (3): String Matching in array
Deployment and operation of mongodb partitioned cluster
day10每日3题(1):逐步求和得到正数的最小值
20: Chapter 3: develop the pass service: 3: get through the redis server in the program; (it only connects with the redis server and does not involve specific business development)
In a bad mood, I just write code like this
Notes on key review of software engineering at the end of the term