Design Rationale
"My observation is that novice programmers document nothing,
apprentice
programmers document everything, journeyman programmers document why
they
did what they did, and master programmers document why they didn't do
something
else." Richard C. Haven, Coder, Santa Cruz Software, Mountain View,
Calif.
"It's been said that the most efficient form of communication is
face-to-face using a whiteboard. However, in my experience, for
technical
communication (unless the terms and diagrams are used with mathematical
precision), the participants' perceptions of the issues discussed begin
to diverge the instant they turn to walk away. I've actually
photographed
whiteboards after "very insightful and productive" meetings, only to
have
them appear as meaningless chicken scratchings to the participants days
or even hours later. Such informal communication can't clearly
preserve
requirement and design decisions which must be documented unambiguously
even if the development team works in the same room." Norman Hines,
Software
Developer, Jacobs Sverdrup Naval Systems Group, Ridgecrest, Calif.
A design team makes dozens of design decisions and tradeoffs in the course of a
major
project. They range from very high level decisions, like which
software
architecture to use, to very low level decisions, like should I use a
FOR
loop or a WHILE loop for this iteration structure. You need to
document
the significant issues you debated and your decision. What is
"significant?"
You have to use your judgement, but if you spend more than five minutes
discussing it, it's probably significant. However, sometimes
significant
decisions result in very little discussion if there is a clearly
superior
alternative. However, you would still need to document it, even
if
only briefly.
(Wikipedia
article)
Recommended Format
Issue #N: Describe the issue in a sentence. State
it as a question or a tradeoff. For example, "How should we
handle persistent game state?" or "Should we use a
common error logging mechanism?" or "Should we send serialized message
objects for simplicity or write our own message protocol to improve performance?"
Alternative A: Brief description of the solution
Advantages: list advantage of this solution.
Disadvantages: list drawbacks of this solution.
Alternative B: Brief description of the solution
Advantages: list advantage of this solution.
Disadvantages: list drawbacks of this solution.
(Repeat for all alternatives you considered).
Decision: Explain which alternative you chose and give
your rationale. You need to justify your choice, and why it is superior
to the other alternatives. Don't just simply restate it's advantages.
Dan Stearn's Issues List
These are examples of high level design issues. These might not
all
necessarily apply to your project.
Other examples of design issues:
- Searching: Can we get away with a simple linear search or
do we
need
a binary search?
- Sorting: There is probably no situation that justifies
writing
your
own sort, when you can reuse one from a library somewhere. So if
you write any sorts you definitely need to provide a rationale.
- Dynamic versus static data structures: Some programmers
like
linked
lists and other dynamic data structures because of a paranoia about not
"wasting" any space. But dynamic data structures are more
complicated,
so you need to show the cost benefit analysis to justify not using a
simple
statically declared data structure, like an array.
- Abstract classes: If you have several classes which have
similar
characteristics, should you create an abstract base class to inherit
from?
Does the ease of reuse which you gain justify the overhead of a more
complex
design?
- Maintainability versus performance: In this course you
should
trade
off performance and prefer maintainability. In other words, never make
a decision on the basis that it saves memory or executes
faster.
If you think your situation is an exception to this guideline you need
to negotiate it with the instructor.
- Recursion versus iteration: Unfortunately most programmers
don't
understand recursion very well, and in addition it has severe
performance
penalties. Be sure to clearly document any decision to use
recursion.
- Complexity in the data structure or in the algorithm: In general
if you
make a more complex data structure you can use a simpler algorithm, and
vice versa. Document this tradeoff where appropriate.
- Data Structure design: There are often several different
ways to
represent the data in your problem domain. Be sure to discuss the
thinking
that went in to your choice of how to represent the major data
structures
in your design.
Defending your decision
Your justification for your decision must use an objective,
technical, engineering argument. You must choose an alternative
based on its technical merit. It must be consistent
with the Quality Attributes from the SRS.
Some unacceptable arguments:
- "Because that's what we are familiar with."
- "We don't have enough time."
- "Because it's "cool" or new or getting lots of press."
Examples
"One design issue we ran into for our game was in designing
the Hall of Fame. We debated whether we should maintain
the names in sorted order, or just sort them when it's time
to display the list. Performance-wise it seemed smarter to
keep the items sorted by just inserting each new name in
it's proper position. Sorting the entire list when there
might be just one new name seemed like overkill.
However, it would be really easy to implement because
we can use Collections.sort. Even though we gringed when
we thought of it, we went with the sort. We decided
there would never be very many items in the hall, so
realistically sorting would be super quick, even though
it is hitting a fly with a sledgehammer. It will save us
time because we don't have to write our own insert method."
Good enough, needs improvement. It doesn't follow recommended
format so the pros/cons aren't easy to identify.
"We considered a more advanced data structure, however we decided on
the Vector class. We chose it because with the relatively small
data
sets expected (under 1000 items) it would not be necessary to get a
faster
search than a linear search. The overhead of sorting the
structure
would not allow for much performance gain with data sets of this
size.
"
Good enough, needs improvement. It doesn't follow recommended
format.
Issue #3: A single player game board and a multiplayer game
board
are very similar classes. Should we create an abstract class,
GameBoard,
that encompasses the common features?
Alternative A: Create a GameBoard abstract class.
Advantages: Promotes reuse. Makes the solution easy to extend
should there be some other type of gameboard in the future. May
contribute
to simpler algorithms via polymorphism.
Disadvantages: Adds a layer of abstraction to the design.
Alternative B: No GameBoard abstract class.
Advantages: Simpler design.
Disadvantages: May have to write similar code for
common features in two places. More work to extend in the future to
accept
different board type.
Decision: Alternative B. There isn't likely to be another
type of board aside from single or multiplayer, so future maintenance
isn't
a big concern. The game will know which mode it is in, (single or
multiplayer),
so polymorphism doesn't help us that much in this situation. So since
we
aren't going to really leverage off the advantages of the abstract
class,
we should avoid the complexity.
Great. Follows recommended format. Explains all alternatives, and
gives a complete justification of decision.
Non-Examples
The following examples are Requirements issues, not Design
issues.
That doesn't mean they are not important; they are VERY
important.
It's just that they SHOULD have been determined already, during the
analysis
phase. But if you neglected to resolve these issue during
analysis
and waited till design to figure out what to do, well, good, at least
you
finally figured it out. Now go back and add these issues to the
specification
document.
"We needed to store certain program preferences to reconstruct a
project
if it were reopened. Should we use a "project" file?"
"Should we allow the user to "undo" an edit operation?"
"When the user requests to open a new document, should we prompt
them
to save the current document first?"
"Should we let the user invoke a function by having an action button
or a menu selection on the menu bar?" (Any user interface
decision
is a requirements issue not a design issue.)
Another Non-Example
Issue: Should the methods be public, protected, or private?
Alternative A: Make all the methods public.
Alternative B: Make all the methods protected.
Alternative C: Make all the methods private.
Alternative D: Use public methods for interface methods
(required),
protected methods for methods to be called from subclasses, and private
methods for those methods only to be called from within a class.
Decision: Alternative D requires the most work, but it will
ensure a good balance between limiting visibility and allowing access
to
the classes we create.
This is not a design issue, because it is not specific to a
particular
project. There is nothing here that involves a tradeoff unique to a
particular
project. This is a general design principle that should always be
followed.
Practice Exercise
Identify the weaknesses in the writing of the following design issue
and then completely rewrite it.
Issue: We are using a
two-dimensional array to represent the playing board for the game of "Destruct-o-Match."
What should we have the array hold to represent the tiles?
Alternative A: Characters
Advantages: It is easy to debug a two dimensional
array that prints characters because they look unique.
Disadvantages: limited on the amount of different
characters that may affect future modifiability for a larger board.
Alternative B: Java ints
Advantages: There can be tens of thousands of
different integers and also you can use integers as subs in an array.
Disadvantages: none
Decision: Alternative B.
The main reason is because array slots are numbered with
integers. The user interface can pass in an x and y coordinate
for where the player clicked on the board and it can easily be checked
with the two dimensional array by having array sub x and y.
Home