The software development business, once the domain of a few advanced technology
companies, is now pervasive. Why? Because software is less costly and easier to
modify than hardware. At first glance this is obvious: building a software telephone switch is a lot less costly than the hardware equivalent. But looking more closely, software products
have far more features and are therefore more complex than hardware products. Software is easier to change, but this just adds to the level of complexity, especially on the management side. Software allows us to build products that are more complex.
Each software development project starts with a concept or proposal, and a favourable business case, and ends with product retirement. There's a lot of process in between: Requirements, Project Management, Architecture Definition, Design, Implementation, Build Management, Change Management, Document Management, Configuration Management, Problem/Issue Tracking, Test Case Management, Test Run Management, Customer Tracking.
The successful software organization can manage complexity - in both the product
and the process.
Focus on Strong but Simple Architecture
Simplicity and good architecture are the keys to managing complexity and producing good
product. Good architecture is a result of understanding the problem, understanding the tools you have to work with, and good design. And there's no substitute for
experience. One important component of good architecture is how you use your tools.
The C language, for example, has numerous capabilities. Some are good, some are bad. At Neuma, we tend to be fairly strict about how the language is to be used. Not just
no "goto" statements, but a whole set of dozens of guidelines that help our developers produce good product. Some examples:
- Use loops with conditions at the beginning of the loop, not at the end. It's easier to read and understand.
- Always use 0-index origin for arrays, loops, etc., and (start,count) rather than (start,end) pairs.
- Don't do arithmetic on pointers and avoid using pointers altogether.
- Name local variables/fields with simple names. Use full names for global identifiers.
- Create single entry, single exit procedures/functions (huge readability
- Use common names for standard or recuring parameters in functions
and the list goes on. You can use a safe subset of the C language, but without losing
functional capability. The idea is to make all code simpler and consistent. Simple formatting rules do not accomplish this goal. But the overall set of guidelines help to make code maintainable and readable, while instilling an attitude of good design.
Using a smaller but adequate subset of the language also provides simplicity. If loops are always going from 0 to N-1, you don't have to spend a lot of time figuring out boundary
conditions, because they all follow the same pattern. That speeds things up and cuts down on errors.
This is a very specific example, but if you have even a dozen clear guidelines explained,
it's amazing how much simpler you can make your development environment.
Other ways to simplify your product include:
- Simplify the technology you use. Don't
let everyone pick their own scripting language, or programming language.
- Perform code reviews so that you have fewer problems flowing through your product life cycle. Also review against
- Use design rules that help your Configuration Management rather than hinder it.
- Instead of variant builds, support run-time configuration of a more generic
These are but a few examples that will have significant effects on your product
architecture. When it comes down to it, a dozen or two little things that improve your software by 1% or 2% each, can have a significant overall effect.
- A Reward, not a Burden
I love it when developers come to me and tell me that they couldn't do their job without
the ALM/CM tools and processes. You'd expect that from CM managers, but often CM is seen as an overhead by developers. And grant it, you'll never hear this until you take away their environment. But if you give them benefits such as:
- Change-based check-in, differencing, merging and promotion
- Ability to check-in source code when the developer is ready (vs. when the build manager is ready)
- To-do lists that eliminate any extra effort to provide traceability
- Easy review of tasks accomplished over the past months and years
- Access to all the product information they need in a single place
- Elimination of tagging and minimizing of branching/merging.
- Easy ways to look for outstanding problems or to identify