Reputation: 1807
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:
animal
? Especially because the same XHTML might use both a Dog
and a Cat
. Before it was fine because there was a Collar
object per each type. If I have to inject it, I have no idea how. (The problem seems similar to this, but it differs slightly).CollarController
and have all the functionallity reused, but this is not possible since the named beans already inherit from another class.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
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