Pattern oriented programming

Ever since the “Gang of Four” book, everyone and their uncle is an expert in patterns. Software is all about patterns – the trouble is, it seems very little of note has happened in the intervening 20 years.

Why patterns are good

Patterns help because they let us talk about code using a consistent language. Patterns make it easier to read code. Ultimately, reading code is all about being able to reason about it.

If I change this, what’s going to break?

This bug got reported in production, how the hell did it happen?

If I can see the patterns the code implements, it lets me reason about the code more easily, without having to carefully analyse exactly what it does. Without them, I have to carefully understand every single line of code and try and reverse engineer the patterns.

The trouble is, the patterns often get mixed up with the implementation. This makes it hard to discern what the pattern is, and whether it’s actually being followed. Just because a class is called TradeManagerVisitorFactory doesn’t mean I actually know what it does. And when you open up the rats nest, you realise it’s going to take a long time to know what on earth it’s doing.

Patterns Exist

Patterns exist in our code, whether we explicitly call them out or not – there are hundreds, probably thousands of patterns that we’re all familiar with. Wouldn’t it be great if these patterns, at least within a single code base, were consistent? Wouldn’t it be great if we could help keep developers on the straight and narrow so that when they instantiate a second instance of my “singleton” we can break the build because it’s obviously changed something that might break all sorts of assumptions.

If we could start identifying the patterns in our code, and (somehow) separate that from how they’re implemented, we might actually be able to change how certain things are implemented, consistently, mechanically, across an entire enterprise-scale code base. Let me guess, an example would help?

The Builder Pattern

