I have got a legacy Java project with a lot of code. The code uses MVC pattern and is well structured and well written. It also has a lot of unit tests and it is still actively maintained (bug fixing, minor features adding). Therefore I want to preserve the original structure and code style as much as possible.
I aim to inject a new behavior into an existing class. Like a Duck that was trained to jump. Then I ask all my Ducks to jump. Those who can - jump. Those who cannot do nothing which is perfectly OK with me.
The new feature I am going to add is a conceptual one, so I have to make my changes all over the code. In order to minimize changes I decided not to extend existing classes but to use containment:
class ExistingClass
{
// .... existing code
// my code adding new functionality
private ExistingClassExtension extension = new ExistingClassExtension();
public ExistingClassExtension getExtension() {return extension;}
}
...
// somewhere in code
ExistingClass instance = new ExistingClass();
...
// when I need a new functionality
instance.getExtension().newMethod1();
All functionality that I am adding is inside a new ExistingClassExtension class. Actually I am adding only these 2 lines to each class that needs to be extended.
By doing so I also do not need to instantiate new, extended classes all over the code and I may use existing tests to make sure there is no regression.
However my colleagues argue that in this situation doing so isn't a proper OOP approach, and I need to inherit from ExistingClass
in order to add a new functionality.
What do you think? I am aware of numerous inheritance/containment questions here, but I think my question is different.
EDIT: Most of people replying to my question presume that a containment relationship looks like that:
class NewClass
{
OldClass instanceOfOldClass;
void oldFunctionality() { instanceOfOldClass.oldFunctionality();}
void newFunctionality() { // new code here }
}
But isn't this a kind of a containment relationship too?
class OldClass
{
void OldFunctionality();
NewClass instanceOfNewClass;
void NewFunctionality {instanceOfNewClass.NewFunctionality();}
}
ExistingClassExtension
, the question can't be answered. Say if, ExistingClassExtension extends ExistingExtension, your code snippet would make very little senseExistingClassExtension
class.