0

如果我有一个方法可以做某事并另外记录信息,如果我不想记录或使用标志,我应该创建一个新方法吗?

public void MethodA(string myMessage, bool logIt)
{
  if(logIt)
  {
    //do stuff with logging
  }
  {
    //don't need to log
  }
}

……对……

public void MethodA(string myMessage)
{
  //do stuff with logging
}

public void MethodANoLogging(string myMessage)
{
  //don't need to log
}

我的场景很简单,我主要对 flag 参数感兴趣,它可能是一个枚举,在同一方法中创建了许多 if...else if...else if 场景。与仅创建具有不同名称的新方法相比。我赞成第二种解决方案(新方法),因为它允许方法承担一个责任。从根本上说,这是一个更简单的解决方案。

使用标志版本的原因是什么?

4

4 回答 4

3

两者都不。您的日志记录配置应该完全独立于您的业务方法。这就是AOP的用途。

于 2009-08-26T00:11:21.280 回答
2

您应该(几乎)永远不要使用布尔标志重载方法。有多种原因:

  1. 为了避免混淆,方法应该只做一件事和一件事。布尔标志清楚地表明一个方法做不止一件事(来自Robert C. Martin)。

  2. 阅读这种方法的代码会让人不清楚到底发生了什么。如果我不熟悉代码,我会看到:

    MethodA("这是一条消息", false);

    如果不看代码,不完全清楚 false 是什么意思。这违背了方法的意图应该从其名称中清楚的原则。

  3. 当以后可能需要添加多个选项时,它有时是对二元选项的不必要绑定。例如:假设您有一个方法:

    public UpdateCustomer(String name, boolean isPremiumCustomer);

如果您稍后决定添加不同类别的客户,那么您将不得不重构调用此方法的每一行代码。在您的情况下,一个更好的示例是,如果您想要一种方法,以便仅在打开调试标志时才登录。

替代方法大致如下:

  1. 创建一个具有不同名称的函数。这是您采用的方法,可能也是我更喜欢的方法。在大多数情况下,就像您的示例一样,拥有一个:doSomething 和一个 doSomethingADifferentWay 就足够了。但是,如果您需要第二种带有标志的方法,那么您应该考虑选项 2:

  2. 创建一个描述选项的枚举。在您的情况下,这将类似于: enum EnableLogging { ENABLE_LOGGING, DISABLE_LOGGING } 然后您将代码编写为:

    MethodA("一条消息", DISABLE_LOGGING);

这至少是明确的。(注意:这个解决方案来自 Joshua Bloch 在Effective Java 2nd Edition中的第 40 条,但同样适用于其他语言)。

于 2009-10-21T01:49:43.270 回答
1

通常,为了避免过度思考,我会做一个超载,默认为“假”

public void MethodA(string myMessage)
{
    MethodA(myMessage, false);
}

public void MethodA(string myMessage, bool logIt)
{
  if(logIt)
  {
    //do stuff with logging
  }
  {
    //don't need to log
  }
}

这是我个人的喜好,我相信其他人会不同意。但是,它并不涵盖所有情况。

于 2009-08-26T00:10:35.353 回答
0

这类事情已经(并且将会)无休止地辩论,但著名的答案是“视情况而定”。

对于诸如是否记录(这意味着在应用程序中不应该有任何副作用)之类的事情,我绝对不会创建一个新方法。您将不得不复制您的逻辑,这意味着将来在两个地方维护它,没有真正的原因。做类似的事情更有意义......

if(logIt) // log information

// do something

if(logIt) // log other info

// do more

....etc

无论您是否要登录,您的核心逻辑都是相同的,并且只在一个地方。

于 2009-08-26T00:00:15.420 回答