Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface inheritance to breakup god objects?

I work on a fairly large product. It's been in development since .Net 1.0 was still a work-in-progress and so it has a lot of bad quality code and was not written with unit tests in mind. Now we're trying to improve the quality and implement tests for each feature and bug fix. One of the biggest problems we're having now is dependency hell and god objects. There is one god object in particular that's bad: Session. Basically, anything related to the current session of the program is in this object. There are also a few other god objects.

Anyway, we've made this god object "mockable" by using Resharper to extract an interface out of them. However, this still makes it hard to test because most of the time you have to look at the code that you write to figure out what really needs mocked out of the 100 different methods and properites.

Just splitting this class is out of the question right now because there are literally hundreds if not thousands of references to this class.

Because I have an interface(and nearly all code has been refactored to use the interface) though, I had an interesting idea. What if I made the ISession interface inherit from other interfaces.

For instance, if we had something like this:

interface IBar
{
  string Baz{get;set;}
}

interface IFoo
{
  string Biz{get;set;}
}

interface ISession: IFoo, IBar
{
}

In this way, existing code using ISession wouldn't have to be updated, nor does the actual implementation have to be updated. But, in new code we write and refactor we can use the more granular IFoo or IBar interfaces, but pass in an ISession.

And eventually, I see this as probably making it easier to eventually break up the actual ISession and Session god interface/object

Now to you. Is this a good way of testing against these god objects and eventually breaking them up? Is this a documented approach and/or design pattern? Have you ever done anything like this?

like image 341
Earlz Avatar asked Feb 08 '13 15:02

Earlz


1 Answers

From my standpoint this is good and right approach. Later you can inject more specific service instances as IFoo/IBar rather than ISession, I would say this is a good intermediate step before further refactoring to extract classes from a god class to many specific services.

Some pros I see:

First stage: extract interfaces

  • A super (god) class type is abstracted by interfaces
  • Code becomes less coupled since relies on single-function responsible interfaces (services)
  • You have ground to move further and split a god class into many services without massive refactoring sicne everythign already relies on interfaces API

Second stage: split a god class into many small services with keeping Single Responsibility principle in mind

Third-stage: Structurize existing unit tests so tests grouped per service type rather than all together around a god class

like image 83
sll Avatar answered Sep 28 '22 07:09

sll