The S in SOLID

Right, I’m back onto the SOLID principles again, I apologise to those who are bored of this.

So the other day I was listening to the most recent Scott Hansleman podcast with Uncle Bob Martin where the conversation was about the recent handbag fight between Bob Martin and Joel Spolsky – as I discussed in a previous blog post. In this podcast Bob Martin talks about an issue Joel Spolsky raised with him on the StackOverflow podcast #41.  An extract from the discussion from the StackOverflow (SO) podcast #41 is given below:

Spolsky: Bob, can you explain again the Single Responsibility principle? Because I don’t think I understand it right.

Martin: The Single Responsibility principle is actually a very old principle, I think it was coined by Bertrand Meyer a long time ago. The basic idea is simple, if you have a module or a function or anything it should have one reason to change. And by that I mean that if there is some other source of change… if there are sources of change out there one source of change should impact it. So a simple example, we have an employee, this is the one I use all the time…

Spolsky: Wait, wait, hold on, let me stop you for a second. Change, you mean like at run-time?

Martin: No. At development time.

Spolsky: You mean changes of code. There should be one source of entropy in the world which causes you to have to change the source code for that thing.

Martin: Yeah. That’s the idea. Do you ever achieve that? No. 

Martin: You try to get your modules so that if a feature changes a module might change but no other feature change will affect that module. You try and get your modules so partitioned that when a change occurs in the requirements the minimum possible number of modules are affected. So the example I always use is the employee class. Should an employee know how to write itself to the database, how to calculate it’s pay and how to write an employee report. And, if you had all of that functionality inside an employee class then when the accountants change the business rules for calculating pay you’d have to change the employee, you’d have to modify the code in the employee. If the bean counters change the format of the report you’d have to go in and change this class, or if the DBAs changed the schema you’d have to go in and change this class. I call classes like this dependency magnets, they change for too many reasons.

Spolsky: Is that… how is that bad?

I kind of feel the same as Joel with this one and I’m afraid that Bob is not really convincing me here. Why? Let’s pursue an example for a second.

Suppose that I’m creating a class that outputs a file. In this class I extract data from a database, convert various bits of the data, then output this data to a file. So how many reasons has my class got to change? Well it looks like 3: the database can change, how I convert the data can change, and how the file is output can change. Hence according to the S in SOLID, each of these operations should be contained in a separate class. Let’s just remind ourselves what the S in SOLID stands for:

A class should have one, and only one, reason to change. [1]

Now if I am forced into making changes to either the database, data conversion, and file format, I make the changes to my class. What is wrong with that? I just compile the project again and distribute the binary. Simple. I can’t see any benefit in breaking this class up into 4 separate classes, there just seems no point, but according to the SOLID principles there is. Arguments from Bob like “Yeah. That’s the idea. Do you ever achieve that? No” are nonsense. It clearly undermines the need for such rules in the first place. There is no point having rules if you are not going to stick to them. Fudging a rule every time it doesn’t fit your argument implies that the rule doesn’t make sense in general.

The discussion in SO #41 then moves on to the WordPress plugin system where Bob comments on how having independent plugins are a great example of the single point of responsibility (I must stress it was not Bob’s example, he just went with it). Eh NO. I think that it sometimes becomes easy to forget what the S means. Let me just state it again: A CLASS should have one, and only one, reason to change. The plugin itself, which is represented by a class, may have lots of reasons to change. Again in the subsequent Hansel Minutes podcast Bob uses the term module, in the sense of say a jar file in Java or a dll in .NET, to describe building a set of components that adhere to the S in the SOLID principles. This is once again deviating away from the actual meaning of S.

OK, am I being pedantic about the definition? I don’t think so. If it doesn’t mean what it says, then change it; there are people out there that will follow these rules blindly, and having such a specific definition only encourages this.

I think a far better rule would state that a class should only be responsible for a single task, in my example that task is creating the file. This is completely different from a class that has only one reason to change. OK, it’s a lot less specific, and maybe harder to judge, but any decent programmer will have a feel for what a task is. Not only does this seem like a more sensible option, it’s what the plugin and the module argument ostensibly encourage. It seems to me this is the only true generalisation you can extract from Bob’s arguments and I think it would be much better if this is what the rule suggested.

Don’t get me wrong, there are times when you want a class to only have one reason to change, this is especially true when you are developing a framework where the source code is essentially immutable to the outside world, in this case class design becomes far far more important. However the SOLID principles are intended as a set of rules for every programmer to use, and as it stands, I’m sure that the S is causing more confusion, code bloat, and misguidance than it is providing benefit to those adhering to these rules.

Having rules are a great idea, but they also encourage people to follow them word-for-word. It’s easy to say they should not be followed religiously, but I’m sure that is what is expected. This coupled with the developer with poor judgement, little experience and lots of blind faith, can leave us all wondering why we are even entertaining all this.



the so SOLID principles

Year after year programmers find themselves faced with a new set of acronyms and principles that dictate the ideal way to develop software. After 10 years in this game it gets rather tedious and tiresome. The problem is you can’t let your guard slip with this stuff, because if you fail to listen, you may fail to find a job.

I have been meaning to write about this since the whole Joel Spolsky vs Uncle Bob debate [1][2]. As it happens, Jeff Atwood beat me to the punch with his article “The Ferengi Programmer“. However, there are a few points I would like to address with regards to the whole acronym waving brigade.

First, let’s look at the SOLID principles. Do most good developers not use a relaxed variant of these things anyway, and have done so for the last 10 years? It seems like we are creating a set of rules for the dumb-ass programmers to follow because they can’t figure out for themselves what is good and what is bad. The problem with this approach is that the average dumb-ass programmer will not even know or attempt to understand the principles anyway. They will just keep typing.

