Sunday 19 July 2009

The difference between craftsmanship and engineering in software development

(Inspired by Jeff Atwood's latest post about Software Engineering)

Definitions:
* Craftsmanship
* engineering
* Software Engineering

Instead of commenting on Jeff's article, I would like to give a real engineer's view on software engineering. I usually say, that a craftsman can be good at creating something that is similar to something that has been created before, in good quality. An Engineer can create something that has not been done before, and predict how long it takes and predict how it will work.

If we look at software development, is it often possible to assign each part to one of two types:

* Doing something that is easy to specify and/or predict (designing a GUI etc.)
* Doing something that is not easy to specify/predict (research, unknown territory)

If things are relatively easy to specify, you can do calculations like "100 forms of each n hours = 100*n hours". This will be a calculation with some uncertainty, of course, but it gives you a good idea of the size of the project. If the tools and methods are well known, you can illustrate the predicted result to others by showing them similar applications. Good craftsmanship is needed for tasks like these, and these processes can be measured easily using metrics, quality is easy to measure and control.

If things get hard to predict and/or specify, engineering starts. Then you need models, knowledge about how things work, knowledge about many options, ideas, and all the other things that we know from traditional engineering. This is also where architecture comes in - and I prefer the definition of architecture as "The decisions that we make early".

When doing Engineering, the skills and knowledge of the central decisionmakers can make a huge difference. This is where the productivity difference between two "programmers" can become more than a factor 1000 - and where wages differ a lot. QA, QC, metrics etc. are usually difficult, and the lack of predictability can be bad for a big organization's ability to cooperate. If marketing needs to prepare a big launch, they need to know when the product is finished.

A project can choose the craftsmanship path by picking an existing development platform, so that all components of a software product can be produced by craftsmen. This is usually preferred by large organizations because it is predictable and well documented. It may also be more expensive, but in the overall budget, that is less important.

The Engineering approach makes sense, if the product's specifications are not met by any existing platform, or if the software project's costs are significant to the organization. This does not mean that engineering can make your costs lower - it means that sometimes your costs can be lower using engineering.

So, what is good engineering? Basically, making the unpredictable predictable, making things really cheap, and delivering what is wanted. What do you need to know in order to do that? My list is this:

* Knowledge about computer hardware, network, programming methods, abstraction methods
* Organizational theory, management knowledge, psychology
* Mathematics, statistics, economy
* Decision theory, risk management, training in using the scientific method
* The knowledge of the users of the product (!)

You don't need all this knowledge in one person, but the combined knowledge is needed in order to achieve good engineering.

11 comments:

Jolyon Smith said...

I haven't read Jeff Atwood original piece that you link to, but for me the distinction - in the software field - is somewhat different, because in other fields you would not consider different practitioners to be either engineers or craftsmen, but one or the other.

A cabinet maker is a craftsman, for example. Nobody would consider a cabinet maker to be an engineer.

Similarly a bridge builder/designer is an engineer. Nobody would consider a bridge builder a crafstman.

But in software we are able to make the distinction, and I think the reason is to do with philosophy.

A Software "Engineer" makes functional pieces of work. They meet a specification, they satisfy some need and they get the job done without fuss or bother.

A Software "Craftsman" on the other hand will produce something that goes beyond the specification. That may in terms of anticipating requirements that the commisioner (user/customer) of the piece did not even realise they had, or interpreting the TRUE requirements from the stated requirements. Or it may simply be that the implementation is more elegant than it needs to be (to get the job done) with the hope that maintenance will prove easier/more efficient/more reliable in the future.

The key characteristic missing in "engineering", in *this* distinction, is "imagination" or "creativity". Thinking outside the box.

An engineer takes a bunch of inputs and produces an adequate output.

A craftsman goes beyond the limits set by the inputs.

A software engineer provided with inadequate inputs has no hope of producing anything worthwhile.

A craftsman in that situation has a much better chance. ("CHANCE!"... I do not mean to say that a craftman will always produce better, or even always correct, results).

The trick when dealing with a craftsman is to ensure that the KEY inputs at least are respected, but not to constrain them so much that the invalid inputs are adhered to despite the recognition that they ARE invalid.


And again, software is a pretty unique field in comparison to any other field in which "engineering" applies, because of the way in which those inputs (requirements) are either poorly stated, poorly understood or just plain not present.

No-one would ever contemplate building a bridge without first identifying and clearly stating the requirements down to the tiniest detail.

It's the engineers job to find the solution/implementation that fits within the constraints of that highly specified system; to "engineer" the solution; take the requirements and embody them in some real device or structure.

Software is rarely so highly specified and more often is utterly inadequately specified.

In those cases where it is, you can call yourself a Software Engineer if your job is to make something that is no more and no less than a complete, faithful embodiment of the specification.

If you are required to do anything else - that's NOT software engineering. It may not be craftsmanship either, but it isn't engineering.

Not imho. :)

