Anti-Patterns and Worst Practices – Monster Objects

monster Monster objects (or God objects) know too much, or do too much; monster objects are nasty beasts. The term God object was coined because these objects are said to be “all-knowing”. I’m in favor of the term Monster objects because knowing something isn’t a bad thing. These objects are usually bad things and Monsters are both big and bad, I find that more fitting. There are several problems with this anti-pattern. The two problems I most often see are testability problems and violating the Law(Suggestion) of Demeter.

Defensive Coding

I try to do my best when adding new functionality to avoid creating a monster object by continually asking myself if this new code is going to add an “and” to this class. If you’re tacking on code that makes the class do this “and” that, you’re probably adding it in the wrong spot. If this continues, you’re headed in the wrong direction. This is the primary tenet of the Single Responsibility Principle.

Violating Law of Demeter

You know you’re dealing with one of these when you find yourself burrowing down the member/function chain like the following:

orderItem.Product.Pricing.MembershipPrice

Likely your tests include creating a lot of setup code:

var price = new Money(35m);
var pricing = new Pricing() { MembershipPrice = price };
var product = new Product() { Pricing = pricing };
var orderItem = new OrderItem(product);

Instead, you probably want to break this apart if possible. There’s no benefit in having the OrderItem ask the Product to have its Pricing… you get the point.

For this example, you could likely remove the Pricing class entirely by incorporating some patterns here. The strategy pattern is a good one to follow when you need to run some calculations given a specific set of criteria.

var calculatedPrice = orderItem.CalculatePrice(new MembershipPricingStrategy()); 

Dealing With Monsters

A good way to deal with monster objects is to not deal with them. If you’re stuck with one for a while, abstract out what need from it and use the abstraction. Wrap this functionality in some code that you own (or are more free to modify) like Colin does in Breaking Free from HttpContext.

Monster Objects in the Wild

Lately, whenever I think of this anti-pattern, ASP.Net MVC’s HttpContextBase comes to mind. What other objects have you encountered that are “monsters”?

[See more Anti-Patterns and Worst Practices]

Related:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Chris Missal

Oh hey, I'm a Senior Consultant for Headspring in Austin, TX. I've been working in software professionally since 2006 and I really, really love it. I'm mostly in the Microsoft world, but enjoy building computer things of all sorts (to be vague). When I'm not slinging code, I'm probably out and about slinging discs, bowling balls, or good beer with great friends.
This entry was posted in Design Patterns, Design Principles, SOLID, Testing. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.agilification.com Jeff Doolittle

    Anything having to do with ASP.NET Membership. Monster object violation and *major* SOLID violations.

  • Kiran

    What is the precise definition of monster objects?

    The classes sit at the boundaries, example WCF implementation classes, tend to be large. These kind of classes typically won’t have any state.

    Do you have any suggestions to refactor such coarse grained service classes, without loosing the discoverability from client side?

  • http://www.lostechies.com/members/chrismissal/default.aspx Chris Missal

    @Kiran

    The definition is the same as it is for a God Object. As for breaking apart some services classes, if you don’t feel any pain, there’s no reason to break them apart. If there are problems with them, try identifying pieces of related functionality like in Colin’s post I linked to above. He breaks apart the HttpContext with a class that wraps Session and another that wraps the cookie persistence. If it is an object you own, you can try to pull it apart at these “seams”, instead of wrapping the functionality.

  • PAul

    The problem comes when customising a commercial system that already has a God object.
    Or even worse, that has multiple god objects that come from extensions of the God class.

    To make it worse; without a support contract, without knowledge of the system, and under a tight commercial deadline.

    The system design assumed every class instantiated was a data class, and required an underlying table and a PK for each instance to persist the class properties.

    Add to that its own model-based development environment that at first appeared to have a lot of potential for RAD, but was just bad in implementation.

    All in all, a rather catastrophic situation to be in, fundamentally a redesign was needed – more than refactoring.

    Unfortunately the promised .NET interface wasn’t, and attempts to produce facades, wrappers, or decorators failed.

    So in those circumstances, where at the same time Agile is introduced in to the mix and the programming staff is extended by contractors who don’t know the business or the tools – can you guess what happened?

  • http://twitter.com/lzp Zhongpeng Lin

    Do you think a Facade class to be a monster class? A Facade is often big, and it knows much because it needs to interact with many parts of a subsystem. Does it violate SRP? Well, if a responsibility means a function of the subsystem, then the facade class delivers multiple functions to the outside world, then it violates SRP. If a responsibility means a role, then its only role is to hide the complexity of a subsystem, no violations.
    Is it bad? Not sure.

    • Chris Missal

       Good question. There’s always going to be exceptions to the rules, and I think a facade would be one of those.