This page contains an archived post to the Design Forum made prior to February 25, 2002.
If you wish to participate in discussions, please visit the new
Good point, well stated
Posted by Bill Venners on 20 Mar 1998, 7:21 PM
Thanks for your comment. You make a good point that
keeping non-independent variables separate creates
the need for communicating the dependency. I
think I'll modify somewhat my wording for the book.
Of course, the responsibility for maintaining
proper values in the to-some-extent-dependent
variables (so long as the variables are private)
lies with the methods. So the dependencies between
the object's fields must be expressed in the
code of the methods.
But your point is how do you communicate the
dependencies to other programmers? Just expressing
the dependencies correctly in the code of the
methods may still leave later readers of the code
in the dark as to how the fields are being used.
When I was in college, I had a part-time job
grading student's Pascal programs, and I was
supposed to dock them 5 points if they didn't
comment their variables. But most of the comments
in the variables were redundant with the variable
names. A better kind of comment in the variables
would perhaps be one that indicated the
dependencies between the variables, such as:
// innerCoffee indicates the amount of coffee in
// the cup when needsWashing is false. When
// needsWashing is true, innerCoffee is unused.
I tend to prefer approaches to design that maximize
readability without relying on comments, simply
because a lot of times people don't bother to
comment. That's one reason I like having two
fields in this case instead of one. Absent any
comments, at least I can look at the field names
and ascertain that there are two attributes
being modelled, and have an idea what the
original programmer's intention was.
Many years ago, I read in some book an anecdote
that described how some poor manager lost his
job because some programmer, many years before,
had overloaded a single variable with multiple
meanings. This programmer decided that the bank
that would be using this program would never
have as many as 10,000 accounts, so he used the
account numbers < 10,000 to mean automatically
send out bills to customers. One day several years later,
the account numbers at the bank crept up past
10,000 and hundreds of customers found erroneous
bills in their mailboxes.
This design was not just a bad way to communicate
what fields are used for, it was a time bomb
because the program was likely automatically
incrementing the account number each time. But
it was a formative moment in my philosophy that
we should "lean towards" modeling separate
attributes in separate fields.
Thanks again for your comments, Harald. If anyone
else has an opinion on this one, please chime in.
> I liked your article about some basics. However, I'd like to comment on
> "The especially valuable guideline for fields".
> There is an underlying assumption in this guideline, namely that the values of any two
> attributes are either fully independent or fully dependent. Independent here means that any combination of values of two attributes a1 and a2 is admissible and
> makes sense; whereas for fully dependent attributes, the values of two attributes can be
> computed from each other.
> However, in reality, in many cases a partial dependence occurs.
> Take the coffee cup: Let us assume that we want to model the coffee cup in a way that
> when it needs washing, the amount of coffee is unspecified. The first implementation, with
> the "specific value", does that perfectly. The second implementation, which separates
> the washed status from the coffee amount, cannot model this.
> So, the tight coupling between the attributes by putting them into one field appears(!)
> to be advantageous sometimes.
> The real question, of course, is: "When are two attributes *sufficiently* independent so
> that they should be placed into two fields?" Observe that this is a question of *degree*
> (and no longer an either-or question, as your guideline assumes).
> The answer to this *is* to lean to your guideline, i.e. "When in doubt, use more fields".
> *However*, the next thing you *have to do* is to specify exactly (formally, if possible)
> the dependencies between the fields; e.g. "needsWashing == true => innerCoffee is undefined".
> Why? Because if you do not do that, programmers will implicitly *assume* "sensible"
> dependencies; and, of course, different programmers might assume different things.
> Again the coffee cup: One might use innerCoffee as a temp variable when needsWashing is true;
> another one might assume that the innerCoffee DOES have a meaning also in the case when
> needsWashing is true. Both are in some sense "right", as each interpretation is a valid model.
> Yet, their methods will quite forcefully clash when used together.
> So the rule should be:
> The especially valuable guideline for fields
> Use a separate field to represent each separate attribute of a class or object.
> If two attributes are only "somewhat separate", use two fields, but document the
> dependencies between the fields' possible values carefully.
> Two attributes count as "somewhat separate" if your team starts arguing.
> There is much more to all that - theoretically as well as in practice -, but my comment
> starts getting long ...