Lars D said...

One of my favorite sparring partners regarding software engineering, is a guy who is responsible for major construction projects, including office buildings, parking garages etc. His problems and the stuff he does on a daily basis, is almost identical to the work of a software engineer.

Many people think that software engineering is special - it's not. It's just another kind of engineering, that happens to involve computers.

Eric said...

The main difference IMHO is that in other fields, craftsmen and engineers have very different tools and work habits: they're easy to distinguish, even to those that have no knowledge of the field.

In software, they both work indoors and use computers ^_^

I agree with Lars, things are very similar in software, but even those working in the field ofttimes fail to grasp the differences (which they then attribute to other factors).

NMI said...

Well a programmer can consider himself/herself an engineer or craftsman depending on the job at hand. I think the problem always comes when somebody wants to consider themselves one or the other, but in reality programmers are almost always a bit of both, some more engineers than craftsmen, and some the other way round. Although most want to be considered "engineers" I think because it sounds cooler :)

Most software projects requires an element of both. When I'm doing highly technical backend work (for example a specialised reporting engine, db replication engine, a complicated syntax parser or specialised scripting language/engine, etc.) then I consider that 'engineering' as alot of that work requires alot of low-level thought & planning and using efficient algorithms, etc. And sometimes have to think back to the theory that I learned at University.

However when I'm designing User Interfaces or writing HTML then for most part I consider that craftmanship... I know many html designers that can create beautiful web user interfaces but might suck at writing code effectively. Those people are more craftsman than engineers.

I don't think there's a clear answer, and depending on the type of job you might need to be more one than the other, but to be a good programmer overall I think you need to be a "engineering craftsman" :)

Lars D said...

Others have already defined Engineering and Craftsmanship, so that we don't have to spend our time on that. That's why this blog post focuses on cost structures and organization.

Anyway, it is actually possible to graduate as a Software Engineer from many Universities - and no, it's not the same as a Computer Science graduate.

Anonymous said...

"Software" engineers only build one sample of anything, say a Pharmaceuticals testing tool, without knowing anything about medicines, then it gets copied and distributed. After that, they move on to the next project, say for a bank, without ever having studied banking. In other words, the domain skills gained in the pharmaceuticals project are largely lost.

Software engineers are also constantly having to use new development tools, new 3rd party libraries, databases, maybe even a different OS. In other words, even many of the basic tools skills are lost, instead of experience being gained.

Imagine a hardware engineer that builds the world's first bridge, which then simply gets copied and distributed as more bridges are needed. Then the hardware engineer goes on to build the world's first and only aeroplane, which gets copied and distributed. Then getting a job to build the oil tanker.

They won't be very good bridges, planes or tankers, will they? Lotsa maintenance? Yup.

Yet they're all made with the same basic materials, and the same math regarding metal fatigue, melting point, etc. applies; right? And bolts, welds and rivets get used in all of them, so what's the problem with this hardware engineer? Is he an idiot or something?!?

Well, that's what software engineering is all about.

We are little more than bricklayers building a factory without understanding the machines it will house, using bricks and mortar that regularly change, on foundations that constantly mutate, with instructions from clients that know what the factory must produce but have only a vague idea of how a factory needs to be structured, and they nevertheless want to know when you will be finished and how much it will cost.

Lars D said...

@Anonymous: There is a huge difference between a self-proclaimed Software Engineer, and a qualified one. A qualified Software Engineer is not necessarily writing source code. I would even continue to say, that a qualified Software Engineer rarely builds something alone, and sometimes isn't doing anything that relates to normal Computer Science.

Warren said...

Software engineering isn't "special" but it *IS* different.

I know a lot of engineers that are wonderful at their engineering disciplines, whether they are civil, electrical, electronic, or computer engineering.

But I know zero engineers that I also consider top-tier software developers. That is to say, I find their abilities in software to be significantly below my expectations.

