user1156544
user1156544

Reputation: 1807

Refactoring named beans to avoid code duplicity

I have detected I am repeating code in my named beans sistematically, so I am looking for a way to reorganise the code.

For example I have three named beans that repeat this code about Collars:

@Named(value = "dogController")
@ViewScoped
public class DogController implements Serializable {

    private Dog dog;  // Class Dog has a List<Collar>
    private Collar collar = new Collar();  // to be used in an XHTML form
    ....
    public addCollar(){
        //adds collar in dog
    }
    public removeCollar(){
        //removes collar from dog
    }
  }

So beans CatController and BirdController have also the same code. The same happens with Photo, all of them repeat code. So I think I am behind a pattern here.

My immediate step is to create an interface HasCollar for Dog, Cat and Bird. Then I move the repeated code into a new bean:

@Named(value = "collarController")
@ViewScoped
public class CollarController implements Serializable {

    private HasCollar animal;
    private Collar collar = new Collar();  // to be used from the XHTML
    ....
    public addCollar(){
        //adds collar in animal
    }
    public removeCollar(){
        //removes collar from animal
    }
  }

So far so good. My problem now is:

So, how can I refactor this situation to have as less repeated code as possible?

(Please, let me know if more information is needed)

Upvotes: 0

Views: 152

Answers (1)

Andrew S
Andrew S

Reputation: 2756

Consider the relationship between Dog and Collar: a Dog has-a Collar.

In other words, addCollar() and removeCollar() are actions of a Dog, so those methods belong inside Dog:

 public class Dog {
    public addCollar(){
        //adds collar
    }
    public removeCollar(){
        //removes collar
    }
}

Same for the Cat, Bird, etc. The code is still duplicated at this point.

Then a controller can simply delegate:

@Named(value = "dogController")
@ViewScoped
public class DogController implements Serializable {
    private Dog dog;  // Class Dog has a List<Collar>
    private Collar collar = new Collar();  // to be used in an XHTML form

    public addCollar(){
        //adds collar in dog
        dog.addCollar();
    }
    public removeCollar(){
        //removes collar from dog
        dog.removeCollar();
    }
}

Same for the Cat, Bird, etc. controllers.

Now the common code can be placed in a single class such as:

public class CollarHandler {
    private List<Collar> collars;
    public addCollar(){
        //adds collar
    }
    public removeCollar(){
        // remove a collar;
    }
}

And Dog's constructor takes a CollarHandler, and its methods delegate to the handler:

public class Dog {
    private CollarHandler collarHandler;
    public Dog(CollarHandler collarHandler) {this.collarHandler = collarHandler; }

    public addCollar(){
        collarHandler.addCollar();
    }
    public removeCollar(){
        collarHandler.removeCollar();
    }
}

Same for the Cat, Bird, etc.

There is no common interface nor inheritance. Each controller is still independent, but behavior can be shared.

Upvotes: 1

Related Questions