The Static Spider Web Pattern

SpiderWebSmall

"I’m picking up your sarcasm." "Well, I should hope so, because I’m laying it on pretty thick."

–Tommy Boy

While the developer lexicon is loaded up with more patterns than we can possibly ever learn, I just wanted to introduce one of the more important patterns that I think exists out there in software development. I call it the “Static Spider Web” pattern. The main driver behind this pattern is that object instantiation, allocation, and deallocation impose far too much overhead in modern programming language runtimes. Since we aren’t in direct control of memory management, and since garbage collectors on systems with large amounts of memory can cause huge latency overheads, we need to find some way to minimize, at all costs, the number of objects that we allocate.

First, we are going to have to just accept the fact that we will have to create a few objects. I mean, our application data needs to go somewhere, right? I’d advocate for passing the data around as parameters, but that would get old pretty quick with all of that typing. Besides, that is what objects were invented for, to be stateless data containers.

Let’s Get Started

The first thing you will want to do is create your business object:

public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public DateTime BirthDate { get; set; }
}

Now that we have our business object, we are going to have to do something with it. So I am going to create a class which will allow me to perform a save operation on my business object:

public static class PersonManager
{
  public static bool SavePerson(Person person)
  {
    
  }
}

I like to use the term "Manager" since it is very generic. That allows me to shove pretty much whatever I want in there. This keeps me from having to create too many classes. I like being efficient.

So now that I have a class which will allow me to save my Person class, I just need to save it to the database. To do that, I create another class which will allow me to save it off. I know I said I like to keep the number of classes to a minimum, but in this case it is good to keep all of your data access in one place:

public static class DataLayer
{
  public static bool SavePerson(Person person)
  {
    // save person to database
  }
}

I call this class "DataLayer" so that I can avoid having to create a different one for each of my business objects. This way I can just keep putting more and more methods in there. Eventually it gets pretty big, but when that happens I just wrap each section in regions so that it looks really small:

image

How cool is that? Almost 6000 lines, but you can’t even tell! This is what I call “code hiding”. It should only be used by super expert coders.

Making Things More Clear

I think you are already starting to really get a good idea of where I am going with this pattern. But I’ve often felt that a diagram always helps get the point across:

 image

So, as you can see, we have some objects that get passed down at the top, and then they get fed into this very simple and efficient web of static methods. These static methods will then call each other, call out to third party libraries, call out to helper classes, or call into the data layer. Occasionally I like to call out to web services for when I am doing service oriented architectures. Or if things get really crazy, I’ll put some XML serialization in between the layers. Then it would look like this:

image

You may think that this might get out of hand, but by keeping everything as static methods in a bunch of different classes it allows for maximum code reuse since anything can call out to anything else. You may think that this breaks concepts such as encapsulation, but we are keeping all of our data in classes, so I don’t think that we really need to worry about that.

Testing

With the Static Spider Web pattern testing is really easy. You just have to create your objects and pass them into the static methods in the Manager Layer. Then you can just check to see if what you expected to happen actually happened! How simple is that? Of course you are going to want to make sure that you have a full test environment setup before you do this. You’ll also want to make sure that you have different types of config for production and for testing so that you can hit different local databases. You’ll probably also want different databases for your unit tests, and reset scripts to get your data back the way you want it. Oh, and you probably also want settings so that you can write to local directories instead of network paths. You know, all of the stuff that is different from your local and production environments. But creating settings for those and then wrapping all of the calls to it is only a few lines of code. Well, a few lines of code repeated a few thousand times, but still, it is really simple code to write.

If you happen to be calling out to web services, you’ll probably want to also setup alternate test web services that you can call. If you don’t have test web services, then you’ll probably need to put in code around every call to them that checks if you are running in "debug" mode. As far as third party code goes, you might need to put checks around calls out to those as well. But other than that, testing should be a breeze.

Summary

Overall I think that the Static Spider Web pattern isn’t for every application, just most of them. It is a very simple pattern that doesn’t really take much effort or forethought to implement. Once you do implement it, you’ll find that your development will go very quickly and you’ll be cranking out feature after feature in no time.

Be Sociable, Share!

