Favor composition over inheritance
We’ve got a requirement to implement an image operation feature. User can select the images or take a photo. Since we already have the experience of other principles, we’ve decided to create a generic class and inherit it whenever needed.
ImageActivity has all features for the image operation. Any activity that wants to have this feature, can simply extend this class and have the image operations! Sound amazing.
Then regarding to requirement, we’ve implemented it in the account feature. AccountActivity is inherited from ImageActivity and it worked great.
As we anticipated, the same requirement has been asked in somewhere else. In the product section, they also wanted the same feature. We were ready and implemented it very very fast.
Everything went very well for a while. Then we got another requirement to implement the share operations. Since we’ve seen how great inheritance works, we did the same thing for the share.
And used it in ProductListActivity. It worked again great. Now anywhere requires image or share, it will be ready in a minute! But later on, we got another request which asks both of them.
What should we do? Since both class has the same method signatures, one can override the other one or both will act weird. Java doesn’t allow us multiple inheritance, so extending both wouldn’t work. Our system stuck in a way. This is not flexible anymore.
The right solution came with the composition.
Favor composition over inheritance.
With the inheritance, we got stuck easily. Then we realized, why do we inherit from activity? Image or share has no associate with the activity at all.
We separated the classes from the activity and created a helper class.
Since they need their own life cycle, they still provide these methods. Instead of inheritance, AccountActivity holds a reference to ImageHelper and use it as a member.
Instead of IS-A, we choose HAS-A.
Same with the share feature. Now for the latest request, we’ve easily added both feature to the Activity. We don’t need to inherit from ImageActivity or ShareActivity but put them as a member. This approach allowed us to have way more flexible structure. Now if they request another feature and implement it in this class, it will be very simple.
And finally our latest structure looks like this.
Still a long way to have a better system. There are many great principles/patterns to apply.