How to Implement code refactoring?
In the past few days, I have taken over the code of a colleague, and the pile of if related to interface development seems so painful. This problem is also easy for many new users, so I wrote this refactoring specially.
Let's take a look at the problem with this Code. The code block logic in if else is hard to modify, making it reusable 0 and hard to read. Of course, if there are only one or two or three if, this is not a problem.
However, if there is more code, it will make maintenance difficult.
If (strMsgType = "text ")
{
TextContentClient = rootElement. SelectSingleNode ("Content"). InnerText;
StrResult = SetMsgType_Text (strClientName, textContentClient, db, strServerName, Identity );
System. Diagnostics. Trace. WriteLine (strResult );
Return Content (strResult );
}
Else if (strMsgType = "event ")
{
String eventType = rootElement. SelectSingleNode ("Event"). InnerText. ToLower ();
If (eventType = "subscribe ")
{
String keyCode = "";
If (rootElement. SelectSingleNode ("EventKey ")! = Null)
KeyCode = rootElement. SelectSingleNode ("EventKey"). InnerText. ToLower ();
StrResult = FormatEventSubscribe (keyCode );
RecordReplyMessage ();
Return Content (strResult );
}
Else if (eventType = "scan ")
{
String keyCode = rootElement. SelectSingleNode ("EventKey"). InnerText. ToLower ();
Var outLetName = "welcome ";
Var outletDB = ShoppingContext. CreateInstance (Identity );
Var outLetModel = outletDB. Outlets. FirstOrDefault (o => o. SceneId = Int32.Parse (keyCode ));
If (outLetModel! = Null)
OutLetName + = outLetModel. Name;
Return Content (GetTextTemp (strClientName, strServerName, outLetName ));
}
Else if (eventType = "click ")
{
String keyCode = rootElement. SelectSingleNode ("EventKey"). InnerText. ToLower ();
StrResult = FomatMenuMessage (keyCode );
Return Content (strResult );
}
Else if (eventType = "unsubscribe ")
{
Var subIds = db. replyRecords. where (r => r. fromOpenId = this. clientId. toString () & r. EMessType = EEventType. subscribe. toString () & r. keyWord! = Null). Select (o => o. KeyWord). ToArray ();
Var unSubIds = db. replyRecords. where (r => r. fromOpenId = this. clientId. toString () & r. EMessType = EEventType. unsubscribe. toString () & r. keyWord! = Null). Select (o => o. KeyWord). ToArray ();
Var SencesId = "";
Foreach (var k in subIds)
{
If (! UnSubIds. Contains (k ))
{
This. ReplyModel. KeyWord = k;
Break;
}
}
This. ReplyModel. EMessType = EEventType. Unsubscribe. ToString ();
RecordReplyMessage ();
}
}
Else if (strMsgType. ToLower () = "location ")
{
String strLocation_X = rootElement. SelectSingleNode ("Location_X"). InnerText;
String strLocation_Y = rootElement. SelectSingleNode ("Location_Y"). InnerText;
StrResult = FormatOutLetLBS (double. Parse (strLocation_X), double. Parse (strLocation_Y), 10 );
// StrResult = FormatTextMessage (strLocation_X + "|" + strLocation_Y );
Return Content (strResult );
}
Else if (strMsgType. ToLower () = "image ")
{
String strImgUrl = rootElement. SelectSingleNode ("PicUrl"). InnerText;
}
A better solution is to extract the code in the statement block and write it as a function, as shown below:
Public class MessageProcesser
{
Public ReplyMessage Process (string xml)
{
Var msg = PostMessage. FromXml (xml );
Switch (msg. MsgType)
{
Case Models. PostMessageType. Event:
Var eventType = (EventMessage) msg). Event;
Switch (eventType)
{
Case EventType. Click:
Return ProcessClickEvent (ClickEvent) msg );
Case EventType. Location:
Return ProcessLocationEvent (LocationEvent) msg );
Case EventType. Scan:
Return ProcessScanEvent (ScanEvent) msg );
Case EventType. Subscribe:
Return ProcessSubscribeEvent (SubscribeEvent) msg );
Case EventType. Unsubscribe:
Return ProcessUnsubscribeEvent (UnsubscribeEvent) msg );
}
Break;
Case Models. PostMessageType. Image:
Return ProcessImageMessage (ImageMessage) msg );
Case Models. PostMessageType. Link:
Return ProcessLinkMessage (LinkMessage) msg );
Case Models. PostMessageType. Location:
Return ProcessLocationMessage (LocationMessage) msg );
Case Models. PostMessageType. Text:
Return ProcessTextMessage (TextMessage) msg );
Case Models. PostMessageType. Video:
Return ProcessVideoMessage (VideoMessage) msg );
Case Models. PostMessageType. Voice:
Return ProcessVoiceMessage (VoiceMessage) msg );
}
Return null;
}
Protected virtual ReplyMessage ProcessClickEvent (ClickEvent msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessLocationEvent (LocationEvent msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessScanEvent (ScanEvent msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessSubscribeEvent (SubscribeEvent msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessUnsubscribeEvent (UnsubscribeEvent msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessImageMessage (ImageMessage msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessLinkMessage (LinkMessage msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessLocationMessage (LocationMessage msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessTextMessage (TextMessage msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessVideoMessage (VideoMessage msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage ProcessVoiceMessage (VoiceMessage msg)
{
Return DefaultProcess (msg );
}
Protected virtual ReplyMessage DefaultProcess (PostMessage msg)
{
Var reply = new TextReply (msg );
If (msg. MsgType = PostMessageType. Event)
{
Reply. Content = string. Format ("{0} event is not processed.", (EventMessage) msg). Event );
}
Else
{
Reply. Content = string. Format ("{0} message is not processed.", msg. MsgType );
}
Return reply;
}
}