Partial class implementation

James Dennett jdennett at acm.org
Tue Jul 17 22:20:08 PDT 2007


Robert Fraser wrote:
> janderson Wrote:
> 
>> Classes should be small and as minimal as possible.  I think this is 
>> part of Meyers argument.  Anything that can be placed outside the class 
>> should be.  If it can't because that gives assess to something that 
>> could potentially be misused by the world outside the class, thats a 
>> case to make it a member.  Therefore you get this highly easy to use 
>> class that is less bug prone.  It knows what is job is, its small so its 
>> easy to maintain.
>>
> 
> I agree so far...
> 
>>> In particular the getter/setter/property pattern is
>>> encouraged by such a design, and overuse of this pattern can degrade a
>>> class to a simple aggregation of data, defeating the purpose of
>>> encapsulation entirely.
>> This is true.  I don't think the example of a point was the best 
>> example. Herb Sutter and Bjarne Stroustrup's often argue that if the 
>> class variables have not constraints (invariants) then the class should 
>> really be a C struct (where everything is public).
> 
> I disagree here, because you are making the assumption that there
> will never be a need to refactor

No such assumption is present.  In fact, quite the reverse;
KISS helps to keep refactoring easy, by dumping unnecessary
complexity that impedes change.  And also for one more reason,
that you touch on further down...

> (with D's property syntax, this is somewhat mitigated since a
> public field can be turned into a method without breaking client
> code, however if something that was a stack-allocated class later
> needs to be given dynamic dispatch, this is not as much as possibility).
> 
> Further, however, this mindset encourages thinking of classes/structs
> as aggregations of data.

It doesn't, but that's the reason why it's helpful when keeping
code amenable to refactoring.

Sometimes types are present to express behavior.  Those should
be designed in terms of operations, with the representaton of
their state hidden.

Other types genuinely are just collections of data.  Such are
rarer than beginner programmers tend to think, but more common
than many OO textbooks would tend to admit.

It's the "mere aggregations of data" that are mostly clearly
expressed in terms of data.

It's true that once in a while, during evolution of a system,
something that was just dumb data turns out to be usefully
converted into a smarter object.  If you ruthlessly kept your
code simple (e.g., by using simple structs where appropriate)
then (in C++ at least) it's trivial to make such a change (as
C++ has less difference between struct and class than current
D).  If you build in speculative complexity in case of change,
you ironically end up making evolution harder.

(This is one of the pieces of XP that I've found has held up
well in the face of experience and experimentation.)

> For a better example than a point, think
> about an AST node in a compiler (what I was thinking about
> when I wrote the OP, though now we're pretty off-topic).
> A generalized AST node will have a set of children and a
> parent, and a subclass implementing a conditional expression
> may have a condition, a then expresson and an else expression.
> It's possible that all this should be properties with getters
> and setters. However, if you think more deeply about it (I'd
> suggest staring at a picture of a bonsai tree...), the parent,
> condition, then expression and else expression will only be set
> once, and, depending on how you generate the tree, this may be
> at construction time. So, having setters for these properties
> is unnecessary and potentially dangerous if other coders will
> be using your class.

Right; a bunch of setters/getters is worse than either (a) a
simple data object or (b) an object exposing behavior and hiding
unnecessary access to its state.

> In fact, very few classes I write have explicit getters/setters
> /properties. Classes, IMO, are aggregations of methods, not data,
> and the data serves to hold state relating to invocations of
> those methods.

That's the common case; I think Bjarne, Herb, Scott etc. are
assuming that you know this, and highlighting the exceptions.

-- James



More information about the Digitalmars-d mailing list