So you have the go-ahead to start a project. At this stage, typically, you have only a vague idea of the requirements. For instance, you might be able to say:
We are going to build the next-generation customer support system for the Watts Galore Utility Company. We intend to use object-oriented technology to build a more flexible system that is more customer-orientedspecifically, one that will support consolidated customer bills.
Of course, your requirements document will likely be more expansive than that, but it may not actually say very much more.
At this point, you want to get a better understanding of the problem.
What is it you are actually going to build?
How are you going to build it?
In deciding what issues to look into during this phase, you need to be driven, first and foremost, by the risks in your project. What things could derail you? The bigger the risk, the more attention you have to pay to it.
In my experience, risks can usefully be classified into four categories:
What are the requirements of the system? The big danger is that you will build the wrong system, one that does not do what the customer needs.
What are the technological risks you have to face? Are you selecting technology that will actually do the job for you? Will the various pieces fit together?
Can you get the staff and expertise you need?
Are there political forces that can get in the way and seriously affect your project?
There may be more in your case, but risks that fall into these four categories are nearly always present.
Requirements are important and are where UML techniques can most obviously be brought to bear. The starting point is use cases. Use cases drive the whole development process.
I'll talk in detail about use cases in Chapter 3; here I'll just give you a brief description of what use cases are.
A use case is a typical interaction that a user has with the system in order to achieve a goal. Imagine the word processor that I am currently using. One use case would be "do a spell check"; another would be "create an index for a document."
The key element for a use case is that each one indicates a function that the user can understand and that has value for that user. A developer can respond with specifics. For instance:
It will take me two months to do the index function for you. I also have a use case to support grammar checking; I reckon that's three months. We have only three months to the releasewhich one would you like?
Use cases provide the basis of communication between customers and developers in planning the project.
One of the most important things to do in the elaboration phase is to discover all the potential use cases for the system you are building. In practice, of course, you aren't going to get all of them. You want to get most, however, particularly the most important and riskiest ones. It's for this reason that, during the elaboration phase, you should schedule interviews with users for the purpose of gathering use cases.
Use cases do not need to be detailed. I usually find that a paragraph or three of descriptive text is sufficient. This text should be specific enough for the users to understand the basic idea and for the developers to have a broad sense of what lurks inside.
Use cases are not the whole picture, however. Another important task is to come up with the skeleton of a conceptual model of the domain. Within the heads of one or more users lies a picture of how the business operates. For instance:
Our customers may have several sites, and we provide several services to these sites. At the moment, a customer gets a bill for all services at a given site. We want that customer to be billed for all services at all sites. We call this consolidated billing.
This passage contains the words "customer," "site," and "service." What do these terms mean? How do they fit together? A conceptual domain model starts to answer these questions and, at the same time, lays the foundation for the object model that will be used to represent the objects in the system later in the process. I use the term domain model to describe any model whose primary subject is the world that the computer system is supporting, whatever stage of the development process you are in.
Note that the Rational Unified Process defines the term "domain model" more narrowly; see Jacobson, Booch, and Rumbaugh (1999) for details. My usage follows that of most people I know in the object community.
I find two UML techniques particularly valuable in building conceptual domain models.
The main technique I use for domain models is the class diagram, drawn from a conceptual perspective (see Chapter 4). You can use these diagrams to lay out the concepts that the business experts use as they think about the business and to lay out the ways those experts link concepts together. In many ways, class diagrams are about defining a rigorous vocabulary to talk about the domain.
If the domain also has a strong workflow element, I like to describe this with activity diagrams (see Chapter 9). The key aspect of activity diagrams is that they encourage finding parallel processes, which is important in eliminating unnecessary sequences in business processes.
Some people like to use interaction diagrams (see Chapter 5) to explore how various roles interact in the business. By thinking about workers and activities together, they find it easier to gain an understanding of the process. I prefer to use activity diagrams to figure out what needs to be done first and to address who does what later.
Domain modeling can be a great adjunct to use cases. When I gather use cases, I like to bring in a domain expert and explore how that person thinks about the business, with the help of conceptual class diagrams and activity diagrams.
In this situation, I use minimal notation, I don't worry about rigor, and I make lots of informational notes on the diagram. I don't try to capture every detail. Instead, I focus on important issues and areas that imply risk. I draw lots of unconnected diagrams without worrying about consistency and interrelationships among diagrams.
I find that this process can quickly yield a lot of understanding. Armed with this understanding, I find that I can more easily identify the use cases for the various users.
After I've covered most of the relevant areas, I like to consolidate the various diagrams into a single consistent domain model. For this, I use one or two domain experts who like to get deeper into the modeling. I maintain a conceptual perspective but, at the same time, become more rigorous.
This model can then act as a starting point for building classes in the construction phase. If this model is large, I use packages to divide the model into chunks. I'll do consolidation for class and activity diagrams and perhaps draw a couple of state diagrams for classes that have interesting lifecycles.
You should think of this initial domain model as a skeleton, not as a high-level model. The term "high-level model" implies that a lot of details are missing. I have seen this mistake made in several situations, expressed as, for instance, "Don't show attributes on these models." The results are models with no substance. It's easy to see why developers deride such efforts.
You can't take the opposite approach and build a detailed model, however. If you do, it will take ages and you will die from analysis paralysis. The trick is to find and concentrate on the important details. Most of the details will be dealt with during iterative development. This is why I prefer to think of this model as a skeleton. The skeleton is the foundation of the rest of the model. It is detailed, but it is only a small part of the story.
Naturally, this does not tell you how to differentiate bone from flesh; that is the art of the skilled analyst, and I haven't figured out how to bottle that yet!
Domain modeling is also driven by the use cases as they become known. As use cases appear, the modeling team should look at them to assess whether they contain anything that could have a strong impact on the domain model. If so, they should explore further; if not, the use cases should be put aside for the time being.
The team that builds the domain model should be a small group (two to four people) that includes developers and domain experts. The smallest viable team would be one developer and one domain expert.
The team should work intensively during the elaboration period until it reaches closure on the model. During this period, the leadership should ensure that the team neither gets bogged down in details nor operates at so high a level that their feet don't touch the ground. Once they get the hang of what they are doing, bogging down is the biggest danger. A hard deadline works well in concentrating minds.
As part of understanding the requirements, you should build a prototype of any tricky parts of the use cases. Prototyping is a valuable technique for getting a better understanding of how more dynamic situations work.
I use prototyping whenever I'm uncomfortable about how a risky part of the system is really going to work. I prototype just enough so that I can understand enough to assess the risk and estimate how much effort it will take to do things. Usually, I don't prototype the whole picture; instead, I use the overall domain model to highlight areas that need prototyping.
I find that people new to the UML need to prototype more. This helps them gain familiarity in how the UML diagrams correspond to actual programming.
When you use a prototype, don't be constrained by the environment in which you will actually deliver. For instance, I have often gained a lot from analysis prototyping in Smalltalk, even if I am building a C++ system.
One of the most important elements in dealing with requirements risk is getting access to domain expertise. Lack of access to people who really know the domain is one of the commonest ways for projects to fail. It is worth investing considerable time and money to bring people who really know the domain into your teamthe quality of the software will be directly proportional to their expertise. They need not be full time, but they need to be open-minded, have deep hands-on understanding, and be readily available for questions.
The most important thing to do in addressing technological risks is to build prototypes that try out the pieces of technology you are thinking of using.
For example, say you are using C++ and a relational database. You should build a simple application using C++ and the database together. Try out several tools and see which ones work best. Spend some time getting comfortable with the tools you are going to use.
Don't forget that the biggest technological risks are inherent in how the components of a design fit together rather than being present in any of the components themselves. You may know C++ well, and you may know relational databases well, but putting them together can be surprisingly hard. This is why it is very important to get all the components you intend to use and fit them together at this early stage of the process.
You should also address any architectural design decisions during this stage. These usually take the form of ideas of what the major components are and how they will be built. This is particularly important if you are contemplating a distributed system.
As part of this exercise, focus on any areas that look as though they will be difficult to change later. Try to do your design in a way that will allow you to change elements of the design relatively easily. Ask yourself these questions.
What will happen if a piece of technology doesn't work?
What if we can't connect two pieces of the puzzle?
What is the likelihood of something going wrong? How would we cope if that happens?
As with the domain model, you should look at the use cases as they appear in order to assess whether they contain anything that could cripple your design. If you fear they may contain a "purple worm," investigate further.
During this process, you will typically use a number of UML techniques to sketch out your ideas and document the things you try. Don't try to be comprehensive at this point; brief sketches are all you need and, therefore, all you should use.
Class diagrams (see Chapters 4 and 6) and interaction diagrams (see Chapter 5) are useful in showing how components communicate.
Package diagrams (see Chapter 7) can show a high-level picture of the components at this stage.
Deployment diagrams (see Chapter 10) can provide an overview of how pieces are distributed.
I often go to conferences and listen to case study talks given by people who have just done an object-oriented project. They usually answer the question: "What were your biggest mistakes?" with responses that always include "We should have got more training."
It never ceases to amaze me how companies embark on important OO projects with little experience and little thought to how to gain more. People worry about the costs of training, but they pay every penny as the project takes longer.
Training is a way to avoid making mistakes, because instructors have already made those mistakes. Making mistakes takes time, and time costs money. So you pay the same either way, but not having the training causes the project to take longer.
I'm not a big fan of formal training courses. I've taught many of them and designed some as well. I remain unconvinced that they are effective in teaching object-oriented skills. They give people an overview of what they need to know, but they don't really pass on the core skills that you need to do a serious project. A short training course can be useful, but it's only a beginning.
If you do go for a short training course, pay a lot of attention to the instructor. It is worth paying a lot extra for someone who is knowledgeable and entertaining, because you will learn a lot more in the process. Also, get your training in small chunks, just at the time you need it. If you don't apply what you have learned in a training course straight away, you will forget it.
The best way to acquire OO skills is through mentoring, in which you have an experienced developer work with your project for an extended period of time. The mentor shows you how to do things, watches what you do, and passes on tips and short bits of training.
A mentor will work with the specifics of your project and knows which bits of expertise to apply at the right time. In the early stages, a mentor is one of the team, helping you come up with a solution. As time goes on, you become more capable, and the mentor does more reviewing than doing. My goal as a mentor is to render myself unnecessary.
You can find mentors for specific areas or for the overall project. Mentors can be full time or part time. Many mentors like to work a week out of each month on each project; others find that too little. Look for a mentor with knowledge and the ability to transfer that knowledge. Your mentor may be the most important factor in your project's success; it is worth paying for quality.
If you can't get a mentor, consider a project review every couple of months or so. Under this setup, an experienced mentor comes in for a few days to review various aspects of the design. During this time, the reviewer can highlight any areas of concern, suggest additional ideas, and outline any useful techniques that the team may be unaware of. Although this does not give you the full benefits of a good mentor, it can be valuable in spotting key things that you can do better.
You can also supplement your skills by reading. Try to read a solid technical book at least once every other month. Even better, read it as part of a book group. Find a couple of other people who want to read the same book. Agree to read a few chapters a week, and spend an hour or two discussing those chapters with the others. By doing this, you can gain a better understanding of the book than by reading it on your own. If you are a manager, encourage this. Get a room for the group; give your staff the money to buy technical books; allocate time for a book group.
The patterns community has found book groups to be particularly valuable. Several patterns reading groups have appeared. Look at the patterns home page (<http://www.hillside. net/patterns>) for more information about these groups.
As you work through elaboration, keep an eye out for any areas in which you have no skills or experience. Plan to acquire the experience at the point at which you need it.
I can't offer you any serious advice on this, because I'm not a skilled corporate politician. I strongly suggest that you find someone who is.
My rule of thumb is that elaboration takes about a fifth of the total length of the project. Two events are key indicators that elaboration is complete.
The developers can feel comfortable providing estimates, to the nearest person-week of effort, of how long it will take to build each use case.
All the significant risks have been identified, and the major ones are understood to the extent that you know how you intend to deal with them.