Re: c++ class design: where to put debug purpose utility class?
On Jun 30, 9:35 am, Ian Collins <ian-n...@hotmail.com> wrote:
James Kanze wrote:
On Jun 29, 4:10 pm, "Phlip" <phlip2...@gmail.com> wrote:
That should map onto C++ classes -
Why? That's the first time I've heard that. (There are a
lot of cases where they do map onto C++ classes.)
Um, we agree again!
That's not really TDD. You start at the test, and write
each test case to illustrate one aspect of your target
class.
Which, of course, isn't true, because until you have at
least some idea as to what the class is to do, you can't
write the tests. You start by determining what the class is
to do (in most cases, that means some high level design).
You don't start by just typing in code, whether it is a test
or anything else.
Here's where we differ. The above assumes you have a design
which defines your classes.
The above assumes that you have at least some idea as to what
the class (or any other bit of code) will do before you start to
write it. I think we both also more or less agree that unless
it is written down, you don't really have any idea. Where we
disagree is that you seem to consider the unit tests a form of
being "written down", whereas I consider them code, just like
the rest---I don't know how to write a unit test until I have
some idea what is to be tested, i.e. what the unit shoud do.
And IMHO, I don't know that until it is written down.
For small applications, it's not unusual that the "written down"
part ends up as comments in the header (in Doxygen format, for
example). For larger applications, there'll almost always be
some sort of high level functional decomposition before I can
even think about "units", and that has to be written down.
Often with TDD, you test and to code to a more abstract
requirement and the design (classes) follow the tests.
Traditionally, that has been called prototyping, not testing:-).
It's almost essential for anything which interacts with a human.
It's of almost no use if you're implementing a protocol defined
by a standard.
Traditionally, you're supposed to throw the prototype out, once
you've learned from it. A rule that is often ignored (which may
account for the poor quality of some of the software out there).
But I suppose that you could call throwing it out simply an
intensive refactorizing, and the prototyping "testing".
Especially since the "throwing out" usually doesn't consist of
actually deleting the source code from the disk, and that the
rewrite often involves some copy/pasting:-).
Sometimes there's an agreed interface, or a base class that is
being extended, but often the tests are testing an action for
a reaction.
In which case, you probably have some idea as to what the action
or reaction should be. And perhaps even some constraints on it.
I'd write those out, in plain French (or whatever language I
happen to be using on the project). Maybe as comments in the
code; maybe even as comments in the unit tests. But in a human
language, at a higher level of abstraction than C++.
At a low level, I tend to work as if I were doing literate
programming, even when I'm not using literate programming tools.
The C++ code is an end product, not the means. And it's not the
only end product, since readability (and not just correct
implementation) is an important issue.
[...]
(I find it very hard to conceive that in this day and age,
people are still suggesting that we code before we think.
And proposing it as a silver bullet, no less.)
I don't think anyone is suggesting that. What is being
suggested is a different way of thinking.
Well, I've said from the start that you can't write any code
without first thinking. Including a unit test. But I'd like to
insist on the fact that if you haven't written it out in your
native language, you haven't really thought it out.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34