Note: This essay is inspired by the "Refactoring and Patterns" section seventh, section 7.6, with the command to replace the conditional scheduler.
For command not to do too much explanation, here I looked for two examples, for some of the garden friends to see: command Example 1 command Example 2.
Conditional Scheduler: My understanding of this noun is that it is a relatively simple combination of the choice structure and the relatively independent business logic.
Words are not very well understood, here is a small example of it.
Pre-refactoring code:
/// <summary> ///It's a simple choice. Branch one layer if else///n a relatively independent task/// </summary> /// <param name= "ActionName" ></param> Public voidDoAction (stringactionname) { if(ActionName = ="Action1") { //Handling Action1 TasksConsole.WriteLine ("Perform task 1"); } Else if(ActionName = ="Action2") { //Handling Action2 TasksConsole.WriteLine ("Perform task 2"); } Else if(ActionName = ="Action3") { //Handling Action3 Tasks//No processing action } }
The refactoring in refactoring and pattern article is:
Create a command for each action, store the command in a collection, and replace the conditional logic with the code that gets and executes the command.
Refactoring step I don't give a detailed description, look at the results after the refactoring:
Public classClass2 {Privatedictionary<string, commandabstract>dic; PublicClass2 () { This. DIC =Newdictionary<string, commandabstract>(); This. DiC. ADD ("Action1",NewCommand1 ()); This. DiC. ADD ("Action2",NewCommand2 ()); This. DiC. ADD ("Action3",NewCommand3 ()); } /// <summary> /// application Command modeReplace Conditional Scheduler/// </summary> /// <param name= "ActionName" ></param> Public voidDoAction (stringactionname) {commandabstract command=NULL; if(DIC. ContainsKey (actionname)) {command=Dic[actionname]; } if(Command! =NULL) {command. Execute (); } } } Public Abstract classCommandabstract { Public Abstract voidExecute (); } Public classCommand1:commandabstract { Public Override voidExecute () {Console.WriteLine ("Perform task 1"); } } Public classCommand2:commandabstract { Public Override voidExecute () {Console.WriteLine ("Perform task 2"); } } Public classCommand3:commandabstract { Public Override voidExecute () {}}
Looking at hard-coded Dictionary, if you often need to add a new command, you may also need to continue refactoring-making it follow the open and closed principle.
Scenario: using reflection instead of hard coding (simple plugin mode), the results of the refactoring are as follows:
Public Static classCommandfactory {Private Staticdictionary<string, commandabstract>dic; Staticcommandfactory () {dic=Newdictionary<string, commandabstract>(); Type Abstype=typeof(commandabstract); Assembly Assem=abstype.assembly; foreach(Type tinchAssem. GetTypes ()) {if(T.isclass &&!t.isabstract &&t.issubclassof (Abstype)) {commandabstract command= Activator.CreateInstance (t) ascommandabstract; if(Command! =NULL&&!DiC. ContainsKey (Command.commandname)) {dic. ADD (command.commandname, command); } } } } Public StaticCommandabstract GetCommand (stringcommandName) { if(DIC. ContainsKey (CommandName)) {returnDic[commandname]; } return NULL; } } Public classClass2 {/// <summary> ///Refactoring hard-coded/// </summary> /// <param name= "ActionName" ></param> Public voidDoAction (stringactionname) {commandabstract command=Commandfactory.getcommand (ActionName); if(Command! =NULL) {command. Execute (); } } } Public Abstract classCommandabstract { Public stringCommandName {Get;protected Set; } Public Abstract voidExecute (); } Public classCommand1:commandabstract { PublicCommand1 () { This. CommandName ="Action1"; } Public Override voidExecute () {Console.WriteLine ("Perform task 1"); } } Public classCommand2:commandabstract { PublicCommand2 () { This. CommandName ="Action2"; } Public Override voidExecute () {Console.WriteLine ("Perform task 2"); } } Public classCommand3:commandabstract { PublicCommand3 () { This. CommandName ="Action3"; } Public Override voidExecute () {}}
If the conditional expression is more complex, how can it be reconstructed?
Hint: Responsibility chain mode.
Refactoring: Replacing conditional schedulers with command