4

我的意思是,我读到编写方法的一种好方法是遵循一条规则:一种方法应该只完成一项任务。如果我有不同的顺序操作,那么我需要将方法分成几个。它应该使代码更简洁、易于解释的方法名称。但是,如果我想实现应该做某事然后返回布尔值的方法——true 表示成功,false 表示失败。例如,假设我们有一个名为 setObjectValue() 的 setter。[再次,这只是一个例子]。

问题:使用此名称并返回布尔值会更好,还是应该是:isSuccessfullsetObjectValue()、setObjectValueAndCheckIsOk(),还是应该有两种方法或什么?因为名称“setObjectValue()”并没有告诉您该方法除了设置值之外还在做其他事情。

4

7 回答 7

11

除非有充分的理由,否则我通常会使用 Exceptions 来表明这一点。这有两个好处:

  1. 您遵循 1 方法 - 1 想法的约定
  2. 你强迫自己(如果检查了异常)来处理失败的情况。如果你返回一个布尔值,那么代码很容易忽略这种情况。

如果你做这样的事情:

try{

  setObjectValue("foo")
} catch(SomeKindOfException e){
  //handle
} 

然后你会得到它的进一步好处,读起来像英语:“尝试设置对象值,但如果你不能处理它......”

于 2013-03-11T19:37:55.157 回答
1

在我看来,詹姆斯的回答非常好。但是想想更多的 setter 和由此产生的 try-catch-blocks。一种稍微不同的方法是通过验证器为这些设置器处理您的值,例如,用户进行了一些输入或类似的事情。

String userInput = ...;
if (myValidator.isValid(userInput)) {
   myObject.setObjectValue(userInput);
}

该方法isValid(boolean valueToCheck)表明它将返回一个布尔值。您setObjectValue(String newValue)只需完成工作而不返回任何价值。

您仍然可以在您的 setter 中检查 newValue。如果这是一个无效的输入,你会抛出一个IllegalArgumentException(快速失败)。

if (newValue==null || newValue.contains("foo")) {
  throw new IllegalArgumentException("Illegal value for newValue: "+newValue);
}
this.value = newValue;

因此,在您的代码中,您可以将您的设置器用于您自己的值。我的意思是,你写了这个方法并且应该知道你的输入,所以这应该没问题。如果用户进行了一些输入,请为您的设置器使用验证器。会有奇怪的输入,相信我!;-)

结果是,您不必处理这么多的 try-catch 块,也不必知道如果遇到异常(如果您不使用验证器)该去哪里寻找。

于 2013-03-11T19:50:38.423 回答
1

这实际上取决于您的代码在做什么,但是根据您的描述,它非常有意义并且可能是理想的行为(再次取决于您的代码在做什么)。

例如,如果Collection因操作而改变,则返回一个布尔值。另一个例子是AtomicBoolean。在这些情况下,由于您可能需要知道是否修改了某些内容,因此返回布尔值是有意义的。只要有意义,方法的命名实际上并不重要。

在这些示例中,了解您的系列是否成功非常重要,这是唯一可以实际执行此操作的地方。但是,我不会有用于设置一些值的方法,该方法也会执行许多其他不相关的操作。

此外,如果您在示例中返回 false 的原因是某些验证错误的结果,那么您很可能希望在尝试设置值之前进行检查。

于 2013-03-11T19:46:18.713 回答
0

可以创建一个检查某些条件并返回布尔值的方法,以及另一个可能在执行某些操作之前使用条件检查的方法。

boolean checkSomeCondition();

而且您的代码不会受到影响

if (checkSomeCondition()) {...}
else {...}

但如果方法无法执行其名称中所述的操作,则应使用异常。它们实际上是为此而创建的。

try {
   DoSmth();
} catch (ParticularError e) {
   ...
}

它通常是使用的样式,并且可能是处理函数体内发生的错误的最佳方式。

于 2013-03-11T20:31:33.420 回答
0

Setters generally should be void (not return a value). There are several ways to accomplish your goal without making your setter return a boolean. One way would be to set a boolean flag as an instance variable that gets set to true whenever you set a particular value. This flag could be accessed via a getter of its own.

For example, you've got a class Person with Name and Phone Number attributes. You want to be able to set a person's phone number and later determine whether or not this phone number has been set:

public class Person 
{
   private String name;
   private String phone;
   private boolean hasPhone;

   public void setName(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return name;
   }

   public void setPhone(String phone)
   {
      this.phone = phone;
      hasPhone = true;
   }

   public String getPhone()
   {
      return phone;
   }

   public boolean hasPhone()
   {
      return hasPhone;
   } 
}
于 2013-03-11T20:05:52.203 回答
0

从我的角度来看,setter 不应该返回值,除非您调用慢速存储设备(如 Web 服务),但是在这种情况下抛出异常会更干净。

于 2013-03-11T19:39:50.713 回答
0

我认为返回一个布尔值而不明确说明方法签名中的值代表什么是可以的,只要您提到返回值在 JavaDoc 中的用途。这是在整个 Java Collections API 中完成的(并不是 Collections API 是黄金标准),因此在 Java 中这样做通常是一种公认​​的做法。

于 2013-03-11T19:39:53.903 回答