我有一个类来处理传入的无线消息并解析它们。根据命令的输出,我需要处理一些UI修改,例如突出显示标签,向文本框添加文本等。我使用的第一个选项是:
void IncomingMessageIfStatements(Message msg, Host host)
{
byte resp;
if (ParseMessageOptionOne(msg, out resp))
{
// Do some windows form stuff
}
else if (ParseMessageOptionTwo(msg, out resp))
{
// Do some windows form stuff
}
else if (ParseMessageOptionThree(msg, out resp))
{
// Do some windows form stuff
}
}
private bool ParseMessageOptionOne(Message msg, out byte resp)
{
throw new NotImplementedException();
}
private bool ParseMessageOptionTwo(Message msg, out byte resp)
{
throw new NotImplementedException();
}
private bool ParseMessageOptionThree(Message msg, out byte resp)
{
throw new NotImplementedException();
}
这样可行,但我会有更多else if
语句,它可能会变得丑陋。我看到的另一种方式是:
void IncomingMessageSwitchStatements(Message msg, Host host)
{
byte resp = 0;
byte someByte = 0;
bool output = false;
switch (someByte)
{
case 1:
output = ParseMessageOptionOne(msg, out resp);
break;
case 2:
output = ParseMessageOptionTwo(msg, out resp);
break;
case 3:
output = ParseMessageOptionThree(msg, out resp);
break;
default:
//handle exception here
break;
}
if (output && resp == 0x01)
{
UpdateUiFromHere();
}
}
private void UpdateUiFromHere()
{
// handle UI updates here
}
这看起来更干净,按预期工作。但后来我开始关注Dictionary<byte, Func<bool>>
,并认为这可能是解决传入多种情况(可能是20)的更好方法。
对于我应该采取的最佳做法的任何建议,鉴于什么需要?
答案 0 :(得分:3)
由于您要做的是根据索引编号&#34;使用相同的签名调用方法,您可以使用delegate
并将其列在Dictionary
中(或者如果索引从List
开始,则0
以明确您的意图。
public delegate bool ParseMessage(Message msg, out byte resp);
然后使用Dictionary
列出它:
Dictionary<byte, ParseMessage> parser = new Dictionary<byte, ParseMessage>(){
{1, new ParseMessage(ParseMessageOptionOne)},
{2, new ParseMessage(ParseMessageOptionTwo)},
{3, new ParseMessage(ParseMessageOptionThree)}
};
或使用List
List<ParseMessage> parser = new List<ParseMessage>(){
new ParseMessage(ParseMessageOptionOne),
new ParseMessage(ParseMessageOptionTwo),
new ParseMessage(ParseMessageOptionThree)
};
并称之为:
bool result = parser[resp](msg, out resp); //dictionary
bool result = parser[resp-1](msg, out resp); //list
答案 1 :(得分:0)
我会将解析移动到里面 Message类本身。
//in your factory
app.factory('dataFactory',function($http){
factory = {};
//get data
factory.getData = function(obj){
return $http({
method: 'GET',
url: 'http://jsonplaceholder.typicode.com/postsn'
})
};
return factory
});
//in your controller
app.controller(someCtrl,function($scope,dataFactory){
dataFactory.getData().then(function(data){
console.log('This will be your data: ', data)
})
})
我还会为所有选项制作一个枚举:
Options option = msg.GetOption();
然后编写代码以使用它,但是你需要......
public enum Options {
One,
Two,
None
}
很难推荐更多,因为我不知道if (option == Options.One)
// or
switch(option)
// etc.
做了什么,因为它不需要参考...但这应该是一些值得思考的好东西。
答案 2 :(得分:0)
您还可以更改ParseMessageOptionOne,ParseMessageOptionTwo,ParseMessageOptionThree的方法签名,以返回封装输出,响应的响应对象,并使用Func内置委托来存储方法:
public struct ParseResponse
{
public bool output;
public byte response;
}
class ParseOptions
{
Func<Message, ParseResponse>[] options = null;
public ParseOptions()
{
options = new Func<Message, ParseResponse>[]{
ParseMessageOptionOne,
ParseMessageOptionTwo,
ParseMessageOptionThree
};
}
public void IncomingMessageSwitchStatements(Message msg, Host host)
{
byte someByte = 2;
var response = options[someByte](msg);
if (response.output && response.response == 0x01)
{
//UpdateUiFromHere();
}
}
private ParseResponse ParseMessageOptionThree(Message msg)
{
return new ParseResponse { output = true };
}
}
答案 3 :(得分:0)
另一种方法是使用LINQ循环遍历委托方法列表,并在找到true
条件后立即短路。
private delegate bool ParseMessageWrapper(Message msg, out byte resp);
void IncomingMessageSwitchStatements(Message msg, Host host)
{
byte resp = 0;
bool output = false;
var parseMethods = new List<ParseMessageWrapper>()
{
new ParseMessageWrapper(ParseMessageOptionOne),
new ParseMessageWrapper(ParseMessageOptionTwo),
new ParseMessageWrapper(ParseMessageOptionThree)
};
output = parseMethods.Any(func => func.Invoke(msg, out resp));
if (output && resp == 0x01)
{
UpdateUiFromHere();
}
}