当前位置:网站首页>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
边栏推荐
- Environment setup mongodb
- 108. 简易聊天室11:实现客户端群聊
- [from database deletion to running] JDBC conclusion (finish the series in one day!! run as soon as you finish learning!)
- Stm32f103c8t6 realize breathing lamp code
- Scala 基础 (二):变量和数据类型
- proxy
- LeetCode Algorithm 24. 两两交换链表中的节点
- Incomplete line spacing adjustment of formula display in word
- 20:第三章:开发通行证服务:3:在程序中,打通redis服务器;(仅仅是打通redis服务器,不涉及具体的业务开发)
- C language -- legal identifier and integer
猜你喜欢

我把它当副业月入3万多,新手月入过万的干货分享!
![[Error] ld returned 1 exit status](/img/38/ec4645880d4c14e3766fbcabe8ddde.jpg)
[Error] ld returned 1 exit status
Scala 基础 (二):变量和数据类型

Teach you to learn dapr - 2 Must know concept

Stm32h7b0 replaces the h750 program, causing the MCU to hang up and unable to burn the program

Community ownership of NFT trading market is unstoppable
![[Li Kou brush question] monotone stack: 84 The largest rectangle in the histogram](/img/75/440e515c82b5613b117728ba760786.png)
[Li Kou brush question] monotone stack: 84 The largest rectangle in the histogram

Interpretation of new plug-ins | how to enhance authentication capability with forward auth

Apache APIs IX has the risk of rewriting the x-real-ip header (cve-2022-24112)

NFT 交易市场社区所有化势不可挡
随机推荐
A simple membership card management system based on Scala
Scala Foundation (2): variables et types de données
Calculate a=1, a2=1/1=a1
Multiply the values of the upper triangular elements of the array by M
Introduction to minimal API
[Error] ld returned 1 exit status
【从删库到跑路】MySQL基础 完结篇(入个门先跑路了。。)
In a bad mood, I just write code like this
无需人工先验!港大&同济&LunarAI&旷视提出基于语义分组的自监督视觉表征学习,显著提升目标检测、实例分割和语义分割任务!...
[Li Kou brush questions] 11 Container holding the most water //42 Rain water connection
Web3去中心化存储生态图景
SQL injection for Web Security (3)
The first open source MySQL HTAP database in China will be released soon, and the three highlights will be notified in advance
板卡的分级调试经验
Find all primes less than or equal to Lim, store them in AA array, and return the number of primes
Discover K8E: minimalist kubernetes distribution
Count the number of each vowel letter in the string
Pybullet robot simulation environment construction 5 Robot pose visualization
Web3 decentralized storage ecological landscape
Interpretation of cloud native microservice technology trend