From: David B. Held (dheld_at_[hidden])
Date: 2004-11-18 23:48:11
Thorsten Ottosen wrote:
> "David B. Held" <dheld_at_[hidden]> wrote in message
> | [...]
> | However, that is exactly the *point* of the Add() function! These
> | pieces of data are collected elsewhere, and it is the responsibility
> | of the Add() function to integrate them into a single package object.
> | Yes, it is possible to refactor it into classes that only take a few
> | fields at a time, but I can guarantee that such a refactoring will
> | not be an improvement.
> how can you guarantee that? What is the abstraction that add() package
> the items together in? Why shouldn't one be able to pass the data around in a
> that "package" form?
Because I have to do processing on the arguments in order to build a
proper package object! And that is exactly what Add() does. So you
can't build a package object from the arguments and pass it to Add(),
because that is the problem Add() is solving in the first place! Any
refactoring will simply add unnecessary complexity to a problem. I am
arguing that Add(), with its unashamedly numerous arguments, is
irreducibly complex. Any attempt to refactor it will *increase*
complexity, not reduce it through abstraction.
> I'm not apologizing for all the bad code I have written...but I am trying to
> do better the next time.
I'm not apologizing because I don't recognize that I've written bad
> | [...]
> | Now, in this case, we are looking at functions that only get called
> | from a small number of places (or even just one). Thus, named
> | parameters don't really help any. But the fact is, long argument
> | lists are not intrinsically evil.
> are they intrinsically good?
Is mowing the lawn intrinsically good or intrinsically evil? If you
can confidently answer that question, I know a few philosophers that
would like to talk to you. Some things are amoral, and long argument
lists is one of them.
> 1. pack the values in an object
> 2. send that object along to a function
> 3. unpack the data from the object inside the function
> And I guess that is what you think is plain stupid.
Yes, because you had to either: pack the values into an object having
a c'tor with a lot of arguments (sound familiar?), or you had to create
an object and set the members later, which sounds downright foolish to
merely avoid long argument lists.
> My point has been, however, that once you start making abstractions you
> 1. simplify interfaces
> 2. makes it possible to define invariants for your data and hence localize
> 3. adds type-safety to the application
> (but I guess we don't have to go through the benefits of OO here.)
And my point is, in order to implement those abstractions, you very
often encounter the very argument lists that you were trying to avoid!!
In fact, preserving invariants implies that you *need* to do all-at-once
initialization in the c'tor!
> So if I were to do it all over, I would probably map my database tables to
> classes instead of passing tuples of strings and intergers around.
That depends on the application. If the strings and ints make sense
in a class, by all means pack them into a class. But when the data
gets entered the first time, from the "outside world", *someone*,
logically speaking, has to pack that data into a class the first time;
and I don't see anything wrong with that being a single function with
a long argument list. Nothing you have said thus far convinces me
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk