Use the design mode to solidify your C # Program (3)

Source: Internet
Author: User

Use the design mode to solidify your C # Program (Part 1)

Design Patterns: Solidify Your C # Application Architecture with Design Patterns Chinese edition (Part 1)
Author: Samir Bajaj
Translator: glory

[Translation: C # advanced article. The translator simply sorts out the C # examples provided by Samir (some of the Code provided by the author cannot be compiled in the translator's environment) and compiles the corresponding C ++ example, put them in comments for readers to compare. All C # And C ++ debugging environments are Microsoft Visual Studio. NET 7.0 Beta2]

Decorator

Customer applications often need to enhance the services provided by some class methods. You may need to insert some pre-processing and post-processing code before and after the method call. One way to achieve this is simply to make different method calls. However, this method is not only troublesome, but is not conducive to the expansion of the framework. For example, if different customers obviously want to execute different pre-processing and post-processing tasks, the application logic will become obscure and difficult to maintain due to conditional statements. The problem is how to enhance the functions provided by the class without affecting the customer code, and the Decorator mode is exactly what is needed.
Let's look at an example of a class with the remote file transfer function. Such class code may be shown in table 5.

Table 5

Class FileTransfer
{
Public virtual void Download (string url, byte [] data, int size)
{
// Download an object
}
Public virtual void Upload (string url, byte [] data, int size)
{
// Upload a file
}
}

Assume that a client program is interested in this function. In addition to the ability to upload and download files, the customer's application also wants to write all file transfer requests and perform access checks into the log. One Implementation Method Based on the decorator mode is to derive a class from the FileTransfer class, reload the virtual method, and insert additional code before or after the base class method is called. See table 6.

Table 6

Class Decorator: FileTransfer
{
Private FileTransfer ft = new FileTransfer ();
Private bool IsAccessAllowed (string url)
{
Bool result = true;
// Determine whether to authorize the requested URL
Return result;
}
Private void LogAccess (string url)
{
// Write URL, time, user identity, and other information to the database
Console. WriteLine ("Logging access to {0}", url );
}
Public override void Download (string url, byte [] data, int size)
{
If (! IsAccessAllowed (url ))
Return;
Ft. Download (url, data, size );
LogAccess (url );
}
} The customer program can continue to work with the same interface [annotation: not a C # semantic interface. In fact, we can further improve this solution by changing the FileTransfer class and Decorator class to implement the same class with the Upload and Download methods. In this way, the customer program can work only according to the interface, and can be completely decoupled from the specific implementation.

When a certain range of extensions and tasks can be performed on the basis of existing classes and all extensions are defined as classes, the decorator mode allows you to dynamically and transparently add or remove features without affecting your code.

The following is a complete example of the decorator mode.

C # example:
Using System;
Class FileTransfer
{
Public virtual void Download (string url, byte [] data, int size)
{
// Download an object
}
Public virtual void Upload (string url, byte [] data, int size)
{
// Upload a file
}
}
Class Decorator: FileTransfer
{
Private FileTransfer ft = new FileTransfer ();
Private bool IsAccessAllowed (string url)
{
Bool result = true;
// Determine whether to authorize the requested URL
Return result;
}
Private void LogAccess (string url)
{
// Write URL, time, user identity, and other information to the database
Console. WriteLine ("Logging access to {0}", url );
}
Public override void Download (string url, byte [] data, int size)
{
If (! IsAccessAllowed (url) return;
Ft. Download (url, data, size );
LogAccess (url );
}
Public override void Upload (string url, byte [] data, int size)
{
If (! IsAccessAllowed (url) return;
Ft. Upload (url, data, size );
LogAccess (url );
}
}
Class Application
{
Public static void Main ()
{
Console. Write ("Enter URL to access :");
String url = Console. ReadLine ();
Console. Write ("Enable logging and access check? ");
String input = Console. ReadLine ();
Char ch = char. Parse (input );
Bool decoration = (ch = y | ch = Y );
FileTransfer ft = null;
If (! Decoration)
Ft = new FileTransfer ();
Else
Ft = new Decorator ();
Byte [] buf = new byte [1, 1024];
Ft. Download (url, buf, 1024 );
}
}
/* The following is the output result of a running task:
Enter URL to access:Www.csdn.net
Enable logging and access check? Y
Logging accessWww.csdn.net
*/
C ++ example: [: the reason why std: string and byte arrays are mixed in the following example is only to facilitate comparison with C # programs]
# Include "stdafx. h ";
# Include
# Include
Using namespace std;
Typedef unsigned char byte;
Class FileTransfer
{
Public:
Virtual void Download (string url, byte data [], int size)
{
// Download an object
}
Virtual void Upload (string url, byte data [], int size)
{
// Upload a file
}
};
Class Decorator: public FileTransfer // decorated file transfer
{
Private:
FileTransfer * ft;
Bool IsAccessAllowed (string url)
{
Bool result = true;
// Determine whether to authorize the requested URL
Return result;
}
Void LogAccess (string url)
{
// Write URL, time, user identity, and other information to the database
Cout <"Logging access to" <}
Public:
Decorator ()
{
Ft = new FileTransfer ();
}
~ Decorator ()
{
If (ft)
{
Delete ft;
Ft = NULL;
}
}
Void Download (string url, byte data [], int size)
{
If (! IsAccessAllowed (url) return;
Ft-> Download (url, data, size );
LogAccess (url );
}
Void Upload (string url, byte data [], int size)
{
If (! IsAccessAllowed (url) return;
Ft-> Upload (url, data, size );
LogAccess (url );
}
};
Int _ tmain (int argc, _ TCHAR * argv [])
{
Cout <"Enter URL to access :";
String url;
Cin> url;
Cout <"Enable logging and access check? Type y or Y to continue :";
Char ch;
Cin> ch;
Bool decoration = (ch = y | ch = Y );
FileTransfer * ft = NULL;
If (! Decoration)
Ft = new FileTransfer ();
Else
Ft = new Decorator ();
Byte * buf = new byte [1024];
Ft-> Download (url, buf, 1024 );
Delete [] buf;
If (ft! = NULL)
{
Delete ft;
Ft = NULL;
}
Return 0;
}
/* The following is the output result of a running task:
Enter URL to access:Www.csdn.net
Enable logging and access check? Y
Logging accessWww.csdn.net
*/
]


 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.