Lives in the UK. Likes blogging, cycling and eating lemon drizzle cake. Roger is a DZone MVB and is not an employee of DZone and has posted 142 posts at DZone. You can read more from them at their website. View Full User Profile

Top Trumps in God Objects

10.18.2011
| 4041 views |
  • submit to reddit

If we were playing the children’s game Top Trumps with Java interface definitions I think that I’d win every time. That’s because I’ve just found an interface, which is part of a prestigious company’s public API with with 167 methods. Trump that! Imagine, if the interface definition contains 167 methods, how big is the implementation class? In the words of a texting teenager “OMG”.

You’ll probably know that objects that are as out of control as this are usually called God Objects or Monster Objects and there’s an anti-pattern of the same name which explains it all. If you look on at various definitions of the God Object Anti-Pattern, they usually say a god object is an object that “knows too much or does too much”1, words which seem to crop up all too often if you dig around the internet. In modern programming speak this generally means that a god object:



These types of objects are not that uncommon (though I haven’t seen too many until recently and none as bad as this one) and it makes you wonder, how does such a mess arise? It’s surely easier to do a good job than to make a complete mess. So, I tried to come up with some of the excuses that the professional company in question might give for creating a God Object of such magnitude:
  • Lack of time, tight deadlines. This doesn’t really stand up as an excuse. From experience, I find that it’s quicker to do a proper job, with Unit tests, than it is to hack in some extra functionality.
  • The programmer adding in a new change “couldn’t be bothered” to refactor and do a proper job, such as changing the whole thing was too much effort and he/she had better things to do like catching up with friends on Facebook. Hm-mm probably...
  • The developer didn’t want to break anything (too scared). This does stack up if you’re asked to add additional functionality to an existing god object that doesn’t have any unit tests. There’s always that feeling of fear and apprehension that you may break something. The only way out of this is to write tests, which is dull and tedious. See my point above: “couldn’t be bothered”
  • Programmer ineptitude. Enough said.
If you need the formal explanation of the God Object Anti-Pattern see Wikipedia, whilst for something more light hearted see Decaying Code.

The question is: how do you go about fixing such a mess and the standard answer is to apply the single responsibility principle, creating groups of methods that are responsible for individual bits of functionality. These should then be removed from the god object one at a time and implemented as objects in their own right.

But, and in this case there’s a BIG BUT, what if you can’t refactor? The interface has above has nothing to do with me, it’s not my code2 and I don’t have access to its source code. The answer is to apply the same idea, splitting the monster class’s methods up in to functional groups, but then writing a set of Adaptors (aka Delegate and Wrapper) classes one for each functional area.


The rough UML diagram above demonstrates the solution to my particular problem, though it should be remembered that with 167 methods there will be lots of adaptor classes, each with proper documentation and unit tests... all of which leaves me with that nagging feeling of “can I be bothered”, after all, Facebook is calling...

1Wikipedia
2I’d be hugely ashamed if it was...

 

 

From http://www.captaindebug.com/2011/10/top-trumps-in-god-objects.html

Published at DZone with permission of Roger Hughes, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Lund Wolfe replied on Sat, 2011/10/22 - 11:40pm

The "God" class anti-pattern is actually the norm for older Swing applications, putting everything in the main JFrame GUI class. I feel your pain as I'm working on one right now. I want to break the whole app into an MVC structure first, which I'll need to do in one non-trivial refactoring. The "God" class I can break up a little bit at a time. I think it makes more sense to actually extract smaller classes/interfaces from the "God" class completely, making the "God" class a client as well. Commenting out the member data often makes it obvious what, and how much, code will have to be extracted out with each new class or set of classes.

I think I know how these things come into being. It starts out as a sort of prototype until the developer gains confidence that his project will actually be functional and deliverable. This prototype has significant technical debt to say the least. This is one of the reasons why they say to build one to throw away. You'll learn a lot about real requirements and class organization, but what you already have isn't worth keeping. Unfortunately, we usually do keep the first attempt, even if we already know it is ill conceived.

There are also some significant risks in doing a full OOD or domain design and fully identifying/naming Classes, Responsibilities, Collaborators, resulting in design clarity and understandability. If you aren't fairly close the first time out, you can expect lots of refactoring and having to confront your mistakes/misconceptions at each point along the way. Many developers don't want to go there.

Once you have a long-standing "God" class, nobody makes an attempt to factor it out. It's too hard to escape the global variable anti-pattern which already has access to everything inside the class. Adding a new feature or change outside the existing class becomes an unnatural act, since you must keep accessing the "God" class for data and methods, anyway, or start a refactoring job which greatly exceeds the time allotted to the new feature itself.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.