Design Pattern reflection and configuration file

Source: Internet
Author: User

To meet the "open/closed principle", most design patterns introduce abstract layers, such as factory method mode, abstract factory mode, adapter mode, Bridge Mode, command mode, and Policy mode. The client code is programmed for the abstraction layer, and its subclass is specified when the program is running. According to the "Rishi replacement principle" and object-oriented polymorphism, The subclass object will overwrite the parent class object at runtime. To extend or modify the system, you only need to modify the subclass class name.In specific implementation, you can add or replace subclass without modifying any client code by introducing a configuration file.The basic implementation process is as follows:

(1) The client is programmed for the abstraction layer. No specific class names appear in the client code, that is, the client does not directly instantiate the object;

(2) Introduce a configuration file in plain text format, usually an XML file, and store the specific class name in the configuration file;

(3) using dom (Document Object Model, Document Object Model), SAX (simple
Apifor XML) and other XML parsing technologies to obtain the class names stored in the configuration file;

(4) create an object based on the class name through the reflection mechanism in the client code. Replace the reference of the parent class object with the object created by reflection. When the program runs, the subclass method will be called to implement business functions;

(5) to expand the function, you only need to add a new subclass to inherit the abstract parent class, modify the configuration file, and re-run the program. If you need to replace the function, you only need to replace the original subclass class name stored in the configuration file with another subclass class name. No need to modify the source code of both the class library and the client, whether it is extension or replacement, and it fully complies with the open and closed principles.

The following describes how to use the configuration file and reflection mechanism through the factory method mode:

[Example description]: The BMW (BMW) factory can produce BMW cars, and the Benz factory can produce Mercedes-Benz cars. This scenario is designed using the factory method model. The following figure shows the example:

Figure 1 instance type diagram of factory method mode


In Figure 1, carfactory is an abstract factory that declares the factory method producecar () and implements this method in its subclass to return a specific product. The following code appears in the client code:

Carfactory CF;

Car car;

Cf = new bmwfactory (); // create a factory

Car = Cf. producecar (); // use the factory method to create a product object

Car. Run (); // call the Business Method of the Product

In the above Code, the client programming for the abstract layer, but the specific factory subclass class name is involved when creating a specific factory. Pay attention to the bold line of code. If you need to change the product, for example, to change BMW to Benz, you need to change the factory to benzfactory, which will cause the client code to be modified. From the client perspective, the open and closed principles are violated, so the above code needs to be improved. Introducing configuration files and reflection mechanisms is one of the best improvement methods.

First, we store the specific factory class names in the following XML documents:

<? XML version = "1.0"?>

<Config>

<Classname> bmwfactory </classname>

</Config>

This XML document is a configuration file used to store the class name of a specific class. Mainstream service layer frameworks such as spring use xml configuration files.

To dynamically create a subclass object, we need to design another tool class xmlutil to read the xml configuration file, which is implemented in Java. In the design of xmlutil, two technical points of the Java language are required. One is Dom, which is the operation of XML files. For details about Dom learning, refer to other related books and materials, it will not be extended here; the second is the Java reflection mechanism, which will give a brief introduction to the Java reflection mechanism.

Java reflection (Java reflection) is a mechanism used to obtain information about a class with a known name or an existing object when the program is running, including information about the class methods, attributes, and parent classes, it also includes instance creation and instance type determination. The most frequently used class in reflection is class. the instance of the class represents the classes and interfaces in the running Java application, and its forname (stringclassname) method can return the information associated with a class or interface with a given string name.
Class object, and then create a new instance of the class represented by this object through the newinstance () method of the class object, that is, the instance of the class is obtained through a class name string. To create a String object, the Code is as follows:

// Generate an Instance Object using the class name and return it

Class C = Class. forname ("string ");

Object OBJ = C. newinstance ();

Return OBJ;

In addition, the JDK also provides the java. Lang. Reflect package, which encapsulates some other reflection-related classes. In this book, we only use the simple reflection code mentioned above and will not extend it here.

After Dom and reflection mechanisms are introduced, you can read the XML file in xmlutil and create the corresponding object based on the class name stored in the XML file. The detailed code of the xmlutil class is as follows:

Import javax. xml. parsers .*;

Import org. W3C. Dom .*;

Import org. xml. Sax. saxexception;

Import java. Io .*;

Public class xmlutil

{

// This method is used to extract a specific class name from the xml configuration file and return an Instance Object

Public static object getbean ()

{

Try

{

// Create a DOM Document Object

Documentbuilderfactory dfactory = documentbuilderfactory. newinstance ();

Documentbuilder builder = dfactory. newdocumentbuilder ();

Document Doc;

Doc = builder. parse (new file ("config. xml "));

// Obtain the text node containing the class name

Nodelist NL = Doc. getelementsbytagname ("classname ");

Node classnode = NL. Item (0). getfirstchild ();


String cname = classnode. getnodevalue ();

// Generate an Instance Object using the class name and return it

Class C = Class. forname (cname );

Object OBJ = C. newinstance ();

Return OBJ;

}

Catch (exception E)

{

E. printstacktrace ();

Return NULL;

}

}

}

With the xmlutil class, we do not directly use the new keyword in the client code to create a specific factory class, but store the class names of the specific factory classes in the XML file, then, the object is instantiated using the static factory method getbean () of the xmlutil class. The code is modified as follows:

Carfactory CF;

Car car;

Cf = (carfactory) xmlutil. getbean (); // getbean ()The return type of is object. Forced type conversion is required here.

Car = Cf. producecar ();

Car. Run ();

It is easier to read the configuration file and reflection in C #. We only need to add a configuration file in XML format, such as app. config. The Code is as follows:

<? XML version = "1.0" encoding = "UTF-8"?>

<Configuration>

<Deleetask>

<Add key = "Factory" value = "demo. carfactory"/>

</Appsettings>

</Configuration>

In. net reflection generation object is also very simple, because in.. net programs encapsulate type metadata information. Therefore, you can first load an assembly using the load ("assembly name") method of assembly, and then use its createinstance ("namespace. class ") method to create an object type object based on the class name. You can convert it to the desired type as needed. The sample code is as follows:

// Import the namespace

Using system. reflection;

Object OBJ = assembly. Load ("assembly name"). createinstance ("namespace. Class ");

In the above Code, the "namespace. Class" can be stored in the configuration file, and the class name string stored in the configuration file can be obtained by using the deleettings attribute of the configurationmanager class. The client code is as follows:

Carfactory CF;

Car car;

// Read the configuration file

String factorystr = configurationmanager. receivettings ["Factory"];

// Reflect the generated object. The Assembly name is demo.

Cf = (carfactory) Assembly. Load ("Demo"). createinstance (factorystr );

Car = Cf. producecar ();

Car. Run ();


Due to the features of the C ++ language, the process of reflecting and generating objects in C ++ similar to Java or C # is relatively complicated. Interested readers can refer to other relevant materials, it will not be extended here.

After the configuration file and reflection mechanism are introduced, it is easy to replace or add new classes. You only need to add new classes and modify the configuration file, you do not need to make any changes to the existing class library and client code. This fully complies with the open and closed principles. In many design modes, you can introduce configuration files and reflection mechanisms to improve the client code. For example, in abstract factory mode, you can store specific factory class names in the configuration file, in the adapter mode, you can store the adapter class name in the configuration file, and in the policy mode, you can store the specific policy class name in the configuration file. Through code improvement, the system can have better scalability and flexibility, and meet the requirements of various object-oriented design principles.

[Author: Liu Wei http://blog.csdn.net/lovelion]

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.