design issues: variables at class scope

N

Neil Zanella

Hello,

It seems to me that using too many variables at class scope in C++ (e.g.
private data members) can be just as bad as having a C program with lots
of global variables. This is especially true for large classes with
lots of methods. The worse part is that even if conventions are used
to assign names to class data members to so as to distinguish them from
other variables, then it still becomes difficult to tell from the
class definition which methods use which variables without looking
at the particular implementation of functions. That is, when we
look at a header file, it is fairly difficult if not impossible
to tell which methods use which data members. This makes it
especially difficult to refactor code. All of this leads me
to wonder whether it is best to pass data members of the
class so as to make it clear which methods use which
variables, and make the methods static. This makes
it really clear to tell which methods use which
private data members: since the methods are
static, they must appear in the parameter
list to the function.

Comments, opinions, and suggestions welcome,

Thanks,

Neil
 
P

Phlip

Neil said:
It seems to me that using too many variables at class scope in C++ (e.g.
private data members) can be just as bad as having a C program with lots
of global variables.

Hmm. So I whip out my copy of /Refactoring/ by Martin Fowler, and find this
situation is "Data Clumps", indicating the refactor "Extract Class".

Are one or two small classes trapped inside your big class, waiting to come
out?
This is especially true for large classes with
lots of methods. The worse part is that even if conventions are used
to assign names to class data members to so as to distinguish them from
other variables, then it still becomes difficult to tell from the
class definition which methods use which variables without looking
at the particular implementation of functions.

Why is knowing this important? Don't the names of the methods reveal their
intent (per /Smalltalk Best Practice Patterns/ by Kent Beck)?
That is, when we
look at a header file, it is fairly difficult if not impossible
to tell which methods use which data members. This makes it
especially difficult to refactor code. All of this leads me
to wonder whether it is best to pass data members of the
class so as to make it clear which methods use which
variables, and make the methods static. This makes
it really clear to tell which methods use which
private data members: since the methods are
static, they must appear in the parameter
list to the function.

Okay, start backwards. Which of these methods are private? Which can demote
to static free functions at file scope in the .cpp file?

The book /Large Scale C++ Software Design/ covers hiding the large aspects
of a program. (/Refactoring/, and /Agile Software Development/ by Robert
Martin cover making the program not large.)

If you can find some set of methods that access generally the same set of
member variables, that is your latent class. Pulling that out into a new
class (inside the same header file, at first) will give you one more place
to name what's going on - the name of the new class.
 
K

Klaus Eichner

Neil Zanella said:
Hello,

It seems to me that using too many variables at class scope in C++ (e.g.
private data members) can be just as bad as having a C program with lots
of global variables.
[Snip]

Comments, opinions, and suggestions welcome,

I utterly agree with you, this applies to C and C++ programs alike.

I am not a design expert, but in my view
the condition 'too-many-variables-at-class-scope' indicates a violation of
the rule 'one-class = one-real-life-representation'.

That means that you should always ask yourself whether the real life
representation (of what you are going to design as a C++-class) can not be
broken down / re-designed better in real life. You should attempt to build
the C++-classes only after you are satisfied that the real-life
representation is your final choice. In my view, trying to design a
C++-class strictly on the grounds of language rules leads to disaster.

The only language-related comment I would like to make is that the C++
language offers a multitude of different techniques to combine classes:
inheritance, composition, generic programming, etc... The coice of the
technique is yours, but only *after* you have decided about the real-life
representation.
 
P

Phlip

Klaus said:
I am not a design expert, but in my view
the condition 'too-many-variables-at-class-scope' indicates a violation of
the rule 'one-class = one-real-life-representation'.

You have a guideline in mind that some call "separation of concerns".

But some poorly-written OO tutorials begin by describing Objects as "models
of real-world objects".

That adds no value because it's not distinct. If you and I want to assess
two designs to figure out which is better to use, we can't select between
them because one "more closely matches the real world".

The best guidelines for a design are...

1. passes all test
2. readable code
3. no duplication
4. minimal class & method sizes

The OP admits breaking 4, so the odds they break 3 are very high.

And no design once implemented is set in stone - it can always be improved.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top