To design or not to design
I just read Joels new article
and started on reflecting how (and if) I design. I must admit that I have very little expereince using UML or other graphical ways of modelling like ER-diagrams. When I had to use them, for university, say, or because some manager wanted us to do so, I found them clumsy and artificial and they never really let me put down the things I found most important about my design. My reluctancy to design before I started coding came mostly from that fact.
When I read about Xtreme Programming, one of the things I liked best was the idea to design via sourcecode. The idea is NOT to code without thinking first. The idea is rather, to put your thoughts down in a language that is easy to use and comprehensive to you as a programmer. As a C++ programmer, to me that is: design your classes by writing the public class definition, the interface if you want. Design your functions by writing the function header and the brackets and then fill the body with TODO comments.
If you have to talk about the design to non-programmers, they will need a little help understanding what you are doing, but it is my impression that they will need the same help understanding UML diagrams. With a little explanation everyone can understand class headers and comments written in plain English (or what ever is your commenting language). To make it easier to understand interaction between classes, print out your headers and arrange them on a whiteboars, draw arrows from one to the other.
The other thing that makes design very hard to do (at least for me) is, that you often do not know what is actually needed until you built something and the user complains that this is not the right thing. All the design in the world cannot really remedy that, because in most cases the designer/programmer is not the user and has never done the same tasks the user will be doing with the software. Xtreme Programming tries to tackle that problem via prototyping and having a customer on the team.
As soon as you agree to the point that you might not know what is really wanted when you start, you have to admit that you cannot design all the way though and then implement all the way through. Therefore you will design and then code and then design again and then code and so on. And then you will have to change code that is already there. Even if you thought you had a solid design all thought through on the start, you will later end up changing things in it. So be honest from the start and try to code in a way that embraces change (this is beginning to sound like a book summary of Xtreme Programming explained here).
I just felt like I had to back up Kent Beck and his fellows here a little bit, because Joel made it sound as if Xtreme Programming meant no design at one point. To me, if there is really one thing reading "Xtreme Programming Explained" changed about my way of working it is the way I design my work. Design just means: Please, think before you do. And this thinking can be done in any "language" you are comfortable with: Diagrams, paper notes, cards, sourcecode, plain text...
How do you design? How do you put down your design and communicate it to others? How fixed is your design during the development process?
Wednesday, March 6, 2002
I'm not a developer but I have been involved in testing and specification in a couple of companies.
I don't buy the XP idea that having a customer on site is going to help for anything but understanding the broad details of the business process.
(a) The customer doesn't understand technical issues.
I lost track of the number of times management have insisted on doing something a certain way which is bad, sub-optimal or makes no sense (I'm talking about implementation details here, not the business process).
I have seen a manager dictate that a database field *had* to be called 'ACCOUNT_BAL' in an application where that could mean about a dozen things. A minor point, but it just served to confuse developers and hinder communication.
If you present a typical manager with the 'File Open' problem, chances are they would not be able to think it through. They'd pick the first thing that came into their head, defend it because it was their idea, and it would only get fixed 6 months down the line.
If your onsite customer is a lowly user, management will probably dictate stupid things over their head anyway.
I think the best thing is to have a fairly detailed spec/design for things which really matter like business processes. For things like file dialogues, the customer won't even see them if you get them right, but will probably screw them up if you let them get involved.
(b) *Even for business process decisions*, the customer won't be able to handle too much detail.
Say you have to implement a program that checks a remote account balance daily. I have had senior managers who would decree how it had to be done based on wrong technical assumptions (do they send us all transactions or just the balance) and with no understanding of issues that programmers are used to thinking about - e.g. what if the link is unavailable? how can we automate the process so someone doesn't have to come in at 4 am to press a button?
Don't get me wrong, figuring out what the customer wants is crucial, but for the particular kind of thing Joel is talking about (the niggly details), it's not helpful.
Do I sound at all cynical here?
Wednesday, March 6, 2002
A problem I've seen with "design via source code" is that some developers get too focused on the local rather than the global issues when they do this. They'll get half a dozen classes blocked out that work together, but don't see that this little clump of stuff won't work well in the overall plan. Development seems to work best to me when there's some sort of overall plan to begin, even if it's just a few iterations of top-down splitting the application into high-level modules.
Wednesday, March 6, 2002
> How do you design? How do you put down your design and communicate it to others? How fixed is your design during the development process?
Design is a broad word: design the functionality of the program (i.e. agree on functional specification, what the program is supposed to do); detailed functional design (what exactly does the user want to see .. what input and output, log format and log medium, all the control points); UI design (exact behaviour and appearance of the UI to implement this functionality); data design (SQL schema, XML or data protocol); system design (interaction with other components, like SNMP or drivers or IIS or whatever other pre-written software you must interface with); 'process' design (staffing, scheduling, getting the development resources, development process like version control); functional (black box) test case design; design with maintenance and evolution in mind (do we design this to be portable); design for performance (reliability, throughput, scaling, making it distributed and will that be for LAN or WAN).
All of the above are 'design' issues beyond the software internals -- they're good and vital and I wouldn't want these design decisions to not exist, and I'd prefer if possible for them to be designed UP FRONT (though if it's a 10-year project/product even these are certain to 'evolve' instead of being 'created').
Then additionally there's the software's internal implementation design (how do we implement this, using intercooperating processes, classes and so on). Even there, some design issues are more systemic, orthogonal to any single class: for example, will classes in this system expecting to throw and catch exceptions, or use return codes; VB or C++; what is our logging mechanism. This aspect of the design is /relatively/ less important ... it's 'only' an implementation detail, the kind of thing that you can leave to the developers' discretion (once you know which developer it is, which implies high-level system partitioning into modules per team). Within the software design, you have major and minor interfaces. Major interfaces, e.g. where you have 2 or more teams, each writing a 'component' which must interface with other components: these interfaces should probably be /formally designed/ up front (design and document the interface, and 'test' it e.g. by verifying/inspecting that it supports the functionality required, passes all the right data and control, for example if we're expecting some datum from another component, then do we see this datum in the interface between our components). Minor interfaces OTOH, like when I alone write one component by implementing several classes, then what are these classes and their intra-component interfaces ... nobody but me cares or need care, and I don't need to (though I may) choose any particular design (5 classes, or 6 ... refactoring makes that fluid and not cast in stone), and any process (waterfall or spiral) ... of course even these minor design decisions matter and I should at least for my own sake make them well, but if major interfaces are good then the worst case is that my implementation is swapped out (scrapped and rewritten) which isn't as bad as a flaw in the whole system.
The hardest (IMO) part of the design is the first part: what should the software do ... there I feel I really /need/ help: input from my employer (or customers, or salespeople, or end-users). Also the second part (what are the constraints, performance, choice of O/S, interaction with other software). The rest seems relatively less important to me because I'm more confident at being able to meet the requirements, once I know the requirement, without external help (without my/our interfacing outside the development team).
Re how to design and communicate requirements: 'any way you can' ... it varies on the technical expertise of who (e.g. customer) you're talking with and the level of interest that they have. I /DON'T/ like it when someone writes the specs without my help and then throws the specs over the wall to me expecting that their specs are finished and understandable and useful /TO ME/ (which they /must/ be), as if they were Moses giving me 10 Commandments engraved in stone ... because I might find their specs ambiguous, missing IMO essential detail, or silly (silly eg because they don't fit in with my understanding of the business need). I /DO/ like it when I have opportunity to give and receive feedback re. the specs: I'd ideally want their agreement re any algorithm that's visible to the end-user, so I might write the detailed description of behaviour as I see it and ask them to OK it or to modify it ... /my/ specs are at the level of detail that I find sufficient to begin internal (implementation) design without their further input: these specs will be in english text, probably written and not verbal unless it's a very small piece of work for an 'internal' customer such as my boss in the cubicle next door, as opposed to a customer in an external organization.
For internal design I chat with team members, maybe agree on internal class-level interfaces either orally or using (version-controlled) C++ headers.
I find my way of doing things appropriate, naturally (or I wouldn't be doing it). I'm aware that what I do seems appropriate /here/ and maybe wouldn't in a different context. For example, the context here is: salaried employees, not contractors; long-term employees (little staff turn-over, with virtually no turn-over of the most senior developers); a long-term product (started 10 or 12 years ago), with 100s of KLOC.
That it is such a long-term product makes your question re. "how fixed is your design" either impossible or trivial to answer: the oldest line of code still in production is I guess only about 7 years old; almost everything gets swapped out (rewritten and replaced) as the corresponding functionality is upgraded to meet new requirements.
But that's just here. At previous employers I/we did things differently: e.g. because the staffing context was different, and in the end the design is for the people involved.
Wednesday, March 6, 2002
I am just wondering where everybody got the idea from that XP suggests "design by sourcecode". I have done XP now for some time and read alot of material about it but have not come over this specific principle.
XP is suggesting to do the "simplest design possible". However you need to remember that most these people who have created XP have done OO for more than a decade. That means that their definition of simple is different then ours. So, for example, a MVC Pattern for a GUI might be the simplest way to solve a certain problem, then you should implement that.
So XP is not about not thinking about design, it is actually about even thinking more about which design you choose because this design should always be the simplest.
I think that "design is not important in XP" is probably the most misunderstood principle of XP since the design experience of the creators are so different than the design experience of the audience.
So I think that Joel did a good job pointing out that you cannot do without design.
Wednesday, March 6, 2002
Design can also mean a 20 minute brainstomring session, followed by a quick test of how easy something is, followed by a time estimate. For something the size of the file open dialog issue Joel discussed, it sounds like that is what happened (at least in Joel's head). Very XP if you ask me.
Wednesday, March 6, 2002
> I am just wondering where everybody got the idea from that XP suggests "design by sourcecode". I have done XP now for some time and read alot of material about it but have not come over this specific principle.
Ok, I think I put it wrongly. Of course you do not design in sourcecode. You do not design in UML either. Hopefully, you do design in your heads. It is just that you have to document your design in some way (at least, if it is supposed to be worked on by several people and over a longer period of time). For this documentation XP suggests to use just the sourcecode it produces (if I remember rightly that is, I cannot look it up at the moment, a guy from product management borrowed our XP explained copy).
Thursday, March 7, 2002
There are many audiences for design (or for "whatever it is that's produced during the phase we call design"). Only some of those people are programmers. Most of them might not be, and so tools like UML are often used as ways for programmers to intimidate other groups by making everything a technical argument.
Of course, there's only one audience during the program design phase, when programmers are doing something before writing code. There are as many ways of approaching this as there are programmers. I think it's a pretty damn stupid idea not to actually write down on paper what you intend to do and roughly how you'll do it, but I suppose that if you write wonderful clear explanatory code and comments, then perhaps no one will ever question your approach.
Thursday, March 7, 2002
Don't forget the key concept in XP : 'Write unit tests first.'
When deciding on your unit tests you think:
I have to test for this, and I have to test for that.
You have to stop, and think about the different situations your code might encounter without actually writing any code.
This means that you then now that you must code for this and code for that.
The 'Write your test first' policy does not just lead to get testing, it leads to good design.
Thursday, March 7, 2002
I took a couple high-falutin software engineering classes. Real pinkies-out IEEE documents, UML diagrams out the ears kind of stuff.
The most important thing I learned from those classes was that if I couldn't solve it on paper, I wasn't ready to start coding. Every place a state diagram showed a magical change from A to B was a signal I had more thinking to do.
Friday, March 8, 2002
Joel's example about the File-Open Wizard reminded
me of the problem of over-specified requirements, not
the problem of an under-designed implementation. In
many companies, the decision to have a wizard for the
file-open would have been made in some product
marketing group, and this individual "requirement"
would eventually land on the desk of a programmer.
This programmer would then typically grumble a bit
about the difficulty of the task, but would slog through
it anyway "because that what the spec says".
So the moral to the story, when I first read it, was to
define the problem, and to suggest the solution. But
not to force a particular solution into the spec. Design
then leads to a choice of whether a wizard is worth
doing, or if some other approach would be better.
Monday, March 11, 2002
Fog Creek Home