Ideally, don't cut and paste code. Duplicating functionality inevitably leads to errors in one and a slow divergence of hacks (need to make an 'easy' change in one leading to an 'ugly' change in the other). The key to this is to refactor it in such a way that the ugliness in the original class can be hidden away as best as possible, and a new layer of code in front of the ugly leads to 'abandon in place' of parts of the ugly.
The ultimate goal, despite the 'legacy' nature of A
is to dry up the code so that B
and A
share a common base class. Even if you can't get there, that is the ultimate destination.
The first step in this process is to make that abstract class that implements just the subset of common methods to B
and A
.
Once you have this, you make a pair of implementation classes - B
and A'
. A'
is an anti-corruption layer / wrapper that wraps around A and passes through the method calls as appopriate.
(This is where it gets a little ugly)
Without knowing if the 5 methods (that are part of the abstract class) change the state of A
in a way used by the other 20 methods it can be difficult to consider the proper design.
Lets call all the methods a
.. z
. The methods a
, e
, i
, o
, and u
are the ones that are to be implemented in class B
. If, in A
, the method a
modified state used by b
and e
- then it is probably best that a
and e
are both pass through.
On the other hand, if aeiou
do not change any state used by the other methods, they can be completely encapsulated within the abstract class.
Now, if you can make a change to the legacy code - its a rather minor one - make an interface (iA
)that defines every method in A
that A
implements and A'
implements. One can then refactor every passing around of A
to iA
.
Then, you can change the iA foo = new A()
to iA foo = new A'(new A())
Now, you've got a class B
that extends the abstract class, A'
that extends the abstract class and implements iA
which provides identical functionality to A
. The code for aeiou
is as isolated from A
as possible so that changes to it in the abstract class make the appropriate changes to both B
and A'
.