好的,情况如下:
我有一个客户端有2个设置:ConnectionState和ConnectionSollState,两者都是相同的可枚举(TypeConnectionState),它们存储客户端连接的实际状态和连接应该是的状态。在to的每个组合上,应该发生不同的事情,例如当ConnectionState为“已连接”但ConnectionSollState为“已关闭”时 - >拆解客户端。所以我有4种可能性需要检查。 现在每个客户端都可以处理无限数量的会话,并且每个会话都有一个状态(StreamState& StreamSollState),这些状态可以有6个可枚举的选项。
从现在开始,我正在制作20个开关条件,我的代码看起来非常混乱,我在编码时每5分钟做错一次。有没有更简单的方法来处理这样的情况? (if / else)会让事情变得更糟。
示例:
private void RTSPWorker() {
try {
byte[] buffer = new byte[2048];
while (!mb_RTSPWorkerAbbort) {
// Call TransportWD
Thread.Sleep(100 * mi_ConnectionTimeOut);
// Check ConnectionSollState
switch(ConnectionSollState) {
case TypeConnectionState.Connected:
// ConnectionSollState = Connected, check ConnectionState
switch(ConnectionState) {
case TypeConnectionState.Connected:
// ConnectionState is connected, keep-alive!
if(GET_PARAMETER() == null) {
DESCRIBE();
}
// Check streams too
foreach (cRTSPStream oStream in mo_StreamDict.Values) {
// Check StreamSollState
switch(oStream.RTSPStreamSollState) {
case cRTSPStream.TypeRTSPStreamState.Play:
// SollState is PLAY, check State
switch(oStream.RTSPStreamState) {
case cRTSPStream.TypeRTSPStreamState.Play:
//Stream is alive, keep-alive!
if (oStream.PLAY() == null) { oStream.DESCRIBE(); } break;
case cRTSPStream.TypeRTSPStreamState.Closed:
// Reinitialise.
if (oStream.SETUP() != null) { oStream.PLAY(); } break;
default:
// Default, send play.
oStream.PLAY(); break;
}
break;
case cRTSPStream.TypeRTSPStreamState.Pause:
// SollState is on pause, check State
switch(oStream.RTSPStreamState) {
case cRTSPStream.TypeRTSPStreamState.Closed:
// Reinitialise.
if (oStream.SETUP() != null) { oStream.PLAY(); } break;
default:
oStream.PAUSE();
break;
}
break;
case cRTSPStream.TypeRTSPStreamState.Closed:
// SollState is closed, check State
switch(oStream.RTSPStreamState) {
case cRTSPStream.TypeRTSPStreamState.Closed:
// Is closed, do nothing
break;
default:
// Default teardown, remove session
oStream.TEARDOWN();
this.RemoveRTSPSession(oStream);
break;
}
default:
// Default, what do?
break;
}
}
break;
case TypeConnectionState.Closed:
// ConnectionState should be connected, re-connect!
while(Connect() != true) {
// Sleep for 200ms, try again
Thread.Sleep(200);
}
break;
default:
// TODO anything else
break;
}
break;
case TypeConnectionState.Closed:
// Check ConnectionState
switch(ConnectionState) {
case TypeConnectionState.Connected:
// Is connected, should be closed. Close connection & clean up!
Close(null);
break;
default:
// Anything other than Connected, do nothing.
break;
}
break;
default:
break;
}
}
} catch {
}
}
答案 0 :(得分:7)
List<Tuple<T1,T2,T etc..>>
构造。例如:
var truthTable = List<Tuple<NavigationTab, Role, Action>>
{
new Tuple<NavigationTab, Role, Action>(NavigationTab.Users, Role.UsersAdministration, MVC.Administration.Users.Index()),
new Tuple<NavigationTab, Role, Action>(NavigationTab.Users, Role.RolesAdministration, MVC.Administration.Roles.Index()),
new Tuple<NavigationTab, Role, Action>(NavigationTab.Products, Role.ProductsAdministration, MVC.Administration.Products.Index()),
}
答案 1 :(得分:1)
更好的面向对象通常被认为是切换语句的最佳选择。例如,您可以使用多态而不是switch语句,并执行以下操作:
try {
byte[] buffer = new byte[2048];
while (!mb_RTSPWorkerAbbort) {
Thread.Sleep(100 * mi_ConnectionTimeOut);
worker.DoWork();
}
} catch (Exception ex) {
Trace.WriteLine(ex);
}
作为状态更改,您可以实例化以不同方式实现DoWork
的不同类型的工作类。一个可能是:
while(Connect() != true) {
// Sleep for 200ms, try again
Thread.Sleep(200);
}
当然,我不一定认为你应该这样做。我唯一要做的就是你发布的代码 - 所以,很可能很多更好的方式来实现不同的行为。
这与Specification Pattern非常相似。
答案 2 :(得分:0)
将代码分解为更小,更易于管理的部分。
如果在case语句中提取逻辑,则可以在没有开关的情况下重写主循环,例如:
while (!mb_RTSPWorkerAbbort)
{
// Call TransportWD
Thread.Sleep(100*mi_ConnectionTimeOut);
if (ConnectionSollState == TypeConnectionState.Closed)
{
CloseIfConnected();
}
if (ConnectionSollState == TypeConnectionState.Connected)
{
if (ConnectionState == TypeConnectionState.Connected)
{
KeepAlive();
ProcessStreams(); // <--bad example name - rename to what it's actually doing.
}
else
{
Reconnect();
}
}
}
当你从现在起一个月后看到这个(或者在你需要审查的情况下这样的情况下),看到发生的事情将会容易得多。