Pigs in Lipstick


A “fluffy” post today, that doesn’t talk about F# or EF or RavenDB etc. but about general development processes. Something I think all developers need to learn, and are always honing, is the ability to trust their instinct when something feels wrong.

What do I mean by this? Well, primarily this is about identifying when you’re working on a piece of code that e.g.: –

  • takes longer than it should to write (or test!)
  • is overly complicated
  • involves copious amounts of boilerplate

These sorts of smells are things that we need to learn to identify as early as possible – ideally when writing it the first time, or at least before the whole team is exposed to a particular paradigm or pattern. By then it’s a costly exercise to fix because of the amount of “wrong” code that’s been written, and the re-training exercise that will occur throughout the team.

Identifying smells

I think that when you make mistakes within software development, that’s when you learn the most – but you can only learn from those mistakes if you identify them (or someone identifies them for you). When I try to model a problem in code, often in my head I’ll go through a simple decision tree where I just knock off the solutions that I don’t think will “work” well and the ones that are left usually will do the job e.g.

  • can I use a factory to make this easier?
  • should I split this class into two… it seems like it’s violating SRP?
  • can I use the Strategy Pattern to simplify the boilerplate and duplicate code in these classes?

More than that though, is I think having confidence in your instincts – if what you’re working on “feels” wrong, it probably is. Or to put it another way – if it quacks like crap code, walks like crap code and swims like crap code – it’s probably crap code.

Summary

Take 10 minutes in your day to review what you’re doing (or get a colleague to do it) before you get bogged down into the depths of the problem and lose perspective. I can’t stress enough how important it is to have early code reviews / pair programming sessions when developing – this is when you can shift between one approach and another as cheaply as possible. Otherwise, you’ll spend three or four days on something only for the code reviewer to say “mmmm… there’s a much better way of doing this in half the time”. You’ll most likely feel defensive that someone has essentially said you’ve wasted a few days on something, and they’ll feel awkward about saying it. It doesn’t matter whether you’re using a fantastic technology; dressing up crap code in an awesome language or framework will not save you – so spot these pigs in lipstick early, and save your team some money.

Over-egging a Framework


I was holding off on posting this, but read some other good blog posts which sort of went along similar lines to this so decided to post it now…

What is a framework?

Whenever you write a reasonably-sized application, you’ll probably end up writing some sort of bespoke “framework” in your application. When you start writing it, the idea sounds great up-front – you’ll write something that will save hours in future! No-one will have to worry about anything, the “framework” will take care of it all! You’ll talk about abstraction and encapsulation etc. etc.. and tell yourself it’s best practice to do it.

Developing Horizontally

There’s just one problem with writing generic, catch-all frameworks – and that’s that more often than you think, it’ll be completely unnecessary. You’ll start by writing some business code. Then you’ll think to yourself, “Hmm, this bit of code seems like it’ll be useful to the team at some point in the future. Let’s write some helper classes and integrate it with our framework so other people can reuse this bit of code.”.

This is what is known as “horizontal development” i.e. developing frameworks and cross cutting concerns rather than developing business functionality.

The biggest problem with horizontal development is that often this code reuse never happens; you end up with abstract factories with just one or two types being returned, or whole class hierarchies being written when it would have been ten times quicker just to manually compose some classes together a few times. Even worse, sometimes you’ll guess wrongly how you’ll end up using the framework and end up boxing yourself into a corner and having rigid and viscous designs i.e. the framework blocks you from doing what you want, and you end up having to work around it.

Developing Vertically

Developing vertically is the idea of developing features end-to-end that cut across all tiers, and developing just the part of every tier that you need to fulfil that feature; as you develop more features, your framework should naturally and organically evolve. You’ll refactor existing business logic to take advantage of your improved framework to make your code more succinct and easy to understand within the context of the domain. Your unit tests will protect you from breaking changes in your framework as you refactor and enhance it.

How do we go about doing this? I tend to strongly follow the Uncle Bob school of thought here, plus the 80/20 rule. This boils down to the following: –

Do you know for a fact that this bit of code is going to be reused, right now, somewhere else? If the answer is “no” – don’t do it. Wait until you need it the second time and then consider doing it then. You’ll be surprised with how many times you end up leaving things as-is. Obviously, it’s not black and white – if it’s fifty lines of code I’d be more inclined to refactor it into a reusable method / class than if it were one or two lines.

There are many examples of this sort of situation that you might come up against every day: –

  • Having a constant in a method / class versus having a shared constants class / enum
  • Hard-coding something versus making some sort of generic / abstract factory
  • Using explicit / hard-coded values or classes versus abstracting it to the database (do you really need run-time configurability?)
  • Writing some screens that look similar versus writing a generic “control factory” that generates UI for you etc.

In all these cases I would choose the simplest, cheapest option and only if I could prove through the codebase that we would benefit from abstracting the code away would I do it.

There’s one exception to this rule: when the cost of doing it later will be excessively high and would require a lot of effort to do retrospectively. Obviously this decision requires a judgement call on your part on an instance-by-instance basis as to whether it’s a real risk or not, and what the likelihood of it happening is. In such situations, I would either absorb the cost up front, or try to protect myself against this sort of thing where possible e.g. in the example above relating to a factory, a decent halfway-house might be to make a factory class but hard-code the implementation to always return the same type of object, so that you can easily expand it later without impacting lots of places.

Conclusion

Whenever you are faced with this sort of situation, I always ask myself questions like: –

  • What’s the cost/benefit of doing this?
  • Are we ever actually going to use this in the future, or is it just “in case”?
  • How discoverable will my framework classes be?
  • Am I going to document the framework and make it easily available to the rest of the team – otherwise there’s little point in having it.

There’s always a cost of having duplicate code everywhere – but there’s also a cost of having a framework that’s unnecessarily complex.

Namespaces, namespaces and more namespaces


Some random thoughts and suggestions follow regarding how you design the namespaces that your classes fit into when writing APIs that other developers will utilise.

Many of these points I’ve recently been dealing with myself whilst having a team of developers joining a team I’m working in; when documenting some of the API and framework, I realised that it was not as easily discoverable or navigable as it could be; the next time I work on a reusable API, I’ll bear these points in mind more. I’d also recommend having a read of Framework Design Guidelines, which I read not too long ago and really opened my eyes in a number of ways to framework design.

  • Make your classes discoverable. I can’t stress this enough. The namespaces of your API should be easy to navigate, logically laid out and as readable as possible. Put yourself in the shoes of another developer who types MyApplication. in Visual Studio. When they press that “.” key, Intellisense is going to pop up and show them the different areas they can look through. This needs to be as clear as possible in order to guide them through the API; when I start trying out a new API, Intellisense is my first port of call – I certainly don’t start by reading all the documentation on every class.
  • Distinguish between 80/20 classes. It’s tempting to simply place all your classes that fulfil a particular function into a single namespace, but this often doesn’t help the developer. Instead, consider making a sub-namespace which contains more advanced features or classes (used 20% of the time) and keep the more common ones (used 80% of the time) at the higher, more easily discoverable, namespace. Also be strict regarding encapsulation – don’t make classes / methods / properties etc. public unless you need to.
  • Do not use department names in your namespace. Physical departments are always changing. At the end of the day they usually really have nothing to do with your API. If your department is restructured or renamed, will your code magically stop working? I would even go as far as to say for internal applications, do not include the company name either – what’s the point.
  • Beware of rigidly following the “namespace must be a child of the assembly name rule”. If we had an assembly called e.g. “MyApplication.Framework”, all code in that assembly should theoretically go underneath the MyApplication.Framework namespace. However, as an API developer, you might want very frequent and popular classes not to be buried away underneath the Framework level – you might want a developer to simply type “MyApplication.” and see the 4 or 5 most important classes that your API has to offer because that’s all that they might need most of the time. Indeed, they might have nothing to do with one another in terms of functionality – perhaps one is to do with logging, another to do with eventing etc.. It might sometimes be better to have an assembly which does not following the System.Subsystem.BlaBla naming convention and instead is simply called “BlaBla” – you’re not implying a namespace from this so are free to put stuff in any namespace.
  • Don’t be concerned with file navigation. Don’t worry that the developer cannot infer at a glance what assembly a particular class lives in. They can hit F12 and be transported to the source code (or metadata) of the class immediately; they can use Solution Navigator to find the file, or have Solution Explorer follow the active file etc.. That should not be your main concern when designing your API.