Recently, I am working on a small project to regularly calculate some financial indicators. During system operation, different errors may occur due to data or other reasons. However, because the system will be running on the server for hours, some irrelevant errors should not affect the system's calculation of other indicators, but the errors must be recorded.
In fact, this is very easy to implement, as long as you call the log writing function in the case of an error.
But the problem is that when an error occurs, the error log may not be written to a file, but may be output to a listview on the interface or even sent over the network.
For example
Code
If(Error)
{
Writelogtotxtfile ();
Writelogtolistview ();
Sendlogtonet ();
}
Of course, these three methods are just assumptions. if you add a new method, I may add new function calls in all the places where errors occur.
You may say that writing a function called writelog () encapsulates various log-writing functions in it.
Like this
1 If (Error)
2 {
3Writelog (StringLog );
4}
5
6 Void Writelog ( String Log)
7 {
8Writelogtotxtfile (log );
9Writelogtolistview (log );
10//When a new log writing method is added, add
11}
This is certainly acceptable, but not elegant enough. Maybe this reminds you of something! Yes, observer mode.
Observer Mode --
Defines a one-to-many dependency between objects. When the status of an object changes, all objects dependent on it are notified and automatically updated.
In fact, the observer mode is usually used to process UI operations. For example, when a button is clicked, N observers respond. In this example, the observed object is no longer a UI control but a log output by the system.
1 Code
2 // Log Structure
3 Struct Deflognode
4 {
5 Deflognode (coledatetime tmdate, String Sztext, String Szdescription)
6 : M_tmdate (tmdate ),
7 M_sztext (sztext ),
8 M_szdescription (szdescription)
9 {
10
11}
12 Coledatetime m_tmdate;
13 String M_sztext;
14 String M_szdescription;
15 } ;
16
17 // Log observer base class
18 Class Clogobserverbase
19 {
20Public:
21Virtual VoidInserterrorlog (deflognode&Log)= 0;
22} ;
23
24 // The observer who writes the file
25 Class Clogtofile: Public Clogobserverbase
26 {
27 Public :
28 Clogtofile () {
29M_pfile=NULL;
30}
31 Void Inserterrorlog (deflognode & Log );
32
33 Private :
34 File * M_pfile;
35
36 Bool openlogfile ();
37 Bool writelogfile ( String Szlog );
38 Bool closelogfile ();
39 } ;
40 // Written to the VC output window during debugging
41 Class Clogtodebugoutput: Public Clogobserverbase
42 {
43VoidInserterrorlog (deflognode&Log );
44} ;
45
46
47 Class Clogadmin
48 {
49 Public :
50 Static Copiable_ptr < Clogadmin > Getinstance ();
51 // Here we use the single-piece mode. When different types of logs are required, we can make some small changes and use a map to manage multiple Singleton logs.
52
53 Void Adderrorobserver (clogobserverbase * Pobserver );
54
55 Void Insertoneerror (deflognode & Log );
56
57 Private :
58 Clogadmin () {} ;
59 Vector < Copiable_ptr < Clogobserverbase > > M_verrorobservers;
60
61 Static Copiable_ptr < Clogadmin > S_instance;
62 // Copiable_ptr is a smart pointer to reference counts written by myself. Leave a message if necessary
63 } ;
In this way, you only need
1 Clogadminptr log = Clogadmin: getinstance ();
2 Log -> Adderrorobserver ( New Clogtofile ());
3 Log -> Adderrorobserver ( New Clogtodebugoutput ());
4
5 // When you add an output method, you only need to derive a new subclass and add a line after the above Code
If you have never touched the observer mode, you can understand this problem. We are Designing object-orientedProgramAlways follow certain principles.
first, the dependency is inverted. The low-level structure depends on the High-level structure. Here, the calling error log is in the high-level structure, while the specific method is in the lower-level structure. If you want to Article at the beginning, it means that the high-level structure depends on the underlying structure, and the program is coupled, because all log writing methods must be known everywhere.
second, when there is a single responsibility, you must know which log writing methods are required to record the logs, so that they do not have a single responsibility.
third, open and closed. -- open to extension; closed -- disable modification. Here, the extension refers to the method for extending the specific log writing. Modification means that when a log writing method is added, the existing program of the system should not be modified.