Reconstruction: Replace the conditional scheduler with Command to reconstruct the command
Note: This essay was inspired by Chapter VII of reconstruction and model, section 7.6, replacing the conditional scheduler with Command.
I will not explain the Command too much. Here I have two examples for some park friends: Command Example 1 Command Example 2.
Conditional Scheduler: My understanding of this term is,It is a combination of a relatively simple selection structure and a relatively independent business logic.
The following is a small example.
Code before reconstruction:
/// <Summary> /// you can easily select the branch layer if else // N relatively independent tasks /// </summary> /// <param name = "actionName "> </param> public void DoAction (string actionName) {if (actionName = "Action1") {// process the Console of the Action1 task. writeLine ("execution Task 1");} else if (actionName = "Action2") {// process Action2 task Console. writeLine ("execution Task 2");} else if (actionName = "Action3") {// process Action3 task // No processing operation }}
The reconstruction practices in refactoring and pattern are as follows:
Create a Command for each action, store these commands in a collection, and replace the conditional logic with the code for obtaining and executing the Command.
I will not describe the reconstruction steps in detail. Let's take a look at the reconstruction results:
Public class class2 {private Dictionary <string, CommandAbstract> dic; public class2 () {this. dic = new Dictionary <string, CommandAbstract> (); this. dic. add ("Action1", new Command1 (); this. dic. add ("Action2", new Command2 (); this. dic. add ("Action3", new Command3 ());} /// <summary> /// Replace the conditional scheduler in Command mode. /// </summary> /// <param name = "actionName"> </param> public void doAction (string actionName) {CommandAbstract command = null; if (dic. ContainsKey (actionName) {command = dic [actionName];} if (command! = Null) {command. execute () ;}} public abstract class CommandAbstract {public abstract void Execute ();} public class Command1: CommandAbstract {public override void Execute () {Console. writeLine ("execution Task 1") ;}} public class Command2: CommandAbstract {public override void Execute () {Console. writeLine ("execution Task 2") ;}} public class Command3: CommandAbstract {public override void Execute (){}}
Looking at hard-coded Dictionary, it is quite uncomfortable. If you often need to add a new Command, you may need to continue refactoring to keep it open and closed.
Solution:Use reflection instead of hard encoding (simple Plugin Mode)The reconstruction result is as follows:
Public static class CommandFactory {private static Dictionary <string, CommandAbstract> dic; static CommandFactory () {dic = new Dictionary <string, CommandAbstract> (); Type absType = typeof (CommandAbstract ); assembly assem = absType. assembly; foreach (Type t in assem. getTypes () {if (t. isClass &&! T. IsAbstract & t. IsSubclassOf (absType) {CommandAbstract command = Activator. CreateInstance (t) as CommandAbstract; if (command! = Null &&! Dic. containsKey (command. commandName) {dic. add (command. commandName, command) ;}}} public static CommandAbstract GetCommand (string commandName) {if (dic. containsKey (commandName) {return dic [commandName];} return null ;}} public class class2 {// <summary> /// rebuild the hard-coded file // </summary> /// <param name = "actionName"> </param> public void doAction (string actionName) {CommandAbstract command = Comman DFactory. GetCommand (actionName); if (command! = Null) {command. execute () ;}} public abstract class CommandAbstract {public string CommandName {get; protected set;} public abstract void Execute ();} public class Command1: CommandAbstract {public Command1 () {this. commandName = "Action1";} public override void Execute () {Console. writeLine ("execution Task 1") ;}} public class Command2: CommandAbstract {public Command2 () {this. commandName = "Action2";} public override void Execute () {Console. writeLine ("execution Task 2") ;}} public class Command3: CommandAbstract {public Command3 () {this. commandName = "Action3";} public override void Execute (){}}
How can we reconstruct a complex conditional expression?
Tip: responsibility chain mode.