![]() |
![]() ![]() |
The flip side of the principles we just discussed takes the form of a number of common errors that our students make when they're doing domain modeling for their projects. Our "Top 10" list follows.
Start assigning multiplicities to associations right off the bat. Make sure that every association has an explicit multiplicity.
Some associations on a class diagram represent one-to-one relationships, whereas others represent one-to-many relationships. These are both called multiplicities. However, you should avoid dealing with multiplicity altogether during domain modeling-it chews up time and can be a major cause of analysis paralysis.
Do noun and verb analysis so exhaustive that you pass out along the way.
Kurt Derr's Applying OMT (SIGS Books, 1995) is a good source of information about "grammatical inspection." If you follow Derr's advice all the way down the line, though, you're likely to find yourself at too a low level of abstraction, in addition to running the risk of a nervous breakdown. Use the technique to get your object discovery started, but take care not to get carried away.
Assign operations to classes without exploring use cases and sequence diagrams.
We advocate a minimalist approach to defining operations during domain modeling. In fact, we're going to tell you that you shouldn't assign any operations to classes during domain modeling. That's because there isn't enough information available with which to make good design decisions about operations at that stage of a project. When we get to interaction modeling, however, we do have good information (at least we hope to). We describe interaction modeling in Chapter 7.
Optimize your code for reusability before making sure you've satisfied the user's requirements.
The more general your objects and classes, the higher the probability that you'll be able to reuse those objects and classes for other projects. And a complete class is one that is theoretically reusable in any number of contexts. However, to achieve reusability and completeness, you need to consider both attributes and operations, and we just told you why you shouldn't be assigning operations to classes during domain modeling, so it's not wise to overdo your efforts to make classes reusable when you're doing high-level class diagrams. Move quickly through domain modeling, so you have time to make sure that you're building what your customers want.
Debate whether to use aggregation or composition for each of your "part-of" associations.
Grady Booch's original descriptions of "has by reference" relationships morphed into aggregation within the UML. Similarly, "has by value" became a "strong" form of aggregation called composition within which a "piece" class is "owned by" a parent class: if the parent is deleted, all instances of the child get deleted automatically. Trying to differentiate between these two during a domain modeling effort is a surefire way to do some serious tail-chasing. We prefer to use simple aggregation during domain modeling. Aggregation versus composition is a detailed design issue.
Presume a specific implementation strategy without modeling the problem space.
As part of ongoing refinement of your domain model, you should remove anything that clearly states an action rather than a dependency or that's specifically related to implementation. What you should not do is start introducing things on your high-level class diagrams that represent commitments to specific technologies, such as a relational database or a particular kind of server. Leave implementation issues to implementation; model the problem domain first.
Use hard-to-understand names for your classes, like cPortMgrIntf, instead of intuitively obvious ones, like PortfolioManager.
One good reason to do domain modeling up front is to facilitate the task of getting everyone on the project team to agree on what your key abstractions should be called. The more obvious the class names, the easier that task will be. Save acronyms and other kinds of abbreviations (if you insist on having them) for implementation.
Jump directly to implementation constructs, such as friend relationships and parameterized classes.
The UML offers a lot of opportunities to add what we call "Booch stuff" to class diagrams. This includes constructs that came across more or less directly from C++, such as parameterized classes and friend relationships. These are much more relevant to the solution space than to the problem space, though, and the focus of domain modeling should definitely be the problem space.
Create a one-for-one mapping between domain classes and relational database tables.
If you're reengineering a legacy system that uses a relational database, the tables within that database are likely to be an excellent source of names for your domain classes. However, be careful not to just bring them over to your static model wholesale. A relational table can have a lot of attributes that might not belong together in the context of an object model. You should try to use aggregation to factor groups of attributes into "helper" classes, which contain attributes and operations that can be grouped into smaller "piece-part" classes.
role="titleicon"
Perform "premature patternization," which involves building cool solutions, from patterns, that have little or no connection to user problems.
Patterns often start becoming visible during robustness analysis. As we'll explore in Chapter 5, there are two strategies, "control in the screen" and "use case controller," that lend themselves to discovering patterns connected to use cases. Looking ahead, design patterns can be highly useful in the context of sequence diagrams and design-level class diagrams. Domain modeling is not the time to start thinking in terms of patterns.
![]() |
![]() ![]() |