Alternative writing of null check between two variables?

Tayfun Omer :

I am having a bit of a conundrum. I have 2 objects A and B. They can come as null or not null, and I have to do some different business logic in all of those situations.

At the moment I have:

if(A != null && B != null) { /* operation1 */ } 
if(A == null && B == null) { /* operation2 */ }
if(A != null && B == null) { /* operation3 */ } 
if(A == null && B != null) { /* operation4 */ }

Can you recommend me a way of writing those ifs in a more elegant way?

GabiM :

In fact, if you want to keep your if conditions visible in the calling method, your code is a better option than the solution proposed to imbricate the if conditions. All those if-else and inner if-else statements make it less obvious what the conditions are that trigger each operation. So you can keep your approach. See this blog post from Jeff Atwood

One small improvement you can do is extract methods from the if conditions and name the new methods in a way that documents your decisions:

if( isYouHaveACarAndEnoughGas(A, b)) { //operation to drive}
if( isYouHaveACarAndNoGas(A, b)) { //operation to walk}
...
private boolean isYouHaveACarAndEnoughGas(...){ return A != null && B != null; }

If you want/need something more fancy, you can use a command pattern or strategy. As a rule of thumb, repeated if-else statements or switches are signs you can use polymorphism to get the same result. See this excellent post with examples.

interface Operation{
    void execute();
}

class OperationBuilder {
    public static Operation build(TypeA A, TypeB B){
        if(A != null && B != null) { return new OperationOne(); }
        if(A == null && B == null) { return new OperationTwo(); }
        if(A != null && B == null) { /* operation3 */ }
        if(A == null && B != null) { /* operation4 */ }
    }

    class OperationOne implements Operation{
        private OperationOne(){...}
        @Override
        void execute(){...}
    }
    class OperationTwo implements Operation{
        private OperationTwo(){}
        @Override
        void execute(){...}
    }
}

To use this you just

Operation op = OperationBuilder.build(A, B) ;
op.execute();

And here is why this can be better than what you started of. Imagine you have

if(codition1){
  //complicated stuff here that makes you scroll and scroll
}
if(codition2){
  //complicated stuff here that makes you scroll and scroll
}
etc

You are likely to not see all the conditions on the same screen so you lose the overview of what's going on. On the other hand, the builder keeps all the conditions tight and clean, while the operational logic is again separated from noise.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=306111&siteId=1