The vertical markets where I write software are heavily populated with scientists, and engineers. I find that scientists bring their methods and tools to the software table, and contribute some great things, but also have some weaknesses. The same is true of the people with pinky-rings.

I think arguing about the difference between "software engineers" and so-called "software craftspeople" is fruitless. One person likes the one term better, perhaps it implies a certain gravitas. Another likes the other term better, perhaps it implies a certain Stradivarius-like quality. Engineers create widgets, and understand their failure modes. Craftspeople create masterpieces. Oi! Gimme a break.

Software is similar in some ways to other disciplines. You have to know enough math, and understand enough of the basic principles of logic, and the organization of large projects involving a lot of complex tasks. Okay, okay, it's like engineering. But you also need a craftsperson-like ability to continuously refine your own processes until you have developed a set of development processes that work well in the environment you are in. This is the craftsperson analogy, in a nutshell. A craftsperson is someone with a deep understanding not only of materials sciences (think engineers) but also the daily grind of using the tools (think craftsperson).

It's about BOTH, people. BOTH. Why do people do this EITHER/OR thing, anyways?

Warren

Warren said...

Cynical response; "Qualified software engineer?". A guy with a cooshy job, hands-off the code, buddy. I just do documents and meetings, participate in team-based development processes where its impossible to measure my results, and I get paid more for it.

I call that a righteous gig.

:-)

Lars D said...

@Warren: It's sad that you haven't met one of the many splendid Software Engineers out there. I can give you two examples of Engineers from the same Engineer University that I graduated from: Anders Hejlsberg (Delphi, C# but didn't have time to graduate), and Jakob Nielsen (useit.com).

Just like you, I don't want to discuss individuals and I don't want to take part in the discussion Engineers VS. Craftsmen. It's not one against the other, and everybody is doing some of both.

However, as a project manager, you have a choice about how much you want of each. If you want to create an inventory system, do you customize an existing system that was created for this purpose, or do you write it from scratch?

It is that choice, that I want to highlight, because it affects your cost structures, your interaction with the rest of the organization, and many other things. Also, when we understand the definitions of the words that are used here, it is much easier to argue for one or the other solution in the planning phase.

Also, if you are doing mostly craftsmanship, what can you do to become better at software engineering? It's not a secret, and almost every engineering university is willing to help you out. Of course, you can also opt for the more specialized Computer Science path.

Lars D said...

When I compare Software Engineering with Construction Engineering, I see so many similarities, it's striking. You need to make good decisions early, or the "foundation" will not hold. Simple specs are often difficult to implement, for instance, putting a Window into a wall may have a lot of dependencies on building stability, climate shield, costs, supply, schedule etc., and a single feature in a building can bring everything to a standstill. Budgets are relatively ok if you are building a standard building in a standard location, but as soon as something gets non-standard, everything is a mess.

If the office building is going to be built in the city, you cannot use normal transport mechanisms, so everything gets more complicated. If it's close to the water, you need to pump away ground water. If the buildings nearby will sink by doing that, you need to keep a very steep water wall, which delays stuff, introduces dependencies, and consumes project management hours. Then, somebody may make a mistake, flooding everything, and your schedules are gone again. Once the foundation is there and the building starts going through several floors, you may find an fault (bug?) in the concrete. What do you do? Rebuild (rewrite?) or patch it? Will the patch just conceal that there are more problems, or should you look deeper into it?

Well, since there are multiple parties involved, let's involve an issue tracker. Every fault that you find in the building, is put into an issue tracker. In order to do quality control, everybody has to handle these issues in a well defined process. This slows down things, so that an important fault/bug can take days to handle... slowing down other parts of the project.

When the whole building is ready, you need to test it. Well, you cannot get quality by testing, of course, but you still have to test it. The best would be to do continuous testing of each single part, but a final test is good. You review a lot of things, pressurize the building to test the climate shield, do camera inspection in the sewers, flush things etc. Escape routes must be efficient, and firewalls must be in place in the right places. Electricity must also work correctly. If the tests fail, you need to bugfix it before the building is finally released to the public.

After some years of running this building, with ongoing maintenance, they're ready for an upgrade to building 2.0. The basic architecture is kept, maybe with some changes, but everything must look new.

In the old days, building were often designed, built and tested. Now, more and more buildings are built using agile methods, where the basic decisions are made first, but where many decisions are made during the building process.

All this is Engineering.