Java Coding Style – Best Way to Call a Method Available to One Class Implementing an Interface

coding-stylejava

Basically I need to execute different actions given a certain condition. The existing code is written this way

Base interface

// DoSomething.java
interface DoSomething {

   void letDoIt(String info);
}

Implementation of the first worker class

class DoItThisWay implements DoSomething {
  ...
}

Implementation of the second worker class

class DoItThatWay implements DoSomething {
   ...
}

The main class

   class Main {
     public doingIt(String info) {
        DoSomething worker;
        if (info == 'this') {
          worker = new DoItThisWay();
        } else {
          worker = new DoItThatWay();
        }
        worker.letDoIt(info)
     }

This code works ok and is easy to understand.

Now, due to a new requirement, I need to pass a new piece of information that is only make sense to DoItThisWay.

My question is: does the following coding style good to handle this requirement.

Use new class variable and method

// Use new class variable and method

class DoItThisWay implements DoSomething {
  private int quality;
  DoSomething() {
    quality = 0;
  }

  public void setQuality(int quality) {
    this.quality = quality;
  };

 public void letDoIt(String info) {
   if (quality > 50) { // make use of the new information
     ...
   } else {
     ...
   }
 } ;

}

If I do it this way, I need to make the corresponding change to the caller:

   class Main {
     public doingIt(String info) {
        DoSomething worker;
        if (info == 'this') {
          int quality = obtainQualityInfo();
          DoItThisWay tmp = new DoItThisWay();
          tmp.setQuality(quality)
          worker = tmp;

        } else {
          worker = new DoItThatWay();
        }
        worker.letDoIt(info)
     }

Is it a good coding style? Or can I just cast it

   class Main {
     public doingIt(String info) {
        DoSomething worker;
        if (info == 'this') {
          int quality = obtainQualityInfo();
          worker = new DoItThisWay();
          ((DoItThisWay) worker).setQuality(quality)
        } else {
          worker = new DoItThatWay();
        }
        worker.letDoIt(info)
     }

Best Answer

I'm assuming that quality needs to be set alongside each letDoIt() call on a DoItThisWay().

The issue I see arising here is this: You are introducing temporal coupling (i.e. what happends if you forget to call setQuality() before calling letDoIt() on a DoItThisWay?). And the implementations for DoItThisWay and DoItThatWay are diverging (one needs to have setQuality() called, the other not).

While this might not cause issues right now, it may come back to haunt you eventually. It might be worthwhile to take another look at letDoIt() and consider if the quality information might need to be part of the info you pass through it; but this depends of the details.

Related Topic