So while rewriting some code, I came across something along the lines of:
Method 1
while ( iter.hasNext() ) {
Object obj = iter.next();
if ( obj instanceof Something ) {
returnValue = (Something) obj;
break;
}
}
I re-wrote it as the following without much thought (the actual purpose of the re-write was for other logic in this method):
Method 2
while ( (iter.hasNext()) && (returnValue == null) ) {
Object obj = iter.next();
if ( obj instanceof Something ) {
returnValue = (Something) obj;
}
}
I personally don't have any strong preference for either and really don't see anything wrong with either approach. Can anyone else think of benefits or consequences of using either approach? The variable, returnValue is returned. How would people feel if that was the last block in the method, and it is just returned?
EDIT: So here's what I'm doing: Currently this method takes a set of authorizations and validates them - returning a boolean. This method allows grouping so you can specify that at least one or all (meaning if at least one authorization is valid, pass the whole set). However, this method does not support levels of authorization which is what I'm changing it to do so that each level can specify different grouping. All this bit is just background information...does not have that much to do with the above code - an alternative method is used to perform the above block of code.
Clearer, for me, would be to extract this as a method of its own; then you can simply return the value rather than assigning it to a local.
while (iter.hasNext()) {
Object obj = iter.next();
if (obj instanceof Something)
return (Something)obj;
}
return null;
Better yet would be a foreach loop
for (Object o : yourList)
if (o instanceof Something)
return (Something)o
return null;
I like the first as it is more clear why you are breaking out of the loop. It says "if this condition is true, set the value and break the loop, we're done". The other took me another second or so, but as you said, there is no huge difference.
I prefer the explicit jump (whether it's a break or a return). It's difficult for me to articulate why, but I can compare it to writing in active vs. passive voice. Sure, it's merely style, but active is a lot more straightforward to read.
One school of thought is that a method should only have one return statement/point at the end of the method.
I tend to use whatever is clearer in the specific circumstances.
As an aside:
1) Should you be rewriting code that works (assuming it does)?
2) Should you be rewriting code that doesn't have tests (assuming it does not)?
Those are equivalent in this case but that is no longer the case if you want to do something after the if condition, which is often the case.
Performance is a wash and even if it wasn't, it's an irrelevant micro-optimization. The key goal should be readability and maintainability.
Method 1 is much clearer in what it is doing, it breaks the loop when obj instanceof Something==true, although method 2 is also pretty obvious.
Another slight advantage of Method 1 is that it is slightly faster since method 2 does one more condition check every loop, and it does one more check than method 1. What if the check
took more than 1 minute?
So obviously Method 1 is better and easier to understand.
Clearly the first form is much better because it is less complex. If you are not doing anything with returnValue you could simply return it as soon as you have found a match.
I don't agree that the first form is clearly better... The problem with returns, breaks and continues is that they make the code harder to refactor. The example given here is too simple to require such manipulation but in general it is all too easy to refactor a complex piece of code into its own method and neglect to ensure the caller's return paths remain valid. This is where automated testing can help, but I still prefer most of my checking to come out of the compiler.
I took the approach of asking what the loop is doing - Two things, it checks for the existence of an Object of type Fish, and it makes that Object available outside the loop. If we separate the two responsibilities we get:
Object obj = null;
while (iter.hasNext() && !(obj instanceof Fish)) {
obj = iter.next();
}
if (obj instanceof Fish) {
returnValue = (Fish) obj;
}
I still don't like it... perhaps its the instanceof or the use of Object or even just the nature of Iterator but it doesn't seem like nice code.
After your edit, it seems that you will have iterate through the whole list to check for all kinds of authorities. The code would be like:
Object returnValue=null; //Notice in your original code
while(iter.hasNext()){
Object kind=iter.next()
switch(kind.getType()){
case "fish":
case "reptile":
if(returnValue!=bird|returnValue!=mammal)
returnValue=(coldblood) kind;
break;
case "bird":
case "mammal":
returnValue=(coldblood) kind;
break;
case default:
//Fall-through
}
}
return returnValue;
So this is what I have to say:
You said you needed to implement multiple levels of permissions, I believe that you will have to iterate through the whole collection.
That having said, I recommend using Method 1 - that is if you have to break. The break keyword is more clear, and it is slightly faster. (One less jump however slight)
Related
down bellow you can see two example methods, which are structured in the same way, but have to work with completely different integers.
You can guess if the code gets longer, it is pretty anoying to have a second long method which is doing the same.
Do you have any idea, how i can combine those two methods without using "if" or "switch" statements at every spot?
Thanks for your help
public List<> firstTestMethod(){
if(blabla != null){
if(blabla.getChildren().size() > 1){
return blabla.getChildren().subList(2, blabla.getChildren().size());
}
}
return null;
}
And:
public List<> secondTestMethod(){
if(blabla != null){
if(blabla.getChildren().size() > 4){
return blabla.getChildren().subList(0, 2);
}
}
return null;
}
Attempting to isolate common ground from 2 or more places into its own Helper method is not a good idea if you're just looking at what the code does without any context.
The right approach is first to define what you're actually isolating. It's not so much about the how (the fact that these methods look vaguely similar suggests that the how is the same, yes), but the why. What do these methods attempt to accomplish?
Usually, the why is also mostly the same. Rarely, the why is completely different, and the fact that the methods look similar is a pure coincidence.
Here's a key takeaway: If the why is completely different but the methods look somewhat similar, you do not want to turn them into a single method. DRY is a rule of thumb, not a commandment!
Thus, your question isn't directly answerable, because the 2 snippets are so abstractly named (blabla isn't all that informative), it's not possible to determine with the little context the question provides what the why might be.
Thus, answer the why question first, and usually the strategy on making a single method that can cater to both snippets here becomes trivial.
Here is an example answer: If list is 'valid', return the first, or last, X elements inside it. Validity is defined as follows: The list is not null, and contains at least Z entries. Otherwise, return null.
That's still pretty vague, and dangerously close to a 'how', but it sounds like it might describe what you have here.
An even better answer would be: blabla represents a family; determine the subset of children who are eligible for inheriting the property.
The reason you want this is twofold:
It makes it much easier to describe a method. A method that seems to do a few completely unrelated things and is incapable of describing the rhyme or reason of any of it cannot be understood without reading the whole thing through, which takes a long time and is error-prone. A large part of why you want methods in the first place is to let the programmer (the human) abstract ideas away. Instead of remembering what these 45 lines do, all you need to remember is 'fetch the eligible kids'.
Code changes over time. Bugs are found and need fixing. External influences change around you (APIs change, libraries change, standards change). Feature requests are a thing. Without the why part it is likely that one of the callers of this method grows needs that this method cannot provide, and then the 'easiest' (but not best!) solution is to just add the functionality to this method. The method will eventually grow into a 20 page monstrosity doing completely unrelated things, and having 50 parameters. To guard against this growth, define what the purpose of this method is in a way that is unlikely to spiral into 'read this book to understand what all this method is supposed to do'.
Thus, your question is not really answerable, as the 2 snippets do not make it obvious what the common thread might be, here.
Why do these methods abuse null? You seem to think null means empty list. It does not. Empty list means empty list. Shouldn't this be returning e.g. List.of instead of null? Once you fix that up, this method appears to simply be: "Give me a sublist consisting of everything except the first two elements. If the list is smaller than that or null, return an empty list", which is starting to move away from the 'how' and slowly towards a 'what' and 'why'. There are only 2 parameters to this generalized concept: The list, and the # of items from the start that need to be omitted.
The second snippet, on the other hand, makes no sense. Why return the first 3 elements, but only if the list has 5 or more items in it? What's the link between 3 and 5? If the answer is: "Nothing, it's a parameter", then this conundrum has far more parameters than the first snippet, and we see that whilst the code looks perhaps similar, once you start describing the why/what instead of the how, these two jobs aren't similar at all, and trying to shoehorn these 2 unrelated jobs into a single method is just going to lead to bad code now, and worse code later on as changes occur.
Let's say instead that this last snippet is trying to return all elements except the X elements at the end, returning an empty list if there are fewer than X. This matches much better with the first snippet (which does the same thing, except replace 'at the end' with 'at the start'). Then you could write:
// document somewhere that `blabla.getChildren()` is guaranteed to be sorted by age.
/** Returns the {#code numEldest} children. */
public List<Child> getEldest(int numEldest) {
if (numEldest < 0) throw new IllegalArgumentException();
return getChildren(numEldest, true);
}
/** Returns all children except the {#code numEldest} ones. */
public List<Child> getAllButEldest(int numEldest) {
if (numEldest < 0) throw new IllegalArgumentException();
return getChildren(numEldest, false);
}
private List<Child> getChildren(int numEldest, boolean include) {
if (blabla == null) return List.of();
List<Child> children = blabla.getChildren();
if (numEldest >= children.size()) return include ? children : List.of();
int startIdx = include ? 0 : numEldest;
int endIdx = include ? numEldest : children.size();
return children.subList(startIdx, endIdx);
}
Note a few stylistic tricks here:
boolean parameters are bad, because why would you know 'true' matches up with 'I want the eldest' and 'false' matches up with 'I want the youngest'? Names are good. This snippet has 2 methods that make very clear what they do, by using names.
That 'when extracting common ground, define the why, not the how' is a hierarchical idea - apply it all the way down, and as you get further away from the thousand-mile view, the what and how become more and more technical. That's okay. The more down to the details you get, the more private things should be.
By having defined what this all actually means, note that the behaviour is subtly different: If you ask for the 5 eldest children and there are only 4 children, this returns those 4 children instead of null. That shows off some of the power of defining the 'why': Now it's a consistent idea. Returning all 4 when you ask for 'give me the 5 eldest', is no doubt 90%+ of all those who get near this code would assume happens.
Preconditions, such as what comprises sane inputs, should always be checked. Here, we check if the numEldest param is negative and just crash out, as that makes no sense. Checks should be as early as they can reasonably be made: That way the stack traces are more useful.
You can pass objects that encapsulate the desired behavior differences at various points in your method. Often you can use a predefined interface for behavior encapsulation (Runnable, Callable, Predicate, etc.) or you may need to define your own.
public List<> testMethod(Predicate<BlaBlaType> test,
Function<BlaBlaType, List<>> extractor)
{
if(blabla != null){
if(test.test(blabla)){
return extractor.apply(blabla);
}
}
return null;
}
You could then call it with a couple of lambdas:
testMethod(
blabla -> blabla.getChildren().size() > 1,
blabla -> blabla.getChildren().subList(2, blabla.getChildren().size())
);
testMethod(
blabla -> blabla.getChildren().size() > 4,
blabla -> blabla.getChildren().subList(0, 2)
);
Here is one approach. Pass a named boolean to indicate which version you want. This also allows the list of children to be retrieved independent of the return. For lack of more meaningful names I choose START and END to indicate which parts of the list to return.
static boolean START = true;
static boolean END = false;
public List<Children> TestMethod(boolean type) {
if (blabla != null) {
List<Children> list = blabla.getChildren();
int size = list.size();
return START ?
(size > 1 ? list.subList(0, 2) : null) :
(size > 4 ? list.subList(2, size) :
null);
}
return null;
}
(Please no advise that I should abstract X more and add another method to it.)
In C++, when I have a variable x of type X* and I want to do something specific if it is also of type Y* (Y being a subclass of X), I am writing this:
if(Y* y = dynamic_cast<Y*>(x)) {
// now do sth with y
}
The same thing seems not possible in Java (or is it?).
I have read this Java code instead:
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
Sometimes, when you don't have a variable x but it is a more complex expression instead, just because of this issue, you need a dummy variable in Java:
X x = something();
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
// x not needed here anymore
(Common thing is that something() is iterator.next(). And there you see that you also cannot really call that just twice. You really need the dummy variable.)
You don't really need x at all here -- you just have it because you cannot do the instanceof check at once with the cast. Compare that again to the quite common C++ code:
if(Y* y = dynamic_cast<Y*>( something() )) {
// ...
}
Because of this, I have introduced a castOrNull function which makes it possible to avoid the dummy variable x. I can write this now:
Y y = castOrNull( something(), Y.class );
if(y != null) {
// ...
}
Implementation of castOrNull:
public static <T> T castOrNull(Object obj, Class<T> clazz) {
try {
return clazz.cast(obj);
} catch (ClassCastException exc) {
return null;
}
}
Now, I was told that using this castOrNull function in that way is an evil thing do to. Why is that? (Or to put the question more general: Would you agree and also think this is evil? If yes, why so? Or do you think this is a valid (maybe rare) use case?)
As said, I don't want a discussion whether the usage of such downcast is a good idea at all. But let me clarify shortly why I sometimes use it:
Sometimes I get into the case where I have to choose between adding another new method for a very specific thing (which will only apply for one single subclass in one specific case) or using such instanceof check. Basically, I have the choice between adding a function doSomethingVeryVerySpecificIfIAmY() or doing the instanceof check. And in such cases, I feel that the latter is more clean.
Sometimes I have a collection of some interface / base class and for all entries of type Y, I want to do something and then remove them from the collection. (E.g. I had the case where I had a tree structure and I wanted to delete all childs which are empty leafs.)
Starting Java 14 you should be able to do instanceof and cast at the same time. See https://openjdk.java.net/jeps/305.
Code example:
if (obj instanceof String s) {
// can use s here
} else {
// can't use s here
}
The variable s in the above example is defined if instanceof evaluates to true. The scope of the variable depends on the context. See the link above for more examples.
Now, I was told that using this castOrNull function in that way is an evil thing do to. Why is that?
I can think of a couple of reasons:
It is an obscure and tricky way of doing something very simple. Obscure and tricky code is hard to read, hard to maintain, a potential source of errors (when someone doesn't understand it) and therefore evil.
The obscure and tricky way that the castOrNull method works most likely cannot be optimized by the JIT compiler. You'll end up with at least 3 extra method calls, plus lots of extra code to do the type check and cast reflectively. Unnecessary use of reflection is evil.
(By contrast, the simple way (with instanceof followed by a class cast) uses specific bytecodes for instanceof and class casting. The bytecode sequences can almost certainly will be optimized so that there is no more than one null check and no more that one test of the object's type in the native code. This is a common pattern that should be easy for the JIT compiler to detect and optimize.)
Of course, "evil" is just another way of saying that you REALLY shouldn't do this.
Neither of your two added examples, make use of a castOrNull method either necessary or desirable. IMO, the "simple way" is better from both the readability and performance perspectives.
In most well written/designed Java code the use of instanceof and casts never happens. With the addition of generics many cases of casts (and thus instanceof) are not needed. They do, on occasion still occur.
The castOrNull method is evil in that you are making Java code look "unnatural". The biggest problem when changing from one language to another is adopting the conventions of the new language. Temporary variables are just fine in Java. In fact all your method is doing is really hiding the temporary variable.
If you are finding that you are writing a lot of casts you should examine your code and see why and look for ways to remove them. For example, in the case that you mention adding a "getNumberOfChildren" method would allow you to check if a node is empty and thus able to prune it without casting (that is a guess, it might not work for you in this case).
Generally speaking casts are "evil" in Java because they are usually not needed. Your method is more "evil" because it is not written in the way most people would expect Java to be written.
That being said, if you want to do it, go for it. It isn't actually "evil" just not "right" way to do it in Java.
IMHO your castOrNull is not evil, just pointless. You seem to be obsessed with getting rid of a temporary variable and one line of code, while to me the bigger question is why you need so many downcasts in your code? In OO this is almost always a symptom of suboptimal design. And I would prefer solving the root cause instead of treating the symptom.
I don't know exactly why the person said that it was evil. However one possibility for their reasoning was the fact that you were catching an exception afterwards rather than checking before you casted. This is a way to do that.
public static <T> T castOrNull(Object obj, Class<T> clazz) {
if ( clazz.isAssignableFrom(obj.getClass()) ) {
return clazz.cast(obj);
} else {
return null;
}
}
Java Exceptions are slow. If you're trying to optimize your performance by avoiding a double cast, you're shooting yourself in the foot by using exceptions in lieu of logic. Never rely on catching an exception for something you could reasonably check for and correct for (exactly what you're doing).
How slow are Java exceptions?
I have a statement as follows
getLD().get(cam.getName()).getAGS().get(aG.getName())
getLD(), getAGS() return Java collections
I would not consider it to be an error if getAGS() were empty, nor if the result of getAGS().get(aG.getName()) were empty. However it is rather messy and somewhat of a pain checking for these null conditions.
e.g. if(getLD().get(camp.getName()).getAGS() !=null && getLD().get(cam.getName()).getAGS().get(aG.getName()) != null) {
Can anyone suggest the best way to deal with this? Obviously I could create a variable x = getLD().get(camp.getName()).getAGS() to shorten the code, but is there a way in which I would not have to do the two checks for null?
All help is much appreciated!
IMO, the best strategy is to design your data structures so that there aren't any nulls in the first place. For example, use empty collections or zero length arrays, or "" instead of null. For application classes, consider implementing special instance that you can use instead of null.
A second strategy is to replace use of exposed generic data structures (e.g. maps, lists, arrays) with custom classes. This hides the implementation details inside a class, and allows you to make use of Java's static typing to avoid many of the situations where a null check would be required.
A third strategy is to create a helper class with a bunch of methods that implement common operations; e.g. "get the Cam for an LD". (IMO, this approach is a poor alternative, compared with the others, but at least it reduces the amount of code repetition.)
To the extent that you cannot get rid of the nulls, you've got no option but to explicitly test for them. (There was a proposal to add an "elvis" operator to Java 7 as part of project Coin, but unfortunately it was cut.)
The best way would be to avoid the chain. If you aren't familiar with the Law of Demeter (LoD), in my opinion you should. You've given a perfect example of a message chain that is overly intimate with classes that it has no business knowing anything about.
Law of Demeter: http://en.wikipedia.org/wiki/Law_of_Demeter
The apache commons project has a library called Bean Introspection Utilities (BeanUtils), which looks like it can do what you need. Check out the nested property access section, in the user guide, and look at the BeanUtils class:
http://commons.apache.org/beanutils/
It has utility classes that I think can do what you need.
Another thing to consider: you should try to avoid doing this many levels of nested property access. This is a code smell called "feature envy", where an object wants to use features of another object regularly. Consider creating methods on the top-level object, or find a way to redesign so that the feature you need is shared more readily.
try {
foo().bar().baz();
} catch (NullPointerException e) {
// Check if it was actually an error
}
Code in groovy!.
Not always possible depending on your environment and performance requirments. But its a joy to just type
if (getLD(camp?.GetName())?.getAGS(ag?.GetName()))
Alternativly you could just code what you mean and catch the null pointer exception. In your case this would be much more readable especially of you dont care which element is null.
I think Something is more complext than needed if you require to do
getLD().get(cam.getName()).getAGS().get(aG.getName())
If you need to check if the second collection or the result is null you can do something like:
Map<?,?> firstList= getLD();
Object value = null;
if (firstList!=null && !firstList.isEmpty() && fistList.containsKey(cam.getName())){
Map<?,?> secondList = firstList.get(cam.getName());
if (secondList!=null && !secondList.isEmpty() && secondList.containsKey(aG.getName())){
value = secondList.get(aG.getName());
}
}
if(value != null){
// Do the required operations if the value is not null
}else{
// Do the required operations if the value is null
}
With this code i checked if the first collection is not null, is not empty and if it has the content. The i get the second collection and i repeated the process in the second collection.
Also a method can be created to do this operation:
private Map<?,?> getItem(Map<?,?> map,Object key){
if (map!=null && !map.isEmpty() && map.containsKey(key)){
return map.get(key);
}
return null;
}
and in your code:
Object value = getItem(getItem(getLD(),cam.getName()),aG.getName());
if(value != null){
// Do the required operations if the value is not null
}else{
// Do the required operations if the value is null
}
I asked this goofy question earlier today and got good answers. I think what I really meant to ask is the following:
String aString = ""; // Or = null ?
if(someCondition)
aString = "something";
return aString;
In this case, the string has to be initialized in order to return it. I always thought that either option (setting it to "" or to null looks kind of ugly. I was just wondering what others do here...or is it more of just a matter of whether you want empty string or null being passed around in your program (and if you are prepared to handle either)?
Also assume that the intermediary logic is too long to cleanly use the conditional (? :) operator.
return (someCondition) ? "something" : "";
or
return (someCondition) ? "something" : null;
Typically though if your function says it will return a String I prefer to actually return a String instead of a null. Either way the calling function should probably check for both cases.
depends on what you want to achieve,
in general i would return null to signal that nothing was processed,
it might later pop up cases where someCondition is true but the string you build together is "" anyway, that way you can differentiate from that case if you return null if nothing was processed.
i.e.
String aString = null;
if(someCondition)
aString = "something";
return aString;
but it all really depends on what you want to achieve...
e.g. if the code is suppose to build together a string that is delivered directly in the UI you would go for "" instead
In this case it might be best to do something like:
public void func() {
boolean condition = getConditionFromSomewhere();
String condString = getAppropriateValue(condition);
}
public String getAppropriateValue(boolean condition) {
if (condition) {
return "something";
} else {
return "somethingElse";
}
}
It may seem a bit overkill for a boolean condition, but if you get into more complex conditions (more choices, like enums and the like), it would nicely abstract that logic away. And with a descriptive method name make it almost self-documenting to boot.
Since you're asking our opinions...
I'm a bit overconscious about quality. I prefer that all my "if" statements have an "else", because (1) it helps to understand the code if there are multiple nested "if's", (2) force me to consider the possibility (what should happen if the condition is false?).
Regarding reason (1), I prefer to avoid nested if's, but sometimes you inherit code with a lot of if's.
if(someCondition)
aString = "something";
else
aString = "";
I would prefer "null", because it would make the app fail and dump a stack that I can follow. An empty string, in contrast, would keep things going. Naturally, it depends on the logic of your code what is better: null or "".
Yes, this is just a matter of whether you want a null or an empty string being passed around in your program. If you plan to append things to it later, and the someCondition just indicates that you should give it a first value to begin with, then use the empty string. If you plan to have it indicate that there is a string or there is nothing, then perhaps using null is better.
Its just your preference of what your api should do. If you are returning null, there may be a chance that the api users can get NPE if they are not checking for null. But if you are using "" string, the error may pass silently if it is not supposed to be null. It is a preference of how you write your api and depends on the use case.
Thinking about it, I rarely use "" in code for any purpose.
This question already has answers here:
Closed 13 years ago.
Duplicate: Should a function have only one return statement?
Often times you might have a method that checks numerous conditions and returns a status (lets say boolean for now). Is it better to define a flag, set it during the method, and return it at the end :
boolean validate(DomainObject o) {
boolean valid = false;
if (o.property == x) {
valid = true;
} else if (o.property2 == y) {
valid = true;
} ...
return valid;
}
or is it better/more correct to simply return once you know the method's outcome?
boolean validate(DomainObject o) {
if (o.property == x) {
return true;
} else if (o.property2 == y) {
return true;
} ...
return false;
}
Now obviously there could be try/catch blocks and all other kinds of conditions, but I think the concept is clear. Opinions?
If it's a method you'll be calling thousands of times, then early return is better to achieve a [slightly] increased performance.
If not, then I'd prefer late return, since it improves readability.
Remember programmers usually spend more time reading than writing code, so anything you can do to improve readability will be certainly welcome.
I prefer returning early and avoiding deep nesting. This is particularly true right at the start of the method: test anything that's simple, and get out (or throw an exception) if you can do so really early.
If it's right in the middle of a method, it's more of a judgement call.
Note that I'd refactor your example straight away to use a single if:
boolean validate(DomainObject o) {
if (o.property == x || o.property2 == y) {
return true;
} ...
return false;
}
I realise this was only a toy example, but my point is that it's always worth looking for more ways to simplify your code :)
As with most coding styles, it's really a matter of preference, but guard clauses are considered by many to be a best practice.
The only time I would say you definitely shouldn't return early is if you can't easily see every return within a single screen (whatever the standard might be for people working on the same code base), you should at the very least be adding comments indicating that the function can return early if there is an early return.
The only time I would say you definitely should return early is if your code looks like...
boolean valid = true;
if( condition1 ) {
valid = false;
}
if( valid ) {
...
if( condition2 ) {
valid = false;
}
}
if( valid ) {
...
if( condition3 ) {
valid = false;
}
}
... (etc)
If you find yourself in either of these situations, however... you should probably be refactoring the function.
There are two factors pulling against each other.
The first factor is ease of debugging. If you return immediately (as shown in your second code snippet), it sometimes becomes difficult to debug a big function since it is hard to find these return statements, specially if they were put there by mistake.
The second factor is ease of implementation. If you are checking basic correctness of arguments at the beginning of the function and there is a long piece of code before the function finishes, you might have to put that entire code in a condition loop. If you don't, at some point the argument might get used for some long calculation, wasting time, because it would ultimately be rejected anyways.
So, the answer could be like this:
If the function is small,
save the return status in a variable and return at the end.
else
return immediately.
To me, this is sort of one of those religious war topics with no correct answer. The argument against returning early essentially boils down to the fact that having one and only one point where a function can exit reduces the number of possible paths through your code, thus, in theory at least, reducing the chances for bugs. My personal style is to, in situations where it makes sense to return early do so, and in situations where it makes sense to limit to one return statement I do that.
If exceptions aren't part of the picture, I prefer returning immediately when I can.
It can be easy to mismanage the flag variable and I'm against flag variables in general. Not returning also might make a maintainer think that further work might be done (if the method is long).
Personally, I like the second method better. It is straightforward and clearer to me, but I do know there are people who must have only one return in a function.
Honestly I think it depends on the situation. Personally I use both, and I decide based on which one will make the code more clear and easy to read.
If you have heavily nested if statements (or any other control structure) and it may get confusing, then I would return inside the statements
Don't worry too much about what is 'best practice' in this case, as it is more important that the code is clear and easy to understand. Use what feels right for the situation.
For this case, I prefer:
boolean validate (DomainObject o) {
if (o.property == x ||
o.property2 == y ||
...) {
return true;
} else {
return false;
}
In general, I like to use early return to handle error conditions, and return at the end to return computed results.