Design Strategy

We are still bad at writing large software.

Many companies (particularly large ones), try to solve the problem by adding lots of design, documentation, and oversight controls and processes; particularly up-front. This seems like a good idea as it is analogous to building a house with

People can specialize and you can pay people according to their "level".

The only problem is that building a house is very poor analogy to building a program. Why? Imagine constructing a house as if it were more like building software:

Sun-Tzu: "no plan has ever survived contact with the enemy." Better to plan on being agile, reacting intelligently rather than stubbonly and rigidly sticking to your original plan even though it doesn't fit the current circumstances.

Confidence in yourself or your coders may influence design strategies. You have to be confident that you can react intelligently and swiftly to the rapidly and constantly changing currents of software development. You should assume you will make mistakes and have to back up, throwing out some software. Your software is always in a state of decay anyway, so you should be used to refactoring your code; it must be groomed continuously lest it become fragile and inflexible.

Tom Burns, CEO of jGuru.com, suggests that some of these "do all design work upfront" strategies are legacies of the day when edit-compile-test cycles were insanely slow (perhaps even using punch cards). You couldn't really "send out scout parties" to test ideas.

Per the above about the toilet, one of your goals should be to make each object as encapsulated and independent as possible.

Process

Design goals: get a list of operations, entities/actors

start with general features then iteratively refine them until you can clearly see the operations like "show email msg". With web apps you can start to lay out the pages as a tool to help you think about the system and get more specific. Same with gui apps.

Once you have actors and functionality, try to group functionality into services or modules. Do a data flow diagram to show what actors or entities you have like mail msg, user, address, ... Usually reveals a general architecture; draw lines where different machines exist. You can begin to formalize everything by making classes for services and actors and then filling in operations names as methods (no implementation yet!). This helps you define the interface between objects.

Try to isolate funtionality that will change by abstracting the operation such as the persistence layer.