Do a grammatical parse of the problem requirements (use cases) for
nouns and noun phrases.
List all candidates you can think of, then prune to an essential set that covers all the requirements.
Identify collection classes (e.g. List, Queue) for managing collections of items.
Research class libraries for classes that you can use or inherit from. Don't reinvent the wheel; use proven code.
Keep in mind the distinction between classes and objects (instances of classes). E.g., a corvette would be an object of type vehicle or car, it is unlikely that corvette would be a class.
Don't worry about UI classes at this point.
Most attributes will come directly from the data dictionary.
Identify the operations suffered by and required of each class.
For example, if you are considering a Stack class, ask: "What can I do
to a stack? What can happen to a stack?"
Focus your thinking on one class without considering its environment. For example, addRecord is a never a method on the Record class.
Don't think about which procedures are going to use the stack or what is going to be pushed on the stack.
Don't think about data structures or algorithms. Those decisions are best left until detailed design unless there is a feasibility problem.
Some use cases map directly to a method.
Create get/set methods for every attribute, even if you don't believe they are necessary.
Create a rich set of constructors, even if you don't believe they
are
necessary.
Read about class relationships.
This is the hardest part of design. There are many decisions to make:
Inheritance or Object Composition?
Consider:Inheritance or Interface?
Inheritance allows programmer to modify operations by overriding them.
Inheritance relationships can be easily extended in the future.
Inheritance exposes the internal structure to it's subclasses - with association, the objects remain encapsulated.
Inheritance carries an assumption of substitutability, promoting a versatile design.
Composition is simpler.
Composition allows for implementation independence.
Composition classes can't modify operations by overriding, thus the interface is more stable.
Learn more: [Summary] [Inheritance Critique]
Consider: Inheritance allows for sharing structure and behavior, Interfaces allow for sharing behavior.Aggregation or Dependency?
Consider: Does one class use another, or does it aggregate another?Cardinality of associations?
Be sure to document the rationale for your decisions in the Design
Issues.
Write the signature for each method. The method signatures become
the skeleton of your program.
Code your class interface (not implementation) and document it as javadoc comments.
Compile your class interface and remove any syntax errors.
Inheritance is implemented using the extends keyword. In UML, inheritance is denoted by a line with a triangle placed toward the superclass.
Aggregation is implemented using instance variables.
Every truck has a tire. (Truck is the whole, tire is the part).
class Truck extends VehicleIn UML, aggregation is denoted by a line with a diamond placed toward the aggregating class.
{ ...
private Tire[ ] tires;
}
Composition, a strong form of aggregation, indicates that the components can't exist without the aggregate. The component can't belong to more than one aggregate. E.g., a window is composed of a slider (the slider can't exist without a window). The relationship is of a structural nature. In UML, composition looks like aggregation with a filled diamond.
Dependency indicates coupling.
Typical Implementation
class DependentClass
{
...
void function1(ReferencedClass parameter1)
...
ReferencedClass function2(...) { ... }
...
void function3(...)
{
ReferencedClass
localvariable;
}
}
In UML, association is denoted by a solid line connecting two classes.
Typical Implementation
class Man
{
Woman wife;
...
}
class Woman
{
Man husband;
...
}