1

Say, I have a class A which has methods m1,m2,m3,m4,m5.... m100.

I am making another simpler class B and I require only m2,m3 and m5 in B.

Should I be ideally using compositions and put a reference of A inside of B and just delegate the functionality ?

or I should just re-write[copy=paste] those 2-3 methods out of class A ?

8
  • 7
    Neither. Class A is most likely far too complicated and that functionality should be separated out into various classes.
    – Phoshi
    Oct 3, 2013 at 13:41
  • 4
    If you don't have the possibility to refactor A, then I would write an interface B and an adapter for Class A. Actually, what I really would do is take the functionality out of A, put it in B and have A inherit from B.
    – Pieter B
    Oct 3, 2013 at 13:48
  • I can't touch A. its "legacy" code! Oct 3, 2013 at 14:00
  • 2
    to work with "untouchable" legacy crap having 100 (!) methods in a single class, consider establishing an anti-corruption layer
    – gnat
    Oct 3, 2013 at 14:12
  • 2
    actually what I was using was a class had a lot of methods for a cucumber step definitions some limited features in the app. All these features are unrelated but all of these step def are put into one class. and now I dont want to add more stuff to this class but I still need the existing code as it has some scenarios which are a pre-requisite to the scenario I am automating for testing. Oct 3, 2013 at 14:17

1 Answer 1

1

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'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.