请查看我的以下代码......
public enum LogType
{
Debug,
Info,
Warn,
Error,
Fatal
}
private static readonly ILog log =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void LogError(LogType logtype, string message)
{
XmlConfigurator.Configure();
if (logtype == LogType.Debug)
log.Debug(message);
else if (logtype == LogType.Error)
log.Error(message);
}
我不喜欢以上所有的if-else语句,并且相信有更清晰的方式来编写它。我怎么能重构它? log类有不同的Debug,Error等方法。
我想单独调用一个方法让它自动处理它。
LogMyError(LogType.Debug, "I am just logging here");
我怎么能做这样的事情?我宁愿远离switch语句。我正在寻找一种干净的面向对象的方法。
答案 0 :(得分:16)
你的代码完全没问题;我不会改变它。
但是,如果您想要更加“面向对象”,那么考虑一下 如何这样做是有益的。我们只考虑你的两个案例;其他人可以很容易地看到它们将如何实施:
public abstract class LogType
{
public static readonly LogType Debug = new LogTypeDebug();
public static readonly LogType Error = new LogTypeError();
private LogType() {} // Prevent anyone else from making one.
public abstract void LogMessage(ILog logger, string message);
private sealed class LogTypeDebug: LogType
{
public override void LogMessage(ILog logger, string message)
{
logger.Debug(message);
}
}
private sealed class LogTypeError: LogType
{
public override void LogMessage(ILog logger, string message)
{
logger.Error(message);
}
}
}
...
//Obtain the log object the way you prefer.
private static readonly ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void LogError(LogType logtype, string message)
{
logtype.LogMessage(log, message);
}
通话网站根本没有变化!它仍然看起来像:
LogError(LogType.Debug, "my message");
你去了:根本没有if
或switch
陈述! “打开类型”代码已经移动到虚拟功能表中,这是它在面向对象代码中所属的位置。
这种技术的一个很好的副作用是你永远不必担心有人将整数转换为枚举类型的不受支持的值。 LogType类型的变量的仅可能值为null或对其中一个单例的引用。
答案 1 :(得分:11)
您可以使用Dictionary<LogType,Action<string>>
来保存要为每个枚举值执行的操作,然后只需调用该委托。
var logActions = new Dictionary<LogType,Action<string>>();
logActions.Add(LogType.Debug, log.Debug);
...
logActions[logtype](message);
更新
如果您的if
语句中只有少量分支,那么这就太过分了。我会将此方法用于5个以上的ifs。
答案 2 :(得分:5)
if/else
定义。
函数声明允许您以想要使用它的方式使用它。
所以我不会改变我看到的代码中的任何内容。
祝你好运。答案 3 :(得分:3)
使用switch block:
switch (logtype)
{
case LogType.Debug:
log.Debug(message);
break;
case LogType.Error:
log.Error(message);
break;
//more cases here as needed...
default:
throw new InvalidArgumentException("logtype");
}
答案 4 :(得分:0)
始终有switch
声明:
switch (logtype)
{
case LogType.Debug:
log.Debug(message);
break;
case LogType.Error:
log.Error(message);
break;
....
}
答案 5 :(得分:0)
您可以使用switch
或使用LogType
作为关键字创建字典,并使用相应的LogXXXX
方法作为值 - Action<string>
,然后执行< / p>
myDictionary[logType](message);