My work needs to write a bill conversion tool. In the process of writing this tool, I found that the entire implementation can be said to be the best embodiment of the policy mode. Perhaps use this example to explain the application of the policy mode, the most appropriate. The purpose of the single conversion tool is to convert a single text file for a service provider to another service provider. If you convert Unicom's single format to a moving words. The requirements of the spending conversion tool are hoped to implement multiple service providers single text files.
Let's analyze the task. First, various service providers' words are undoubtedly different. For example, after the word collection, the order of the field, the width of the field, and the separator between the fields are different. However, in general, the expression of the reply is roughly the same, which provides a technical feasible premise for us to implement the conversion.
The so-called conversion, it is necessary to read a bill text file, and then identify each row, then convert to a single text file that meets the corresponding service provider. The operation is simple, that is, the reading and writing of text files, different is the way to convert. According to the service provider, we should provide corresponding algorithms for each conversion. The so-called strategy mode is the packaging and abstraction of the algorithm, and the responsibility of the algorithm and itself are separated. So, what we have to do now is to abstract the algorithm of the conversion bill.
According to the requirements of the tool, the bill conversion should include 3 methods: 1. Convert the one-line string read from the file to the corresponding bill object; 2, convert a bill object to another words, Convert the words object to a string to make it easy to write a single text file;
According to the above analysis, we also need to establish corresponding objects for different words. For example: Netcom, Unicom and mobile phone number objects are:
public
Class
CNCCDR
{// network call single format object public property;}
public
Class
Cuccdr
{// common attribute of single-handed single format object;}
public
Class
CMCDR
{// mobile phone single format object public property;}
The algorithm of the bill conversion should be implemented. First, the algorithm needs to be abstracted, and the best choice for abstraction is to use the interface, for example, we define an interface IcDrConvert: public interface icdrconvert {}, in the interface, in the interface, in the interface, for example, in the interface. Conversion method. But now there is a problem, it is the conversion of the bill object. Since the method is in the interface, it is an abstraction. There may be a variety of words objects, and how specifically convert it, it can be determined when the specific implementation is required. Therefore, in the interface method, regardless of the return type, or incoming parameters, the bill object involved can only be abstract. Perhaps we can consider System.Object to represent a bill object, but a better way is to provide an abstract interface for all the bill objects.
Due to the current analysis, there is no public approach, so this abstract text is a logo interface: public interface icdrrecord {}
Now, the method of the conversion interface can be defined:
public
Interface
ICDRCONVERT
{ICDRRECORD CONVERT (String Record); ICDRRECORD Convert (Icdrrecord Record); String Convert (Icdrrecord Record);}
Natural, such an interface definition cannot be compiled. why? It is because the signature of the second method is repeated with the signature of the third method (the signature of the method and the return type are independent). Therefore, we need to modify the name for the third method. But we carefully think about it, is the conversion of the third method in the conversion interface? The task of this method is to convert a bill object to a String type. In fact, this responsibility does not require a special conversion object to complete, but should belong to the responsibility of the bill object itself. Think about .NET, all objects are derived from System.Object, and the Object type provides the toString () method.
From the perspective of the design, the best way is the toString () method of Override System.Object in the specific bill object, rather than in the conversion object, providing the conversion algorithm.
However, in mind, the object of the abstract words single interface type will be more calling more in the bill processing, and maybe we will abstract the toString () method to be better in IcDrRecord.
public
Interface
Icdrrecord
{String Tostring ();
public
Interface
ICDRCONVERT
{Icdrrecord Convert (String Record); ICDRRECORD Convert (Icdrrecord Record);
And specific bill objects should be implemented in IcDrRecord interface. Because each of the words objects have inherited System.Object, the toString () method of the object object is indirectly inherited, so the phone number should override the method:
public
Class
CNCCDR: ICDRRECORD
{// network call single-format object public property; // Rewrive Object's toString () method, and also implement the TOSTRING () method of interface ICDRRECORD; public override string toString () {// Implement specific content;} }
public
Class
Cuccdr: ICDRRECORD
{// Connect the public property of the single format object; // Rewind Object's toString () method, and also implement the TOSTRING () method of interface ICDRRECORD; public override string toString () {// implement specific content;} }
public
Class
CMCDR: ICDRRECORD
{// mobile phone single format object public attribute; // Rewrive Object's toString () method, and also implement the TOSTRING () method of interface IcDrrecord; public override string toString () {// implement specific content;} }
Here is a key implementation. Since we have abstracted to the conversion algorithm, the specific conversion algorithm is achieved according to the policy mode, it is the thing that water to the stream. Before implementing the code, let's take a look at the UML class diagram:
Note to see the orange section, this part is the main body of the strategy mode. Interface ICDRCONVERT is an abstract policy role, class CNCTOCUC, CuctoCM as a specific policy role, which implements the algorithm that converts the network call single conversion to the Unicom single, and the co-call single conversion to China Mobile. According to actual needs, you can also add multiple similar specific policy roles and implement ICDRCONVERT interface: public
Class
CNCTOCUC: ICDRCONVERT
{Public icdrrecord communication {// Implement specific conversion algorithm;} public icdrrecord convert {// implement specific conversion algorithm;}}
The implementation of class CuctoCM is similar, no longer repetitive. So what is the benefit of implementing the policy mode? Please pay attention to the CDROP class above. This class is an abstract class that provides a constructor that can pass the IcDrConvert object:
public
Abstract
Class
CDROP
{Protected ICdrConvert _convert; protected string _sourceFileName; protected string _targetFileName; public CdrOp (string soureFileName, string targetFileName, ICdrConvert convert) {_sourceFileName = soureFileName; _targetFileName = targetFileName; _convert = convert;} public abstract void HandleCdr ();}
CDRFileop inherits abstract class CDROP:
public
Class
CDRFileop
{Public override void HandleCdr () {Read (); Write ();} private string Read () {using (StreamReader sd = new StreamReader (_sourceFileName)) {ICdrRecord cdr = null; string line; while ((line = sd. ReadLine ())! = Null) {// First call the icdrrecord communication method; / / The IcDrRrecord Convert (IcDrRecord Record) method; // Behind to the conversion of the implementation, ICDRCONVERT incorporated by the constructor Object decision; CDR = _Convert.convert (_Convert.convert (line)); _List.Add (CDR);}}} private void write ()} (streamwriter sw = new streamwriter (_targetfileename, true) {sw.write ({sw.write ());}}} private arraylist _list} private arraylist _list} private arraylist _list} private arraylist _list = new arraylist ();} This class implements an abstract class CDROP Handlecdr () method. However, the specific implementation details are completed in the private method read () and Write () (according to the actual situation, the READ and WRITE methods can be used as public abstract methods or protection methods, and in abstract CDROP The implementation of the HandleCDR method is specifically provided in class CDROP. This method calls the READ and WRITE methods so that the template mode mode is used.
Note that there is no specific class in the Read and Write methods. Whether it is a bill object, or a bill conversion object, is an abstract interface object. Especially in the read () method, the CONVERT method of _Convert is called: CDR = _Convert.convert (_Convert.convert (line)); where the internal Convert method, ie _convert.convert (line) is read The string of strings is converted to the IcdrRecord object, and then convert the object to another bill format object by calling the _convert.convert (IcDrRecord Record) method, but the type is still IcdrRecord.
So, in these conversion, which type format object is converted to? This is determined by the _convert field. And this object is passed from the parameters of the constructor.
The same reason, in the Write () method, you can also see the benefits of all the words object abstraction as an interface ICDRRECORD. Call the toString () method via ICDRRECORD to avoid introducing a specific object in CDRFileop. To know, once the program introduces a specific object, the coupling is high. Once the demand changes, the encoding needs to be modified. With the above architecture, the client call is very convenient:
public
Class
Client
{Public static void main () {string sourceFileName = @ "c: /cnccdr.txt"; string target1 = @ "c: /cuccdr.txt"; string target2 = @ "c: /cmcdr.txt"; // Net call single conversion to the Unless single; icdrop op1 = new cdrfileop (SourceFileName, Target1, new cnctocuc ()); op1.handlecdr (); // Translate the Unless single conversion generated by the conversion to mobile posts; ICDROP OP2 = New cdrfileop (target1, target2, new cuctocm ()); op2.handlecdr ();}}
Of course, we can also introduce factory models to create CDRFileop objects. Or set the ICDRCONVERT object to CDRFileop, not through constructor.
Through this explanation, you will find that the strategy mode is nothing mysterious, nothing more than an object, the only difference is that the strategy mode is an abstraction of the algorithm. So, "Abstraction is the last word", when we are making an object-oriented design, you need to remember this sentence!