Where does this leave the good programmers? Well they may find themselves trotting along to a job interview and one of the questions they are asked is: “Do you use the SOLID principles when writing code?”.  This person then responds: “What are the SOLID principles?”. Often the interviewer will then disregard the candidate and in doing so may be throwing away the chance to work with a great talent. OK, you may say the interviewer is a dumb-ass for disregarding someone for this reason alone, but then again, I bet you can think of several that would. I’m certain there are people I know who are not aware of the SOLID principles, but who I think are awesome developers.

My problem with all this is that we shouldn’t automatically disregard someone because they can’t state the SOLID principles or that they are not using TDD (oh yes another acroymn), BDD (and another), and DDD (and ANOTHER). God, are there people sitting at their workstation trying to figure out how to squeezing every-single-one of these things into their development cycle. I would bet you quite a bit of money that there is. These folk must get NOTHING done because they are spending so much time trying to do the “right” thing. The consequence of this is that they fail to write code that actually implements ANY functionality. It seems like it is no longer enough to be able to write good software. You also have to know all the latest buzz words. This is sad.

However, despite my reservations, I find myself thinking why shouldn’t we allow “bad” developers to become “good” developers? Is it rather patronising to say otherwise? 

What we all as developers should watch out for is the developer that accepts all these rules blindly, and applies them to EVERY situation. I’m all for writing code the correct way, but we also must be careful how we judge fellow developers.

developing software nobody wants

Developing software that nobody wants is a classic mistake.  Joel Spolsky once said that if he had listened to what his customers wanted, and created a product with only their suggestions, they would not have came up with as many nice features (I paraphrase from an episode of the stackoverflow podcast). However, maybe his logic is slightly skewed. Why? Well he is developing a product for software developers (FogBugz). Therefore, his target market is essentially the same people who are writing the software. This makes developers a great source for feature suggestions.

However, consider on the other hand the average software developer. They are not creating a product that is used by other software developers. Instead, customers can range from a highly technical audience (say Matlab), to a secretary with little computing knowledge. Clearly if we are creating a product aimed at the latter market, a software developer is the last person you should be asking for feature advice.

Unfortunately, misaligned product requirements actually happen in the wild. I have been involved a project that forced a user into making around 10 clicks to achieve a particular goal. Each step was valid, and allowed the user fine grained control over a feature. However, the user didn’t need this level of control, and they simply selected the same options every time. There was great difficulty convincing most of the developers that this kind of fine grained control was not required. Thus: developing software without thinking about how a customer is going to use the software should be high on the list of UNFORGIVABLE sins.

Some problems, like the one described above, are hard to grasp for us programmers. As programmers we are taught to generalise, and I think we find it difficult to turn this off in our heads. This can be seen in many applications that drown us in XML configuration. Product managers, and CEOs have less room for excuses.

So how do we ensure that we are not developing software that nobody wants? It just seems obvious to me that you have to ask the people that will be buying your software. This seems so simple right? Can you even believe that it doesn’t happen? Is it beyond the realms of possibilities that somebody, somewhere, is developing a piece of software for a market without asking that market the features that they want? You’d better believe it. It happens all the time.

the secrets to obtaining a happy programmer

The ideal working environment for a programmer is an topic which has received considerable attention. What we (programmers) normally idolise after are, amongst other things, (multiple) large monitors, Herman Miller Aeron chairs, private offices, break-out rooms, and, of course, the best tools for the job. Joel Spolsky, the Godfather of programmer satisfaction, went even further and gave us the Joel Test for assessing a prospective employer. However, are the above all that it takes for programming nirvana? Probably not.

First up, I would love to experience an environment where each and every one of the things mentioned above was in place. However, in my career so far, I have yet to work in an environment where these things have been par for the course, and maybe I would be content with such a work environment. I’m pretty sure I wouldn’t though. Not because these things aren’t good but there is a vital ingredient that can make these things irrelevant.

So what is this ingredient? Well it’s FUN, or lack of it. Yes a fun workplace! I’m sure there will be those out there that think work isn’t supposed to be fun, well ask yourself why. Fun doesn’t necessarily mean that no work gets done – the contrary in fact. It’s a place where like minds can sit and create and innovate about things they find interesting. Now here is our first problem.

Essentially fun is the environment combined with the people. However, all too often we find ourselves in an environment where the people are not like minded. What surprises me most is that in an office full of software developers only a handful (or less) may be genuinely interested in software development. I’m not sure if I have just worked in the wrong places – however friends have confirmed a similar problem. It’s not simply that you couldn’t sit and talk to certain individuals about software development, it’s that you pretty much had difficulty talking about anything. It was often like talking to a baked potato.

For me this not just a job, software is one of my top three interests (along with music and cycling, for those who are nosey 😉 ). Wouldn’t it be nice if an employer could respect this – I’m not saying they all don’t, but most don’t, it makes it easy to see why Google attach such an importance to their culture.

All this is not to say that I think we should all be the same, it may be the case that you have to turn good people away because they simply don’t fit your culture. I think the culture is that important. This has been shown in the past by the likes of Richard Branson whose music empire started by providing an environment (in essence a community) where both the employee and consumer found it fun to gather in his record shops. Certain universities have also found this valuable over the years.

So essential we can have all the goodies we like, but unless we are working with people that are Smart and Gets Thing Done (or preferably Done and Gets Things Smart), and fit our culture, then maybe we are never going to reach our programming nirvana.