4

What I mean is, I read that a good way to write a method is by being guided with a rule: one method should do only one task. And if I have different sequential operations, then I need to split the method into several ones. It should make code cleaner and simple, self-explaining method names. But if I want to implement method which should do something and then return boolean value – true is success, false if failed. For example, assume we have setter called setObjectValue(). [again, it is just an example].

Question: Would it be good to use this name and return boolean values, or should it be something as: isSuccessfullsetObjectValue(), setObjectValueAndCheckIsOk(), or should there be two methods or what? Because name "setObjectValue()" doesn't tell you that the method is doing something besides setting value.

LaRRy
  • 626
  • 5
  • 20
  • I don't understand what you're asking. Seems to be a question about naming, or a question about how to split up your code into methods, or something about Hungarian notation... I'm not sure. – Daniel Kaplan Mar 11 '13 at 19:37
  • @LaRRy I guess setter is a wrong example. Do you need it for setter??? – amod Mar 11 '13 at 19:38
  • naming if it is good to return boolean indicator as extra-feature of method. Or more appropriate approach for returning indicator (well, Exceptions have being proposed). – LaRRy Mar 11 '13 at 19:41
  • Unless failure is fairly common, you should use exceptions. In other languages exceptions are pretty crude, but they're fairly well designed in Java and make it possible to build far more robust code than (sometimes) testing return codes. – Hot Licks Mar 11 '13 at 20:04
  • Honestly, I would stay away from Exceptions unless there is an actual Error. It really depends on what your code is doing though. For example, FileNotFound. If you cannot access the File it makes some sense that an exception could be thrown. However, there are many other examples where it makes no sense to throw an exception. – John Kane Mar 11 '13 at 20:10
  • Take a look at this for some of the debate over using exceptions heavily: http://www.ibm.com/developerworks/java/library/j-jtp05254/index.html – John Kane Mar 11 '13 at 20:31

7 Answers7

11

Unless there's a good reason, I would normally use Exceptions to indicate this. This has two benefits:

  1. You follow the convention of 1 method - 1 idea
  2. You force yourself (if the Exception is checked) to handle the failure case. If you return a boolean, then the code could easily ignore this case.

If you do something like this:

try{

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

Then you get the further benefit of it reading like English: "try to set the object value, but if you can't then handle it by ... "

James Kingsbery
  • 7,298
  • 2
  • 38
  • 67
  • 2
    there is a fair amount of debate on whether throwing exceptions like this is really good practice. Not sure it makes the most sense here either. – John Kane Mar 11 '13 at 19:39
  • Related: http://stackoverflow.com/questions/77127/when-to-throw-an-exception. If you buy the top answer here, then you throw an exception if a fundamental assumption is false. Since setters should not normally fail, this seems appropriate. – James Kingsbery Mar 11 '13 at 19:43
  • take a look in Collection, that returns a boolean if it was modified. false does not necessarily mean failure. It could be that nothing was modified as a result of the applications logic. I would only throw an exception if there was a specific error. – John Kane Mar 11 '13 at 19:48
  • @JohnKane -- There is a good deal of unjustified prejudice against using exceptions (mostly on the part of people who have never attempted to use them). The "debate" resembles debates on the floor of Congress -- static positions being tossed back and forth, with no one listening. And even if exceptions turn out to not be the ideal solution for the OP's situation, it would be very educational for him to give them a try. – Hot Licks Mar 11 '13 at 20:16
  • @James Kingsbery not sure I would really bring the "floor of Congress" into this. There are reasonable arguments on both sides... For example, if you are working with a file and you cannot access/read it it makes sense that a exception would be thrown (though probably not from the constructor...). Here there is a true error. However, there are also many examples of other cases when it makes little to no sense to do this. I would argue that it makes more sense to take the time to really think about what should be done case by case instead of defaulting to one technique over another. – John Kane Mar 11 '13 at 20:27
  • @Hot Licks, word "educational" is not what I search for, creating current topic. I want to find out "the good practise", "ideal solution for these cases", "panacea", not experimenting with Java's features like exceptions, if they are not appropriate and "turn out to not be the ideal solution for the OP's situation". I want to learn how to write clean and logical code, that's my aim. – LaRRy Mar 12 '13 at 07:43
  • @LaRRy - You can't learn how to program without "stretching" yourself to do things you don't quite understand. You can't learn without making mistakes. And programming is not a "cookbook" activity -- you must often delve back in your experience for techniques that wouldn't be obvious at first. I've many times gone back 10-20 years to reuse a technique in a completely new set of circumstances. (And exceptions (in the Java style) *do* help you write "clean and logical code" -- that's why they were invented.) – Hot Licks Mar 12 '13 at 10:45
  • @LaRRy -- By the way, you admit that you *are* experimenting already -- with the "one method/one task" paradigm. Presumably you are hoping to learn something from that exercise? (I hope you're not just using a cookbook approach because it's the popular thing to do.) – Hot Licks Mar 12 '13 at 10:56
1

It really depends on what your code is doing, but from what you described it makes perfect sense and is probably desirable behavior (again depending on what your code is doing).

For example, Collection returns a boolean value if it was changed as a result of the operation. Another example of this is AtomicBoolean. In these cases, since you may need to know if something was modified it makes sense to return a boolean. The naming of a method really doesnt matter as long as it makes sense.

In these examples, it is very relevant to know if whether your set was successful and this is the only place to realistically do this. However, I would not have a method used to set some value which also does a lot of other non-related manipulations.

Additionally, if the reason you would return false in your example is the result of some validation error, you most likely want to check that before attempting to set the value.

John Kane
  • 4,383
  • 1
  • 24
  • 42
1

In my opinion the answer of James is pretty good. But think about some more setters and the resulting try-catch-blocks. A slightly different approach is to handle your values for these setters through a validator, e.g. the user has made some input or something like this.

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

The method isValid(boolean valueToCheck) is indicating, that it will return a boolean value. Your setObjectValue(String newValue) just have to do the job without returning any value.

You can still check the newValue in your setter. If this is an invalid input, you would throw an IllegalArgumentException (fail-fast).

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

So in your code, you can use your setters for your own values. I mean, you wrote this method and should know your inputs, so this should be fine at all. If the user has made some inputs, use the validator for your setter. There will be strange inputs, believe me! ;-)

The result is, you don't have to handle this amount of try-catch blocks and know where to look if you got an exception (if you don't use the validator).

Martin Seeler
  • 6,874
  • 3
  • 33
  • 45
0

From my point of view, a setter should not return a value, unless you make a call to slow speed storage device (like a Web Service), but, throwing an exception on such cases will be cleaner.

Rafael
  • 2,827
  • 1
  • 16
  • 17
0

I think returning a boolean value without explicitly saying what the value represents in the method signature is okay provided you mention what the return value is to be used for in the JavaDoc. This is done throughout the Java Collections API (not that the Collections API is the gold standard), so it's generally an accepted practice in Java to do this.

CodeBlind
  • 4,519
  • 1
  • 24
  • 36
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;
   } 
}
curena
  • 26
  • 3
0

It is OK to create a method that checks some conditions and returns a boolean, and another method that might use condition checking before performing some operations.

boolean checkSomeCondition();

And your code will not suffer

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

But in cases when the method could not perform actions stated in its name, exceptions should be used. They were actually created for that.

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

It is generally used style, and probably the best way to handle errors that ocurred inside the body of the function.

Danylo Fitel
  • 606
  • 1
  • 6
  • 8