Over on Reddit teval takes me to task about my last post:
Yes, code monkeys try to bang out code as quickly as they possibly can. This is quite terrible actually; with very little amounts of work and thought one can come up with a nice and clean decoupled solution that will be much easier to maintain, extend and above all fix. Look at how many projects fail due to bugs or the fact that minor changes are impossible! It's all this guy's fault, well.. and people like him too. Changing requirements? No problem, the code is trivially easy to modify. New people on the team? Sure, they only need to know about their area of the code since everything else interfaces with it cleanly, so it's easy to get them started.
Yup, the task is to give the user something that then the user can expand upon. But the answer here isn't to do a crappy job quickly, it's to put a bit more work upfront and then be able to make changes very quickly. The time to the first prototype is very small compared to the final release; why is there this obsession to optimize the time for the minor part and not the major one? And above all to look terrible while you're at it. This guy should be happy that users tolerate incompetence on this scale, I'm hoping one day they'll stop.
I agree with many of teval's points. In fact the only ones I don't agree with are the ones where he blames me for problems in other's projects.
So, let's be clear here. When I talk about computer science and software engineering I'm talking about the difference in approach that is needed for the case where we know the detailed specification when we start a task and the case where we don't.
When I sat down on Friday night and decided to knock up a general use C++ component to do natural sorting I was using computer science techniques. I knew before hand exactly how it had to work — what the correct results were — and I also knew the structure of the interfaces that it needed to follow in order to be usable as an adapter within the existing C++ standard library. I knew exactly how to go about breaking the string into sections and I could deduce exactly how the comparison needed to work because I could derive that from the specification of how the final sorted list should appear.
Let's imagine for a moment that I was responding to this as a bug fix or as a specification as part of a new system.
The system must sort the product lists properly on the product catalogue pages.
It would be reasonable to interpret that as a request for a standard computer sort, what is normally called ASCIIbetical.
With my Agile hat on I would put the working program in front of prospective users and the specification writers and check to see that my team's understanding of the specification matches their understanding, and just as importantly, look for deficiencies in everybody's understanding of what the system ought to do. Knowing software development costs I would want to get this in front of users with the minimum amount of code written because the less code there is to change the cheaper it is to change it if there is a problem.
I might get to hear something like this,
Look idiot, the ten pack has to be listed after the five pack. It's bigger. What's wrong with you guys!
At this point we spend some more money to do a more complex search. If this requirement appears in more than one or two places then we generalise the solution to make it as cheap to use wherever we want it as the normal sort is.
Now comes the million dollar question: What should the code look like after we've done this process?
The code should look exactly the same as the code I wrote with a detailed up front specification.
If you're using poor specification as an excuse to deliver poor code then you are doing yourself and your customers a disservice — that isn't what the goal of the process is. You use different techniques to derive the same high quality code!
Clearly the second approach is more expensive than the fist. Using a detailed specification meant I could write the code quickly and efficiently straight away rather than having to arrange meetings, package up a system to show off and collect and disseminate a ton of paper work to detail how I've been spending the customer's money.
Clearly the first approach is better to use whenever and wherever we can, but in the real world, with real users and real specifications that level of detail just isn't forthcoming. That is why we have developed this whole other way of writing software.
But there is likely one big difference between the code that the two approaches would give. The Agile software engineering technique will make a larger and more complex solution. Why? Because some user will also say “Why aren't the dates in the product names in the right order?” and we'll have code that solves that too.
The assumption is that there is inherent tension between computer science and software engineering, that you can't be both a software engineer and a computer scientist. That's news to me. Software engineering is a huge area in computer science.
Daniel Lyons also talks about the difficulty of finding the specification:
The uncharted territory is problem definition itself. This is what computing science has taken for granted, because sorting and searching are intrinsic and easily defined problems that require interesting solutions that vary only by how. This is also why “real world” programming is such a hassle—most of your time is spent defining the problem/solution space rather than working on the solution.