37 comments

  1. This pattern reminds of that PDC 09 video I watched about Axum. It describes the same pattern in a new language (which looked like C#). Axum attempts to solve scalability and tread safety issues.

    Any chance you’ve seen it? Could this pattern be made to support thread safety without a lot of locking?

  2. I just checked my calendar, and it’s NOT April Fool’s Day, Justin. ;)

  3. @Lee It doesn’t need to be April Fool’s day in order to be a smart ass. :-)

  4. I hope you are being facetious. Please tell me you are not serious.

  5. @Daniel Did I really not lay the sarcasm on thick enough? :-)

  6. I’ll begin migrating my GOTO code to this immediately!

  7. Sad part is, I’ve seen code like this.

  8. @Justin I just needed to know if I had to cancel my vacation to Flo-rida for an intervention. :)

  9. @Sean I think we have all seen code like this. But until you look at it in this way, it just seems simple to implement. Sure, I was very sarcastic about it, but to me it is a somewhat comical situation.

    The absurdity of the pattern doesn’t really become apparent until you fully lay it out.

  10. This is one of the most entertaining posts I have read in a while.

  11. Hillarious ! :)

    This is the most common pattern that I see in my gigs, I am very surprised that it wasn’t named before !

    Something with this level of popularity can’t be wrong, so this should be included in Fowler’s pattern book / directory for further promotion.

  12. Not only have I seen a lot of code like this. I have also implemented it, back in the dark days of 1.1. I used an ORM though, so that made it totally better.

  13. How long until we see SSW frameworks in PHP, Java, and ASP.NET? :)

  14. @Bill You don’t need a framework, since it is so simple! Ha.

  15. I’ll agree with you that when you present this as a pure architecture pattern it looks crazy. However, have you read any of the Microsoft Patterns and Practices material? Most of their web application guidance suggests the "static spider web" and has for years. It’s only recently that the .net world has embraced test-first and a lot of the code the fits this pattern is legacy .net code following Microsoft’s suggestions. Be careful you don’t sound too snarky because many people the deal with this every day can’t change it overnight.

  16. @Marcus Agreed. I’m sure this came off as snarky, and I’m sure a few people will get offended, but that wasn’t my goal.

    I’ve written this code in the past, I’m sure most of us have been there. But it is time for people to look past that, and look for ways of doing things better. I hoped to point out a bit of the absurdity, and at the same time, have a good laugh.

  17. This reminds me heavily of abject-oriented programming: http://typicalprogrammer.com/?p=8 – similar hilarity

  18. Justin, I can see one (and maybe only one) problem with your pattern: wouldn’t it interfere with having really deep class inheritance hierarchies? You’ve just never experienced a smooth ride until you’ve had seven layers of base classes underneath you to do all the hard stuff. Of course this could just be two side of the same KISS-coin.

    </wink>

  19. haha … i am crawling it! Fantastic!

  20. The best part about this pattern is it is also applicable to most SOA implementations in production today! It’s even easier because "web" is already in the name!

  21. Gabriel Schenker

    I best like this one "…objects are stateless data containers…". LOL

  22. I have no mouth, and I must scream

    @Sean Sad part is I deal with code like this. And I wrote it

  23. Just when I thought I had it all figured out this gets posted. It will be a while until I reach this plane of existence.

    But it has me thinking? Maybe you need to add some binary serialization in there too. Then you could store everything in one database table.

  24. [quote]I like to use the term "Manager" since it is very generic.[/quote]

    Now I use DDD so I replaced all occurrences of [i]Manager[/i] with [i]Repository[/i].

  25. Ouch! Don’t worry about offending people; I doubt many people who read your blog are fans of this "design."

    What you need to do is break that DataLayer class into partial classes. That way, it doesn’t [i]seem[/i] like your class is so large, but everything is still easy to find through intellisense. Now that’s how an expert hides code. <ducks>

  26. A cool pattern but I think wrapping objects functionally with Scala is simpler – with implicit conversions – check out Lift

  27. @Chuck Yep, but repositories have a very focused purpose!

    @Al Thanks, sometimes I lean towards not offending at all, but I think then people don’t learn anything.

  28. #region BEEN THERE

    NEVER AGAIN

    #endregion DONE THAT

  29. I was once helping a fellow developer work through some issues and came upon a method which had been added inappropriately to a class intended for a completely different purpose. I pointed out the ill placed method and nudged him to find another solution.

    Long story short is that after much nudging he finally says to me "you mean we should create a completely new class for this new method". I said "yes, you see it is doing a new type of task and so we should place it in a new class for this type of purpose". He says "but that is so much work".

    I was floored….what do you even say to that. Creating a class in C# is the easiest thing to do since slicing bread with an automatic bread slicer.

    In all seriousness I have seen resistance from developers of varying skill levels to creating classes. There is some mental barrier that folks struggle to overcome. Why is Curly’s Law so hard to follow?

  30. The sad thing is, a long time ago, I’ve [b]written[/b] code like this.

  31. @Erik I would so that most of us have.

  32. Nice anti-pattern, looks very much like some projects i’ve worked on. But as stupid as it may sound, i would very much like to see examples of the ‘right’ way to do it. :)

    Or to put it in another way: When is it okay to make a class static?

  33. @Theo Okay, this might sound stupid to you, but my answer is "never". And again, that might sound crazy, but hear me out. Static a commitment. Static is saying, I want only a single reference to this. I will never need multiple instances. I will never need any instance data. I will never need anything. I want this to be set in stone.

    So you might be saying "well, that just sounds like a performance nightmare!" My first response would be "test it, it probably is nowhere near as bad as you think", but my second response would be "if you can prove it is a nightmare for your performance, then use a singleton". At least with a singleton you can replace it when you need to. Or if you are using an IoC container, you can turn off its singleton behavior easily.

    So, in the end, I would say that I would lean away from ever using static in business applications. If you are writing games or modeling nuclear exposions, then all bets are off.

  34. @Justin Thanks for the explanation Justin, actually most decisions for making strings static that I’ve seen have never been regarding performance. And i would agree that it wouldn’t be a particular performance-hit, especially compared to data-access and other bits that one always have in a typical application.
    I think people are using static, cause they cannot find a reason why they should instantiate an object, when the functionality they want is in one method alone and the class doesn’t keep state. (ie. making the class static, cause we only call this seperate method anyway, and then we ‘save’ the instantiation).
    Now im sure that they know that making these methods / classes static is the easy/short (procedural) way of doing it, and not the correct object oriented way, but it’s done like this anyway because they lack the basic OO skills/theory to convince them of the right way. And i don’t myself know the correct way of modeling this, without turning everything static and making the giant helper-classes. Or even making the helper-classes without static, but with a lot of seperate methods.

    How to one get away from making these ‘helper’ classes?

    Thanks for the help and merry christmas :) :)

  35. Couldn’t you make the argument that static methods on "helper" classes are really "functional" programming? :-)

Leave a comment