Today I was thinking about software engineering. Ok, I should say, “The process that real world software gets written with”. I’m in the camp that thinks Software Engineering is a poor choice of words. Software is more a lingual art than an application of principles. Engineering implies that you have some principle, you apply it, you get a product. Bridges are engineered.
Software is totally different. So I hope anyway. The big difference is that the principle is different — software is really a bunch of “Let’s try X and see what happens”. Which brings me to my thoughts on this. Software shouldn’t be engineered. More-over, the engineering concepts embedded in the Software arts should be shown the door. Software is an Art. It should be called Software Artistry. Software is more like sculpture, painting, or writing than bridge building. Not to say some components aren’t more like bridge building — some are. But those times should be less frequent and more obvious… If there’s no user other than another developer, then it’s bridge building. If there is an ordinary end user, it’s art.
The difference between “bridge building” style software engineering and “sculpture” style artistry is scale. Software engineering often uses large-scale processes where small scale processes would work better. It’s far better to write small, fast programs then scale them over time, than to design a large product and hack stuff off to get it out the door.
But Software isn’t written that way. It’s written as a large design that’s then hacked to ship in a schedule. Lots of “Do we cut this” type meetings. Layers of approval for design before line 1 can be written. The database guy wants the schema locked, but the product designer wants freedom to try new schemas — before anyone has had a chance to see how any schema would ever perform!
Which is why I have a radical proposal for software.
1. Software products should never have more than 1 or 2 testers. A super-large product with millions of lines of code may need a few hundred — but only a few hundred, not a few thousand. I think the rule of thumb should be something like a dev/tes ratio — at least 1 Tester for your product — that really does help — plus some sort of logarithmic growth with number of devs . I’ll say this time and again — Quality is designed into a product, not tested in. Testers just become a crutch to enable crap design and get away with it, since developers/managers have someone to blame for their bugs. Testers should be the voice of the customer — they should be there to keep developers and management honest — but that’s it.
2. Software should have no “Project Managers”. They have tons of titles — but they don’t write code. They’re value add is in asking the right questions, building consensus, and in getting a team moving as a team. Except this is managements job, which they’ve abdicated. If you’ve got this class os people, and they’re doing great work, then you’ve got bad management, an org structure that’s too flat, or worse… PMs can only add value when the management/organization is weak. Though I hate this fact, strong hierarchies are better for getting things done. Management doesn’t want to order folks to do things — they want people to self volunteer. But those who volunteer are really responding to economic incentives ( perhaps non-monetary ), and may not be the right person for the job…
3. Designers/art people are 110% more important than given credit for. I’ve seen so many good ideas go bad because the team had tons of PMs ( who write no code and hold meetings all day ), testers( who write “test frameworks” that never work and may not have used the product in months ), too few devs, and not a single Design/art person. I remember a product that I so loved and so hated at the same time — it worked well — but man, it was UGLY. Bad design = bad user experience. No artist = lots of cluttered menus where an Icon would do. No designer = lots of unintuitive placements for feature controls. This means a lessor product with good design has an opening to kill — because a few usable features trump a lot of good features poorly laid out.
So my radical proposal for building software.
1. Have as few Developers as possible on the product — more devs = herding cats, primodonna problems.
2. Have no more than 1 project manager for the entire shipping product. More = “value add” meetings that steal time and don’t really get things done. Empower this manager — let them make real decisions — including over-ruling the developer’s opinion. Developers, by their nature, will “engineer” — exactly what you don’t want. Instead, think of the product as belonging to the PM — it’s their project, and whatever choice they make, echo it… If you must have more than 1 PM, put them into a hierarchy under the head PM, otherwise you create more room for side political interactions that derail the project. Worst case, you have PMs on the prowl to steal other groups products, which yields backstabbing, teams that refuse to take work in order to kill downstream teams, then putting together decks to look good to management, etc… The instant you see one of these decks that show, “Our team is great. Our partners don’t know crap” — fire the PM who presented that. Their presentation will stick — and become the truth — whether you want it to or not. Once morale is broken, it’ll take years to recover.
3. Keep teams in their silos. Cross group collaboration = bad. It’s actually better to re-invent the wheel than to have cross group collaboration. Cross group collaboration means code designed for one purpose being shoe-horned into another. It means “hold-back” items all over the place as dev A wants credit for his work in Project B, etc… If you really want cross group collaboration, then make a clean interface in a two-cycle process. Cycle 1 — the consumer group creates a framework that they like, but doesn’t quite work in an optimal way. You can normally get to this stage in a month or two. Cycle 2 — the consumer group hands off the code for re-implementation. This two-cycle process forces cross group collaboration, and automatically converts a product to a framework — which is the only reasonable way to do cross-group collaboration.
4. Have as few tests as possible. You heard me. Test only the core scenarios in an end-to-end manner. No frameworks. No automations. You can have an automated regression suite if you really want. It might even be a good idea for long term maintenance. But only regressions should be automated, only in V2 of the product, and each regression test justified. If it’s an automated test case, and it’s not a regression test, then it’s a stupid test case. Testers will say different, I’m sure. But again, quality is a design issue, not a test one… Lots of tests just create lots of checkin friction. Testers will eventually want every checkin to be tested fully. At this point, there is no development at all going on, since devs are writing test cases rather than product code. Everyone is living in “productivity illusion” land, where lots of churn is happening, and 10% of it will be useful in the end. Those automated test cases — they’ll be broken in a wee when the server is renamed. The bugs they found will become normal practices for the devs, who now expect the automation to find it. A simple one line checkin will take 5-6 hours, or more. These costs will add up to delay the project by years…
5. All software is date driven. Release every X months, and stick to that date. Cut whatever can’t make it, and try again in the next cycle. Even core features. Set a ship date. Stick to it. No more than 6 months at a time, no less than 2.
6. Every project should have a dedicated artist/UX person.
7. Every project should have a dedicated marketing person. A “one man” proejct, that “one man” should be a marketing person, who happens to know how to write software…
Of course, my position here is pretty radical — but if you look at the state of software as we know it, this radical is probably correct. Software is late, over budget, and poorly received far too often. This is because the process is fundamentally broken — fast iteration, fast feedback, few tests, and many redesigns with lots of marketing input is surprisingly the right model… Many of these cycles integrated ( the calculus concept here ) into a product will produce more, faster, and better than the traditional approach.