Ok, it’s a really simple pattern – but it makes a nice example. I have a class, that I need to be able to create, so I use the builder pattern. However, really, a builder is a type of object construction pattern. If I start thinking about different ways objects can be instantiated I can quickly come up with a handful of alternatives:

  • A constructor, with a long parameter list
  • A builder, with a lot of setXxx methods
  • A builder, with a lot of withXxx methods, that each return the builder for method chaining
  • A builder with a list of properties for object initialisation (C#)

Now, this means I have four ways of implementing “the builder pattern”. And you know, it makes precisely zero difference, functionality-wise, which I choose. It’s an entirely stylistic choice. However, I probably want it to be consistent across my codebase.

When it boils down to it, my pattern has three elements:

  • The actual pattern – e.g. a builder with method chaining
  • The logic & configuration for the pattern – the list of fields, the types, any type conversions or parsing etc
  • The actual rendering of the first two – this is all we have today: source code

I don’t want to get rid of the last (code generation is great, until you have to, you know, actually use the generated code). This should all work from existing, real code. But maybe we could mark up the code with annotations or attributes to describe what pattern we’re following and how it’s configured. Some of the logic and configuration would have to be inferred – but that’s ok, once we know it’s a builder pattern we can take entire method bodies as “logic”.

Pattern Migration

But you know what would be really awesome? If I could change how the pattern is implemented. Maybe today I’m happy with all my objects being constructed from a long parameter list. But maybe tomorrow I decide to change my mind and use builders and withXxx method names. Wouldn’t it be awesome if I could simply change the global config and have all my code automagically refactored to match? If all my builders are annotated and identified, and all enforced to be written the same way – I can extract the configuration & logic from the implementation and re-render the pattern differently. I could programmatically replace a constructor call with a builder or vice versa.

Ok, the builder is a trivial example that probably isn’t of much use. But how many more patterns are there? Say today I have classes with lots of static methods. Well, really, they’re singletons in disguise. But none of the cool kids create singletons nowadays, they use IoC frameworks like spring to create singleton beans. Wouldn’t it be nice if I could mass-migrate a legacy codebase from static methods, to singletons, to spring beans (and back again when I realise that’s made things worse!)

Controllers

What about a more complex example – let’s compare spring-mvc and struts. Two frameworks to accomplish basically the same thing – but both with a very different philosophy. The answer isn’t to build a framework to capture the common parts of both – trust me, been there, done that: you get the worst of both worlds.

But, could you describe a pattern (probably several) that struts actions and spring-mvc controllers follow? Ultimately, both spring-mvc and struts let you respond to web requests with some code. Both give you access to the HTTP request and the session. Both give you a way of rendering a view. I wonder if you could describe how to extract the pattern-specific parts of a struts action and a spring-mvc controller? The config comes from different places, how to render views is different, how the view is selected is different, even the number of actions-per-class can be different. But, could you extract all that functionally irrelevant detail and separate the pattern configuration from the underlying source code.

If you could, maybe then you could describe a transformation between the two (sets of) patterns. This would give you a purely mechanical way of migrating a struts application to spring-mvc or vice versa.

Pattern Database

Now, the cost for me to describe, in great detail, all of the patterns for spring-mvc and struts in order to automatically migrate from one to the other is probably more than the effort to just get on and do it by hand. I could probably tackle a bunch with regexes and shell scripts, then hand finish the rest. However, what if we could define these patterns and share them? If there was some kind of open source pattern database? Then, the cost for the community is spread out – the cost for me is minimal.

Could we get to a point where our patterns are documented and codified? Where we can migrate between frameworks and even architectures with a manageable cost? An impossible dream? Or a better way of crafting software?

10 thoughts on “Pattern oriented programming

  1. Jonas Hellborg

    Yo Dave, Jo(nas) here: interesting post, and I’m currently very much in Pattern Land at the moment, but with a desperate need to stop typing so much Java code. 🙂 This has triggered a vague idea of mine, with even vaguely correct Java annotations like @ObjectCreation @SomeExternalDependencyRequired @RandomSignificantThingX @WeAllDieIfThisOneBreaks and such, and if such could let me do far more powerful refactoring as and when I need to, or feel like it. Yeah, even more than Eclipse does. Even more. Lol. For non-java, a basic comment just above the method signature and some regexp could help. Also hear the community cry! If/when I try some random craziness out, I shall let you know that I’m ready!

  2. There is actually a small but fundamental difference between your first builder implementation (constructor injection) and the other three. With constructor injection you can guarantee that all your dependencies have been provided, as long as you don’t do silly things with multiple constructor overloads. With property injection, the object under construction never knows when the builder is done, so you have to have some sort of verify() method at the end of the chain (or, of course, make all the rest of your code capable of handling the fact that the object hasn’t been built properly, but no-one wants to do that).

    This means that the builder pattern is itself 2 patterns – one that guarantees object construction, and one that doesn’t (e.g. if you don’t notice one line of your 1000-line spring config xml gets mergesplatted).

    This applies to other patterns too. Is your legacy singleton (anti)pattern using double-locked checks for thread safety? Does it need to be? Are your decorators independent, or must they be invoked in a particular order (for instance validator decorators first)? Do the commands in your command pattern have behaviour, or are they data-only and serialisable?

    Before we can think about mechanising things, we need consistency of design.

    1. Thanks for the comment, Russ! You’re absolutely right. When discussing builders I was assuming that all the setters were optional, or could be given reasonable defaults. Obviously this isn’t always the case, so you might have a mixture of patterns – where mandatory fields are set in the constructor and optional parameters can be passed in via the builder. In my mind, this means some fields in the pattern are marked as mandatory and some as optional – you then have a couple of choices for how you deal with missing mandatory fields (basically compile time error or runtime error).

      I think where patterns overlap and have complex configuration this higher-level description becomes even more powerful. As you say, a singleton may or may not use some locking mechanism – locking is itself another pattern, that overlaps with the singleton pattern. Each class and method might have numerous patterns, each with their own “configuration” that apply to them – to allow for variation, e.g. is the singleton implemented as a static or a spring bean.

      Interestingly, for me, describing things in terms of patterns is about getting consistency of design. In most normal code bases that isn’t the case, but maybe by expressing things in terms of patterns you can see what the exceptions are and deal with them one by one over a period of time – either mechanically or manually.

      1. TBH, this is where I find things like IoC containers useful, but I know your feelings on the tendency for them to be abused 🙂 As long as there’s no XML, of course. I like Ninject on the .Net platform – no XML, no implementation-specific attributes on the POCOs (unless you really want to), type safety from the compiler on your bindings, etc. SimpleInject has a really nice syntax for binding decorator chains, too. With these containers, you don’t implement the guts of certain patterns youself, and so you get consistency.

  3. Hi Dave,

    Nice post on an interesting topic! I share your view on many aspects: patterns help reason about the code, and they “exist in our code, whether we explicitly call them out or not”. So why not make them more explicit?

    I’ve been investigating that very idea of harnessing patterns for something useful for some time, in code and in blog posts: http://cyrille.martraire.com/category/patternity-blog/

    More recently with some colleagues we settled on the fact that patterns made explicit in the code could help define, and therefore enforce, the forbidden or allowed dependencies between pattern participants. This can work from the class level to the layers level. We re-started a project on github: https://github.com/cyriux/Patternity Your feedback is welcome! Another track is obviously to output smarter design documentation extracted from the source, thanks to the knowledge of declared patterns.

    Aside from the GoF patterns, other patterns like those from the DDD book are especially interesting to structure projects at a more macro level.

    And if you’re just looking for annotations, jpatterns.org and the infamous google gag annotations are available too…

    Cheers,

  4. That’s definitely an interesting and intriguing thought, but I’m afraid it will end like any other approach to standardize patterns in a library: As a failure by design. The reason is that a pattern is really only… well… a pattern. Each implementation varies wildly. That’s not an accident, but simply the price you have to pay for applying a pattern to ever changing contexts.

    1. I suspect you might be right. But I’m hopeful the difference with this approach is that rather than trying to create a pattern library, this is describing something a level above source code – to differentiate between the pattern and the context-specific stuff.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.