Refactoring Change Unidirectional Association to Bidirectional
ProblemYou have two classes that each need to use the features of the other, but the association between them is only unidirectional.
SolutionAdd the missing association to the class that needs it.
Originally the classes had a unidirectional association. But with time, client code needed access to both sides of the association.
- If a class needs a reverse association, you can simply calculate it. But if these calculations are complex, it is better to keep the reverse association.
Bidirectional associations are much harder to implement and maintain than unidirectional ones.
Bidirectional associations make classes interdependent. With a unidirectional association, one of them can be used independently of the other.
How to Refactor
Add a field for holding the reverse association.
Decide which class will be "dominant". This class will contain the methods that create or update the association as elements are added or changed, establishing the association in its class and calling the utility methods for establishing the association in the associated object.
Create a utility method for establishing the association in the "non-dominant" class. The method should use what it is given in parameters to complete the field. Give the method an obvious name so that it is not used later for any other purposes.
If old methods for controlling the unidirectional association were in the "dominant" class, complement them with calls to utility methods from the associated object.
If the old methods for controlling the association were in the "non-dominant" class, create the methods in the "dominant" class, call them, and delegate execution to them.
Tired of reading?
No wonder, there are 7 hours worth of the text on this website.
Try out something different. We've just launched the interactive learning course on refactoring. It has more content and much more fun than a boring text.Learn more...
Everything is quite simple. This example is like video (but much cooler):
- After pressing the Play button, you will see floating messages, which will guide you through the example. You can proceed by clicking on them.
- You can fast-forward or return to previous steps by pressing arrow buttons on the left.
- Also, you can take a look at the code diff window, which will show what has changed in code during the example ()
- To check the code for errors, you can press "Compile and test" button ()