Decoration mode
Decoration mode refers to dynamically extending the function of an object without changing the original class file and using inheritance. It wraps the real object by creating a wrapper object, that is, decoration-- Baidu Encyclopedia
Decorator mode is mainly to add new behavior to an object. The effect is similar to that of subclass extending parent class, but the implementation method is different from inheritance, and it is more flexible.
Decoration pattern class diagram
Componet: defines the interface base class.
ConcreteComponent: the concrete decorated target object.
Decorator: decoration class base class.
ConcreteDecoratorA: specific decoration class A
ConcreteDecoratorB: specific decoration class B
Application scenario
actual demand
Realize a customized log, including log printing, adding time stamp, printing to terminals and files, etc.
analysis
One of the most basic log functions is to print and output the code debugging to the specified file. Now it is necessary to add time stamp and terminal display functions on this basis. According to the previous writing method, directly modifying the log function code may cause the following problems:
- The log function is referenced too much, and a slight carelessness will cause compilation problems.
- The log function tends to be stable. Direct modification may add hidden bugs.
Solution
The decoration mode is introduced to encapsulate a layer of decoration code on the original log interface. In this way, there is no need to modify the original log code and ensure the development of new requirements.
Log class diagram
effect
Client code
int main(int argc, char *argv[]) { LOGI("main", "Welcome kaiyuan519!\n"); LOGD("main", "Welcome kaiyuan519!\n"); return 0; }
Terminal printing
It can be seen from the above figure that not only the string printed by the client is output to the same level directory, but also the time stamp and terminal display functions are added.
Source code
The code is too long. This article only pastes the main code functions. You can enter all the source code in the background of the official account.
Client code
int main(int argc, char *argv[]) { LOGI("main", "Welcome kaiyuan519!\n"); LOGD("main", "Welcome kaiyuan519!\n"); return 0; }
Reference modification class adds new features to log
// Custom log: add timestamp and terminal printing int sys_log(int level, const char *tag, const char *msg) { // Save to file if (!pLog) { pLog = CLog::GetInstance(); } // Display at terminal if (!pLog2Terminal) { pLog2Terminal = CLog2Terminal::GetInstance(pLog); } // Add log debugging information: timestamp, level and label if (!pLogAddInfo) { pLogAddInfo = CLogAddInfo::GetInstance(pLog2Terminal); } // Interface for finishing decoration pLogAddInfo->SetLogLevel(level); pLogAddInfo->WriteLog(tag, msg); return 0; }
Log add information code
int CLogAddInfo::WriteLog(const char *tag, const char *msg) { char logStr[LOG_STR_LENGTH] = {0}; // The length of one log print shall not exceed 2000 int length = 0; // log add debugging information: time, level, tag: 2022-01-14 10:09:51.106 I / < main > length = get_local_time(logStr); snprintf(logStr + length, LOG_STR_LENGTH - length, "%s <%s> %s", LEVEL_STR[levelIndex], tag, msg); CCustomLog::WriteLog(tag, logStr); return strlen(logStr); }
Output to terminal code
int CLog2Terminal::WriteLog(const char *tag, const char *msg) { // Output to terminal fprintf(stdout, "%s", msg); // Add new function return CCustomLog::WriteLog(tag, msg); }
summary
- The implementation method of decoration mode is nothing more than encapsulating the original single function through layers of functional interfaces, and providing the encapsulated interface to the client. Since the functional interface is the same as the native interface, the use code of the client does not need to be changed.
- The decoration mode is only part of changing its appearance, and the original function is retained.
- When in use, the required functions can be added at will without modifying the original functions. It is also flexible to use.
- The disadvantage is that the decoration mode has strict initialization requirements, and the code is difficult to understand. When the demand increases, many classes will be added. Therefore, new functions should be treated with caution.