当前位置:网站首页>Interesting talk about decorator mode, so you will never forget it
Interesting talk about decorator mode, so you will never forget it
2022-06-24 02:22:00 【Tom bomb architecture】
This article is excerpted from 《 This is how design patterns should be learned 》
1 Use decorator mode to solve the problem of pancake overweight
Look at a scene like this , Most office workers have the habit of sleeping in , I have a tight time at work every morning , So many people want to sleep more , Just solve the breakfast problem in a more convenient way , Some people may have pancakes for breakfast . Eggs can be added to pancakes , Or sausages , But no matter how big it is , It's still a pancake . Another example , Add some fruit to the cake , Decorate the house , It's all decorator mode .
The following code is used to simulate the business scenario of adding code to pancakes , Let's look at the situation without decorator mode . First create a pancake Battercake class .
public class Battercake {
protected String getMsg(){
return " pancakes ";
}
public int getPrice(){
return 5;
}
}Then create a pancake with eggs BattercakeWithEgg class .
public class BattercakeWithEgg extends Battercake{
@Override
protected String getMsg() {
return super.getMsg() + "+1 An egg ";
}
@Override
// Add 1 An egg with 1 Yuan
public int getPrice() {
return super.getPrice() + 1;
}
}And create an egg and sausage BattercakeWithEggAndSausage class .
public class BattercakeWithEggAndSausage extends BattercakeWithEgg{
@Override
protected String getMsg() {
return super.getMsg() + "+1 Sausages ";
}
@Override
// Add 1 A sausage with 2 Yuan
public int getPrice() {
return super.getPrice() + 2;
}
}Finally, write client test code .
public static void main(String[] args) {
Battercake battercake = new Battercake();
System.out.println(battercake.getMsg() + ", Total price :" + battercake.getPrice());
Battercake battercakeWithEgg = new BattercakeWithEgg();
System.out.println(battercakeWithEgg.getMsg() + ", Total price :" +
battercakeWithEgg.getPrice());
Battercake battercakeWithEggAndSausage = new BattercakeWithEggAndSausage();
System.out.println(battercakeWithEggAndSausage.getMsg() + ", Total price :" +
battercakeWithEggAndSausage.getPrice());
}
The results are shown in the following figure .
There's no problem with the results . however , If the user needs a plus 2 An egg and 1 Pancakes with sausage , You can't create a class structure with the current class structure , The price can't be calculated automatically , Unless you create another class to customize . If the demand changes again , So it's obviously unscientific to add customization all the time .
Let's use decorator mode to solve the above problem . First create an abstract of the pancake Battercake class .
public abstract class Battercake {
protected abstract String getMsg();
protected abstract int getPrice();
}Create a basic pancake ( Or basic package )BaseBattercake.
public class BaseBattercake extends Battercake {
protected String getMsg(){
return " pancakes ";
}
public int getPrice(){ return 5; }
}Then create an abstract decorator that extends the package BattercakeDecotator class .
public abstract class BattercakeDecorator extends Battercake {
// Static proxy , delegate
private Battercake battercake;
public BattercakeDecorator(Battercake battercake) {
this.battercake = battercake;
}
protected abstract void doSomething();
@Override
protected String getMsg() {
return this.battercake.getMsg();
}
@Override
protected int getPrice() {
return this.battercake.getPrice();
}
}Then create an egg decorator EggDecorator class .
public class EggDecorator extends BattercakeDecorator {
public EggDecorator(Battercake battercake) {
super(battercake);
}
protected void doSomething() {}
@Override
protected String getMsg() {
return super.getMsg() + "+1 An egg ";
}
@Override
protected int getPrice() {
return super.getPrice() + 1;
}
}Create sausage decorators SausageDecorator class .
public class SausageDecorator extends BattercakeDecorator {
public SausageDecorator(Battercake battercake) {
super(battercake);
}
protected void doSomething() {}
@Override
protected String getMsg() {
return super.getMsg() + "+1 Sausages ";
}
@Override
protected int getPrice() {
return super.getPrice() + 2;
}
}Then write the client test code .
public class BattercakeTest {
public static void main(String[] args) {
Battercake battercake;
// Buy a pancake
battercake = new BaseBattercake();
// Pancakes are a little small , Want to add more 1 An egg
battercake = new EggDecorator(battercake);
// add 1 An egg
battercake = new EggDecorator(battercake);
// Very hungry , add 1 Sausages
battercake = new SausageDecorator(battercake);
// The biggest difference from static agents is that they have different responsibilities
// Static proxies don't have to satisfy is-a The relationship between
// Static agents will be enhanced , The same responsibility becomes different
// Decorators are more concerned with expansion
System.out.println(battercake.getMsg() + ", The total price :" + battercake.getPrice());
}
}The results are shown in the following figure .
Finally, let's look at the class diagram , As shown in the figure below .
2 Use decorator mode to extend log format output
To impress , Let's look at another application scenario . The demand is roughly like this , The system uses SLS Service monitoring project log , With JSON Format parsing , Therefore, you need to encapsulate the logs in the project into JSON Format and print . The existing log system adopts Log4j + Slf4j It's made of frames . The client invocation is as follows .
private static final Logger logger = LoggerFactory.getLogger(Component.class);
logger.error(string);
This prints out a random line of strings . When considering converting it into JSON When the format , The author adopts the decorator mode . At present, there are unified interfaces Logger And its concrete implementation class , What I want to add is a decorative class and really encapsulated into JSON Decorative products in format . Create decorator class DecoratorLogger.
public class DecoratorLogger implements Logger {
public Logger logger;
public DecoratorLogger(Logger logger) {
this.logger = logger;
}
public void error(String str) {}
public void error(String s, Object o) {
}
// Omit other default implementations
}Create specific components JsonLogger class .
public class JsonLogger extends DecoratorLogger {
public JsonLogger(Logger logger) {
super(logger);
}
@Override
public void info(String msg) {
JSONObject result = composeBasicJsonResult();
result.put("MESSAGE", msg);
logger.info(result.toString());
}
@Override
public void error(String msg) {
JSONObject result = composeBasicJsonResult();
result.put("MESSAGE", msg);
logger.error(result.toString());
}
public void error(Exception e) {
JSONObject result = composeBasicJsonResult();
result.put("EXCEPTION", e.getClass().getName());
String exceptionStackTrace = Arrays.toString(e.getStackTrace());
result.put("STACKTRACE", exceptionStackTrace);
logger.error(result.toString());
}
private JSONObject composeBasicJsonResult() {
// Assembled some runtime information
return new JSONObject();
}
}You can see , stay JsonLogger in , about Logger All kinds of interfaces , We all use JsonObject Object to a layer of encapsulation . When printing , Finally, call the native interface logger.error(string), Just this String The parameters have been decorated . If there is additional demand , You can write another function to implement . such as error(Exception e), Only one exception object is passed in , This is very convenient when calling .
in addition , In order to try not to change too much code and usage in the process of replacing the old with the new , The author is JsonLogger An internal factory class is added to the JsonLoggerFactory( This class is transferred to DecoratorLogger Maybe it's better ). It contains a static method , Used to provide the corresponding JsonLogger example . Finally, in the new log system , Use as follows .
private static final Logger logger = JsonLoggerFactory.getLogger(Client.class);
public static void main(String[] args) {
logger.error(" error message ");
}
For clients , The only difference from the original is that it will LoggerFactory Change it to JsonLoggerFactory that will do , Such an implementation , It will also be accepted and used by other developers faster and more easily . Finally, look at the class diagram shown in the figure below .
The most essential feature of the decorator pattern is to pull out the additional functions of the original class , Simplify the logic of the original class . Through these two cases , We can sum it up , In fact, abstract decorators are dispensable , You can choose according to the business model .
Pay attention to WeChat public number 『 Tom Bomb architecture 』 reply “ Design patterns ” The complete source code is available .
This paper is about “Tom Bomb architecture ” original , Reprint please indicate the source . Technology is about sharing , I share my happiness ! If this article helps you , Welcome to pay attention and like ; If you have any suggestions, you can also leave comments or private letters , Your support is the driving force for me to adhere to my creation . Pay attention to WeChat public number 『 Tom Bomb architecture 』 More technical dry goods are available !
边栏推荐
- Benchmarking Shopify? Similarities and differences between "two giants" of Chinese e-commerce SAAS and Weimeng
- Where is the domain name filed? What materials are required for domain name filing?
- Mainstay of network detection - nping User Guide
- If there are enumerations in the entity object, the conversion of enumerations can be carried out with @jsonvalue and @enumvalue annotations
- Development status of industrial Internet
- What is the industrial Internet? What is the industrial Internet platform?
- [untitled]
- Use cloudflare to defend against DDoS for free
- The same set of code returns normally sometimes and reports an error sometimes. Signature error authfailure SignatureFailure
- No serializer found for class ** and no propert no properties discovered to create BeanSerializer
猜你喜欢

Review of AI hotspots this week: the Gan compression method consumes less than 1/9 of the computing power, and the open source generator turns your photos into hand drawn photos

Stm32g474 infrared receiving based on irtim peripherals

Advanced BOM tool intelligent packaging function
Cloudpods golang practice

BIM model example

application. Yaml configuring multiple running environments

163 mailbox login portal display, enterprise mailbox computer version login portal

Introduction to development model + test model

How to fill in and register e-mail, and open mass mailing software for free

Leetcode969: pancake sorting (medium, dynamic programming)
随机推荐
Analysis report on development trends and prospects of China's pyrolytic boron nitride (PBN) component industry 2022-2028
Implementing cos signature with postman
How to improve the success rate of trademark registration? How long does it take to register a trademark?
Cloud game cannot select a server cloud game server fees
2020 language and intelligent technology competition was launched, and Baidu provided the largest Chinese data set
Measurement model 𞓜 pre determined variable # time Fe
Shopify has quietly taken the second place in e-commerce in North America. Is independent station the "magic weapon" to win?
The same set of code returns normally sometimes and reports an error sometimes. Signature error authfailure SignatureFailure
The blue screen will be displayed at a remote location, and the error code kmode will be reported_ EXCEPTION_ NOT_ Handled, the DMP file has the keyword cdd dll
Talk about 15 tips of SQL optimization
An attempt to use Navicat tool to copy and export MySQL database data
Tencent cloud won the first place in the cloud natural language understanding classification task
Centeros environment setup
Initial experience of creating partitioned tables under MySQL cases tdsql for MySQL (I)
Kubesphere upgrade & enable plug-ins after installation
My eight year relationship with the message queue
Junior network security engineers master these penetration methods and steadily improve their technology to become leaders!
How to set up a cloud desktop server? What are the advantages of cloud desktop?
Cloud recommendation Vol.1: quick start to remote control under f-stack, go modules and 5g!
Modify the original place where the method needs to be called and triggered