Decoupling request senders from receivers-command mode (2)

Source: Internet
Author: User

3. Complete Solution

To reduce the coupling between function keys and function processing classes and allow users to customize the functions of each function key, sunny software developers use the command mode to design the "custom function keys" module, its core structure 4 is shown below:

 

Figure 4 custom function key core structure

In Figure 4, fbsettingwindow is the "function key settings" interface class, functionbutton acts as the request caller, command acts as the abstract command class, minimizecommand and helpcommand act as the specific command class, And windowhanlder and helphandler act as the request receiver. The complete code is as follows:

Import Java. util. *; // function key setting window class fbsettingwindow {private String title; // window title // define an arraylist to store all function keys private arraylist <functionbutton> functionbuttons = new arraylist <functionbutton> (); Public fbsettingwindow (String title) {This. title = title;} public void settitle (String title) {This. title = title;} Public String gettitle () {return this. title;} public void addfunctionbutton (functionbutton FB) {func Tionbuttons. add (FB);} public void removefunctionbutton (functionbutton FB) {functionbuttons. remove (FB);} // display window and function key public void display () {system. out. println ("display window:" + this. title); system. out. println ("display function key:"); For (Object OBJ: functionbuttons) {system. out. println (functionbutton) OBJ ). getname ();} system. out. println ("------------------------------") ;}// function key class: Request sender class functionbutton {private string n Ame; // function key name private command; // maintain a reference to an abstract command object public functionbutton (string name) {This. name = Name;} Public String getname () {return this. name;} // enter the public void setcommand (command) {This. command = command;} // Method for sending a request public void onclick () {system. out. print ("Click function key:" commandid command.exe cute () ;}// abstract command class abstract class command {public abstract void execute () ;}// HELP command class: class helpcommand E Xtends command {private helphandler hhobj; // maintain the reference to the request receiver public helpcommand () {hhobj = new helphandler ();} // command execution method, public void execute () {hhobj. display () ;}// minimal command class: Class minimizecommand extends command {private comment whanlder whobj; // maintain reference to the request receiver public minimizecommand () {whobj = new windowhanlder ();} // The command execution method that calls the request recipient's business method public void execute () {whobj. minimize () ;}}// window processing class: Request recipient clas S too whanlder {public void minimize () {system. Out. println ("minimize the window to the tray! ") ;}}// Help document processing class: Request recipient class helphandler {public void display () {system. Out. println (" Show Help document! ");}}

To improve system flexibility and scalability, we store the class names of specific command classes in the configuration file, and read the configuration file and reflect the generated objects through the tool class xmlutil, the xmlutil class code 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, different parameters can be used to return the public static object getbean (int I) {try {// create the Document Object documentbuilderfactory dfactory = documentbuilderfactory. newinstance (); documentbuilder builder = dfactory. newdocumentbuilder (); document DOC; Doc = builder. parse (new file ("config. XML "); // get the text node containing the class name nodelist NL = Doc. getelementsbytagname ("classname"); node classnode = NULL; If (0 = I) {classnode = NL. item (0 ). getfirstchild ();} else {classnode = NL. item (1 ). getfirstchild ();} string cname = classnode. getnodevalue (); // generate an Instance Object using the class name and return Class C = Class. forname (cname); object OBJ = C. newinstance (); Return OBJ;} catch (exception e) {e. printstacktrace (); return NULL ;}}}

The configuration file config. xml stores the Class Name of the specific builder class. The Code is as follows:

<?xml version="1.0"?><config><className>HelpCommand</className>    <className>MinimizeCommand</className></config>

Write the following client test code:

Class client {public static void main (string ARGs []) {fbsettingwindow fbsw = new fbsettingwindow ("function key settings"); functionbutton Fb1, fb2; fb1 = new functionbutton ("function key 1"); fb2 = new functionbutton ("function key 1"); command command1, command2; // generate the specific command object command1 = (command) xmlutil by reading the configuration file and reflection. getbean (0); command2 = (command) xmlutil. getbean (1); // inject command objects into function keys fb1.setcommand (command1); fb2.setcommand (command2); fbsw. addfunctionbutton (Fb1); fbsw. addfunctionbutton (fb2); fbsw. display (); // call the function key's business method fb1.onclick (); fb2.onclick ();}}

Compile and run the program. The output result is as follows:

Display window: function key settings

Show function keys:

Function key 1

Function key 1

------------------------------

Click the function key to display the help document!

Click function key: Minimize the window to the tray!

If you need to modify the function of the function key, for example, a function key can implement "automatic screenshot", you only need to add a new specific command class, in which the command class and the screen handler (screenhandler) create an association between them, and then inject the object of the specific command class into a function key through the configuration file. The original code does not need to be modified and complies with the "open/close principle ". In this process,Each specific command class corresponds to the handler (receiver) of a request. By injecting different command objects to the request sender, the same sender can correspond to different recipients, in this way, we can encapsulate a request as an object and parameterize the customer with different requests"The client only needs to inject a specific command object as a parameter to the request sender, without directly operating on the request receiver.

 

[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.