Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

The Visitor pattern

14 views
Skip to first unread message

angela....@madison-wellington.co.nz

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Hi,

I am reading through the GOF book and I don't understand the visitor pattern.
Would people who have used this pattern (or understand it) be able to provide
me with some more examples (preferably simple, more business domain
orientated ones). Alternatively if you have seen another article, web page
etc that delves into the Visitor pattern could you please point me in that
direction.

Regards,

Angela Sharples

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum

Rick Ratliff

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
On Mon, 20 Jul 1998 03:58:30 GMT,
angela....@madison-wellington.co.nz wrote:

>Hi,
>
>I am reading through the GOF book and I don't understand the visitor pattern.
>Would people who have used this pattern (or understand it) be able to provide
>me with some more examples (preferably simple, more business domain
>orientated ones). Alternatively if you have seen another article, web page
>etc that delves into the Visitor pattern could you please point me in that
>direction.
>

Here's an example of the last time I used the visitor in a design:

There is a Pipe class which contains elements all derrived from a
common base class Record.

Class Filter is a reader of the pipe and needs to do different things
with the data read from the pipe depending on what kind of
specialization Record is read from the pipe.

The Record specializations are Header, Data, Trailer.

The Filter implements a method for each specialization of Record,
processHeader(Header aHeader), processData(Data aData),
processTrailer(Trailer, aTrailer).

The Record implements a method visitFilter(Filter aFilter).

When the Filter reads a Record from the Pipe it invokes the method
visitFilter(this). Depending on the specialization of Record, one of
Filter's processBlahBlah() methods is invoked.

To use this pattern you should have a small limited number of
visitors. If the number of visitors is large than I think you need a
better plan.


>Regards,
>
>Angela Sharples
>
>-----== Posted via Deja News, The Leader in Internet Discussion ==-----
>http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum

Rick Ratliff - OO Mentor ** voice:(804)749-3170 fax:(804)749-3170
Object Systems Group, Inc. ** http://www.ratliff.org/rick/
1950 Stemmons Frwy, Dallas, TX 75207 *** email:ri...@ratliff.org

Steve Burgess

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
You might like to check out:
'A Little Java, a Few Patterns'
Matthias Felleisen and Daniel P. Friedman
MIT Press ISBN: 0262561158


The contents of this message express only the sender's opinion.
This message does not necessarily reflect the policy or views of
my employer, Merck & Co., Inc. All responsibility for the statements
made in this Usenet posting resides solely and completely with the
sender.

Bruno Conductier

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
angela....@madison-wellington.co.nz wrote:

> ................ Alternatively if you have seen another article, web page


> etc that delves into the Visitor pattern could you please point me in that
> direction.

http://www.research.ibm.com/sop/sopcvisp.htm

http://www.oma.com/Publications/publications.html
( http://www.oma.com/PDF/acv.pdf )

Bruno

Dave Griffiths

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
In article <35b322c...@news-s01.ny.us.ibm.net>, Rick Ratliff
<URL:mailto:ri...@ratliff.org> wrote:

> There is a Pipe class which contains elements all derrived from a
> common base class Record.
>
> Class Filter is a reader of the pipe and needs to do different things
> with the data read from the pipe depending on what kind of
> specialization Record is read from the pipe.
>
> The Record specializations are Header, Data, Trailer.
>
> The Filter implements a method for each specialization of Record,
> processHeader(Header aHeader), processData(Data aData),
> processTrailer(Trailer, aTrailer).
>
> The Record implements a method visitFilter(Filter aFilter).
>
> When the Filter reads a Record from the Pipe it invokes the method
> visitFilter(this). Depending on the specialization of Record, one of
> Filter's processBlahBlah() methods is invoked.

Unless you've got some sort of religious hangup about them, you're better
off using switch statements and RTTI than a visitor pattern for this case.
That way you keep everything to do with Filter processing encapsulated in
the Filter class where it belongs, rather than sticking some of it in the
Record class (why should a Record know about its users?).

BTW, the GOF book is about patterns that people have adopted. That doesn't
necessarily mean that they're the best way of doing things. A lot of is down
to taste.

Dave

John Goodsen

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to
>>
>>I am reading through the GOF book and I don't understand the visitor
pattern.
>>Would people who have used this pattern (or understand it) be able to
provide
>>me with some more examples (preferably simple, more business domain
>>orientated ones). Alternatively if you have seen another article, web

page
>>etc that delves into the Visitor pattern could you please point me in that
>>direction.
>>
>
>Here's an example of the last time I used the visitor in a design:
>
>There is a Pipe class which contains elements all derrived from a
>common base class Record.
>
>Class Filter is a reader of the pipe and needs to do different things
>with the data read from the pipe depending on what kind of
>specialization Record is read from the pipe.
>
>The Record specializations are Header, Data, Trailer.
>
>The Filter implements a method for each specialization of Record,
>processHeader(Header aHeader), processData(Data aData),
>processTrailer(Trailer, aTrailer).
>
>The Record implements a method visitFilter(Filter aFilter).
>
>When the Filter reads a Record from the Pipe it invokes the method
>visitFilter(this). Depending on the specialization of Record, one of
>Filter's processBlahBlah() methods is invoked.
>
>To use this pattern you should have a small limited number of
>visitors. If the number of visitors is large than I think you need a
>better plan.
>

(Hi Rick)

If the number of visitors get's large, you might look at Robert Martin's
Acyclic Visitor Pattern. It removes all the nasty dependency issues in
*large* visitors. It's one of the papers on their web site: www.oma.com.

--
John Goodsen Saguaro Software, Inc. / Training & Consulting in:
jgoo...@saguarosoft.com - User Centered Systems Analysis
http://www.saguarosoft.com - Object Oriented Architecture and Design
602.283.0142 / 888.298.2566 - Rapid Incremental Delivery S/W Process

"Example isn't another way to teach, it is the only way to teach. "
- Albert Einstein

da...@prim.demon.co.uk

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to
In article <6p17tf$5...@examiner.concentric.net>,
"John Goodsen" <jgoo...@saguarosoft.com> wrote:

> If the number of visitors get's large, you might look at Robert Martin's
> Acyclic Visitor Pattern. It removes all the nasty dependency issues in
> *large* visitors. It's one of the papers on their web site: www.oma.com.

I checked it out. This pattern business is getting out of hand. RM manages to
make a very straightforward problem sound exceedingly complicated. He starts
with a daft idea - the Visitor Pattern - sees that it's not quite right, but
instead of ditching it in favour of something simpler, he crafts on an
additional layer of complexity and gives it a grand sounding title. The
Acyclic Visitor Pattern. Oh yes.

Let me introduce you to "The Switch Statement Pattern". This has actually
been around now for at least thirty years, but people appear to have
forgotten about it. It's wonderously simple. What you do in a situation like
that described by RM is you add a type field to your Modem class (a type
field! the horror, the horror! it gets worse...). Then your ConfigureForUnix
method simply does a switch based on the modem type. It's so easy! It's so
flexible!

Ah, but you don't get to be a priest in a new religion by telling people
things they already knew.

Dave

John Goodsen

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to

da...@prim.demon.co.uk wrote in message <6p2b35$gmo$1...@nnrp1.dejanews.com>...

>In article <6p17tf$5...@examiner.concentric.net>,
> "John Goodsen" <jgoo...@saguarosoft.com> wrote:
>
>> If the number of visitors get's large, you might look at Robert Martin's
>> Acyclic Visitor Pattern. It removes all the nasty dependency issues in
>> *large* visitors. It's one of the papers on their web site: www.oma.com.
>
>I checked it out. This pattern business is getting out of hand. RM manages
to
>make a very straightforward problem sound exceedingly complicated. He
starts
>with a daft idea - the Visitor Pattern - sees that it's not quite right,
but
>instead of ditching it in favour of something simpler, he crafts on an
>additional layer of complexity and gives it a grand sounding title. The
>Acyclic Visitor Pattern. Oh yes.
>
>Let me introduce you to "The Switch Statement Pattern". This has actually
>been around now for at least thirty years, but people appear to have
>forgotten about it. It's wonderously simple. What you do in a situation
like
>that described by RM is you add a type field to your Modem class (a type
>field! the horror, the horror! it gets worse...). Then your
ConfigureForUnix
>method simply does a switch based on the modem type. It's so easy! It's so
>flexible!
>

There are other forces at work. Using switch statements, you have to
modify *EXISTING* code whenever you want to extend a system. This is a
nasty side-effect and we call it a violation of the open-closed principle.
The system is no longer open for extension but closed to changes.

Worse yet, those simple little switch turn into maintenance headaches as
they tend to replicate themselves all over the system. Polymorphism
and abstraction are much more useful tools to manage these dependencies,
IMHO.

>Ah, but you don't get to be a priest in a new religion by telling people
>things they already knew.


I am not religious about patterns as some are - but when they are useful,
I point people to them... regardless of what they are called or how
religious
others are about it... :-)

John Goodsen

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to
>
>I checked it out. This pattern business is getting out of hand. RM manages
to
>make a very straightforward problem sound exceedingly complicated. He
starts
>with a daft idea - the Visitor Pattern - sees that it's not quite right,

Not only is the visitor "not quite right", IMHO, it is fatally flawed in
it's
lack of dependency management. Of all the GOF patterns, this one
takes the most negative hits when you evaluate it wrt. to dependency
management.

> but
>instead of ditching it in favour of something simpler, he crafts on an
>additional layer of complexity and gives it a grand sounding title.
>

Actually, he applies the Interface Segregation Principle to an existing
problem to create a resulting solution that is more flexible and resilient
to change.

I think it was B. Meyer who said you can measure the "OO-ness" of a
system by counting the number of switch statements it doesn't contain.

Nick Mein

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
angela....@madison-wellington.co.nz wrote:
>
> I am reading through the GOF book and I don't understand the visitor pattern.
> Would people who have used this pattern (or understand it) be able to provide
> me with some more examples (preferably simple, more business domain
> orientated ones).

I work on a pre-harvest forest inventory software product. An Inventory
consists of Plots. Each Plot contains a number of Trees. Trees are made
up of SubTrees (main stem, forks, merchantable branches). All of these
classes are Elements. A Processor is a Visitor that visits the Elements
in an Inventory, simulating felling and cross-cutting and accumulating
statistics.

Use of a Visitor-like pattern in this software dates back to at least
1989. The 1989 version was implemented in C, using function pointers to
achieve dynamic dispatch. In addition to the Processor described above,
a growth-projection Visitor was added a year later.

--
Nick Mein
Forest Research
Rororua, New Zealand.

John Goodsen

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to

>
>There are other forces at work. Using switch statements, you have to
>modify *EXISTING* code whenever you want to extend a system. This is a
>nasty side-effect and we call it a violation of the open-closed principle.
>The system is no longer open for extension but closed to changes.

^^^^^

*and* (not but)

da...@prim.demon.co.uk

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
In article <6p3h1g$6...@examiner.concentric.net>,
"John Goodsen" <jgoo...@saguarosoft.com> wrote:

> There are other forces at work. Using switch statements, you have to
> modify *EXISTING* code whenever you want to extend a system. This is a
> nasty side-effect and we call it a violation of the open-closed principle.
> The system is no longer open for extension but closed to changes.

Oh no, more gibberish. Take a look at the paper in question. If you add
a new modem type and it needs configuring for Unix, you have to add a
new method to the ConfigureForUnixVisitor class to implement Visit for
the new modem type. This is what we call modifying existing code. And
it's no different from adding a new case to a switch statement.

As for "maintenance headaches" - the simpler a piece of code is, the
easier it is to maintain. Use of switch statements is undeniably simpler
than the "Acyclic Visitor Pattern". Look at the headaches that are being
produced amongst novice programmers as they struggle to understand
the reasoning behind these pointless mechanisms.

Rick Ratliff

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
On Mon, 20 Jul 1998 17:13:45 +0100 (BST), Dave Griffiths
<dgri...@acorn.co.uk> wrote:

>In article <35b322c...@news-s01.ny.us.ibm.net>, Rick Ratliff
><URL:mailto:ri...@ratliff.org> wrote:
>

[my visitor pattern example deleted]


>
>Unless you've got some sort of religious hangup about them, you're better
>off using switch statements and RTTI than a visitor pattern for this case.

I'd rather fight than switch.

I always start with the assumption that a switch statement in my
object-oriented implementation is an error, and try to justify it, if
I can't find alternatives.

>That way you keep everything to do with Filter processing encapsulated in
>the Filter class where it belongs, rather than sticking some of it in the
>Record class (why should a Record know about its users?).

It only knows to invoke a single method on an interface that it gets
passed as a method argument. I would agree there is a coupling, but in
a very abstract way.

>
>BTW, the GOF book is about patterns that people have adopted. That doesn't
>necessarily mean that they're the best way of doing things. A lot of is down
>to taste.
>

I was trying to answer a question about the visitor pattern and how it
can be used. I throught the request was for clarification of the
pattern as it is written in the GOF book not for a justification of
its goodness.

>Dave

Steven Kefford

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to

da...@prim.demon.co.uk wrote in message <6p2b35$gmo$1...@nnrp1.dejanews.com>...
....

>I checked it out. This pattern business is getting out of hand. RM manages
to
>make a very straightforward problem sound exceedingly complicated. He
starts
>with a daft idea - the Visitor Pattern - sees that it's not quite right,
but
>instead of ditching it in favour of something simpler, he crafts on an
>additional layer of complexity and gives it a grand sounding title. The
>Acyclic Visitor Pattern. Oh yes.
>
>Let me introduce you to "The Switch Statement Pattern". This has actually
>been around now for at least thirty years, but people appear to have
>forgotten about it. It's wonderously simple. What you do in a situation
like
>that described by RM is you add a type field to your Modem class (a type
>field! the horror, the horror! it gets worse...). Then your
ConfigureForUnix
>method simply does a switch based on the modem type. It's so easy! It's so
>flexible!
>
>Ah, but you don't get to be a priest in a new religion by telling people
>things they already knew.

You certainly don't with the style of communication used here.
-----------------------------------------------------------
Steven Kefford
(+44) (0)1438 739669
s.ke...@mia.co.uk*remove-this*


da...@prim.demon.co.uk

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
In article <6p3h7m$7...@examiner.concentric.net>,
"John Goodsen" <jgoo...@saguarosoft.com> wrote:

> I think it was B. Meyer who said you can measure the "OO-ness" of a
> system by counting the number of switch statements it doesn't contain.

And you can measure a programmer's creativity by the number of rules they
don't obey. The switch statement is your friend. If it provides the simplest
solution, use it. BTW, this may reinforce any prejudices anyone has against
Java, but I just counted the number of switch statements in the 1.2 classes:

1784.

:)

Tom Kreitzberg

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
Rick Ratliff writes:

> I'd rather fight than switch.
>
> I always start with the assumption that a switch statement in my
> object-oriented implementation is an error, and try to justify it, if
> I can't find alternatives.

I've got a set of port-watching classes to deal with messages
that arrive from different ports. The first few bytes of each
message identify the message type; for each message type, a
different action is required. A port-watching class has to worry
about at most twenty messages.

Knowing that switch statements are a bad thing, and that the
set of messages and the behavior each implied were among the
most dynamic parts of the system, I came up with a design
that avoided switch statements, satisfied the open-closed
principle, and was laughably complex. Since I was the one
who had to implement my design, I scrapped it for one using
switch statements.

Is there a suitably OO "multiple message type" pattern, or
am I justified in using switch statements there?

Tom

--
Tom Kreitzberg | The Johns Hopkins University
Tom.Kre...@jhuapl.edu | Applied Physics Laboratory

Michael Schuerig

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
Tom Kreitzberg <Tom.Kre...@jhuapl.edu> wrote:

Use a state machine. Unless Robert Martin has already replied
accordingly look at <http://www.oma.com/> in the "Freeware by Mail"
section. :-)

Michael

--
Michael Schuerig
mailto:schu...@acm.org
http://www.uni-bonn.de/~uzs90z/

John Goodsen

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
da...@prim.demon.co.uk wrote in message <6p4hr9$5vo$1...@nnrp1.dejanews.com>...
>In article <6p3h1g$6...@examiner.concentric.net>,

> "John Goodsen" <jgoo...@saguarosoft.com> wrote:
>
>> There are other forces at work. Using switch statements, you have to
>> modify *EXISTING* code whenever you want to extend a system. This is a
>> nasty side-effect and we call it a violation of the open-closed
principle.
>> The system is no longer open for extension but closed to changes.
>
>Oh no, more gibberish. Take a look at the paper in question. If you add
>a new modem type and it needs configuring for Unix, you have to add a
>new method to the ConfigureForUnixVisitor class to implement Visit for
>the new modem type. This is what we call modifying existing code. And
>it's no different from adding a new case to a switch statement.


Yes, but you don't have to recompile the *entire* Modem hierarchy
and any clients that depend upon that hierarchy as you would have
to in the GOF Visitor pattern. I agree with Rick Ratliff's motto on this
topic: I'd rather fight than *switch* - or maybe it should be:

I'd rather (dis)patch than *switch* ? :-)


>As for "maintenance headaches" - the simpler a piece of code is, the
>easier it is to maintain. Use of switch statements is undeniably simpler
>than the "Acyclic Visitor Pattern".

I might agree here, as long as I am sure that this is the ONE AND ONLY
place in the entire system where I'm going to see a switch statement
on the visitor types. How can you gaurantee that this will be the case
after introducing your enums into the system? You still have the
recompilation issues, and in some environments this means
re-shipping and re-testing code that has not been changed but
only re-compiled (e.g. in Avionics systems or medical systems
for example, where testing of software can account for over 75%
of the total software development budget)... it's not always as
economically simple as we would like it to sound...

>Look at the headaches that are being
>produced amongst novice programmers as they struggle to understand
>the reasoning behind these pointless mechanisms.
>

Clearly the Visitor is a complex pattern. It breaks several design
principles. The acyclic visitor addresses the design principle violations.

If you are still more comfortable with your switch statements, then my
advise is to continue using them and don't lose any sleep over it, but
I only give this advise to clients after I am sure that they understand the
repercussions of their design.

In large systems, maintaining switch statements is much more of a
headache, and if your using language other than Ada, Eiffel or others
that enforce complete coverage of enumerations in switch
statements, you are opening your system up for strange run-time
defects that are hard to debug later down the road, as people
change the enums.... but forget to change all of the various
switch statements that tend to become spread across the system.

pgoo...@my-dejanews.com

unread,
Jul 23, 1998, 3:00:00 AM7/23/98
to
In article <35B64200...@jhuapl.edu>,

Tom Kreitzberg <Tom.Kre...@jhuapl.edu> wrote:
> Rick Ratliff writes:
>
> > I'd rather fight than switch.
> >
> > I always start with the assumption that a switch statement in my
> > object-oriented implementation is an error, and try to justify it, if
> > I can't find alternatives.
>
> I've got a set of port-watching classes to deal with messages
> that arrive from different ports. The first few bytes of each
> message identify the message type; for each message type, a
> different action is required. A port-watching class has to worry
> about at most twenty messages.
>
> Knowing that switch statements are a bad thing, and that the
> set of messages and the behavior each implied were among the
> most dynamic parts of the system, I came up with a design
> that avoided switch statements, satisfied the open-closed
> principle, and was laughably complex. Since I was the one
> who had to implement my design, I scrapped it for one using
> switch statements.
>
> Is there a suitably OO "multiple message type" pattern, or
> am I justified in using switch statements there?


Depends on what you really need. Avoiding switch statements provides certain
benefits which, of course, are only valuable if you're going to take
advantage of them. In your case I would anticipate that you're going to want
to add new messages. If that is the case it would be nice to be able to do it
by adding new code instead of modifying code that you've already written
(OCP). In that case I'd (probably) implement the message types as classes
derived from an abstract base. I would use an associative container (like an
STL map) and the GOF Prototype pattern to associate incomming messages with
instances of the correct type. I'd have the classes register themselves with
the associative container at start-up time. When a new message came in I'd
use those first few bytes as the key to my associative container, retrieve a
prototype message object of the correct type, and use it to create a new
message object which in turn would read in the rest of the message data. When
the time came to handle a new type of message all I'd have to do is create a
new class to handle it. On the other hand, if I'm never going to use the
flexibility then I won't bother with implementing it -- it's way easier to do
it with a switch statement.

Phil

Zoran Ivanovic

unread,
Jul 23, 1998, 3:00:00 AM7/23/98
to
Tom Kreitzberg wrote:

> I've got a set of port-watching classes to deal with messages
> that arrive from different ports. The first few bytes of each
> message identify the message type; for each message type, a
> different action is required. A port-watching class has to worry
> about at most twenty messages.
>
> Knowing that switch statements are a bad thing, and that the
> set of messages and the behavior each implied were among the
> most dynamic parts of the system, I came up with a design
> that avoided switch statements, satisfied the open-closed
> principle, and was laughably complex. Since I was the one
> who had to implement my design, I scrapped it for one using
> switch statements.
>
> Is there a suitably OO "multiple message type" pattern, or
> am I justified in using switch statements there?
>

> Tom
>
> --
> Tom Kreitzberg | The Johns Hopkins University
> Tom.Kre...@jhuapl.edu | Applied Physics Laboratory

Hi Tom,
I was working on very similar things, and result of that was paper
submitted to EuroPLoP '98 conference. You can get copy of this
paper from their web. Please note, paper is still in early writing stage.

I named this pattern TriggerValue Pattern.

Kent Beck, reviewing this paper, was saying that is variation of
Command Processor pattern, so you might look at that as well.

Best regards,
Zoran I.


rma...@oma.com

unread,
Jul 29, 1998, 3:00:00 AM7/29/98
to
In article <ant20164...@om107.acorn.co.uk>,
Dave Griffiths <dgri...@acorn.co.uk> wrote:

<< regarding the use of Visitor in Filters >>


>
> Unless you've got some sort of religious hangup about them, you're better
> off using switch statements and RTTI than a visitor pattern for this case.

> That way you keep everything to do with Filter processing encapsulated in
> the Filter class where it belongs, rather than sticking some of it in the
> Record class (why should a Record know about its users?).

In the visitor case, the Record class knows nothing. The only concession it
makes is the 'accept(RecordVisitor&)' method; and that method is abstract
(pure virtual). So, the Record class knows nothing of its users.

On the other hand, if we use a switch statement, that switch statement has to
switch on something; probably an enum. Where is this enum defined? Probably
in some RecordTypes.h file, or perhaps as static constants in the Record base
class. In either case, the user of *any* record has a dependency on *all*
record types. When a new record type is added, the enum must be altered, and
everybody who #includes RecordTypes.h will recompile.

If we use RTTI, then we may have a long chain of if/else statements with
typeid comparisons. This can be very slow.

Visitor, on the other hand, is very fast (two polymorphic dispatches at most),
and does not use an enum that needs to be updated. So it is a much better
solution than either a switch or a set of if/else statements.

Visitor does have a problem, however, each of the derivatives of Record
depend upon the visitor interface; and the visitor interface names *all* of
the derivatives of Record. Thus the derivatives of Record depend upon each
other in an indirect way. If a new derivative of Record is created, all
existing derivatives must recompile.

Even this small dependency knot can be eliminated by using the Acyclic
Visitor (see the paper in the 'publications' section of my website) which
makes use of dynamic_cast in each derivative of Record. This adds the cost
of a dynamic_cast to the visitor, but breaks the dependency cycle.

rmart...@my-dejanews.com

unread,
Jul 29, 1998, 3:00:00 AM7/29/98
to
In article <35B64200...@jhuapl.edu>,
Tom Kreitzberg <Tom.Kre...@jhuapl.edu> wrote:

> I've got a set of port-watching classes to deal with messages
> that arrive from different ports. The first few bytes of each
> message identify the message type; for each message type, a
> different action is required. A port-watching class has to worry
> about at most twenty messages.
>
> Knowing that switch statements are a bad thing, and that the
> set of messages and the behavior each implied were among the
> most dynamic parts of the system, I came up with a design
> that avoided switch statements, satisfied the open-closed
> principle, and was laughably complex. Since I was the one
> who had to implement my design, I scrapped it for one using
> switch statements.

Take care that you do not trade maintainability away in
order to reduce "complexity". It may be that the switch
statement makes the code easier to read; but harder to
maintain. What is the impact of adding a new messsage
type? How many modules must recomple? How many DLLs must
be reshipped?

If the answer is "not very many", and if the answer always
will be "not very many", then your switch statement approach
is probably safe. Or if your answer is that new messages types
are very infrequent, then you many also be safe.

On the other hand, you may also have laid the groundwork for
a disaster. If there is suddenly a proliferation of message
types; and each new message type causes the entire system to
be recompiled and reshipped; then folks are going to learn
to hate the simplicity of the switch statement that is
causing the thrashing.

Yes, the visitor approach is a bit more complex. Although
I doubt that it is "laughably" more complex. And the Visitor
has the nice feature that you can substitute different visitors
for different states of the system; so it is quite a bit more
flexible.

I prefer to use Visitor (or Acyclic Visitor) in preference to
switch statements in nearly every case.

rma...@oma.com

unread,
Jul 29, 1998, 3:00:00 AM7/29/98
to
In article <6p2b35$gmo$1...@nnrp1.dejanews.com>,
da...@prim.demon.co.uk wrote:
> In article <6p17tf$5...@examiner.concentric.net>,

> "John Goodsen" <jgoo...@saguarosoft.com> wrote:
>
> > If the number of visitors get's large, you might look at Robert Martin's
> > Acyclic Visitor Pattern. It removes all the nasty dependency issues in
> > *large* visitors. It's one of the papers on their web site: www.oma.com.
>
> I checked it out. This pattern business is getting out of hand. RM manages to
> make a very straightforward problem sound exceedingly complicated. He starts
> with a daft idea - the Visitor Pattern - sees that it's not quite right, but
> instead of ditching it in favour of something simpler, he crafts on an
> additional layer of complexity and gives it a grand sounding title. The
> Acyclic Visitor Pattern. Oh yes.
>
> Let me introduce you to "The Switch Statement Pattern". This has actually
> been around now for at least thirty years, but people appear to have
> forgotten about it. It's wonderously simple. What you do in a situation like
> that described by RM is you add a type field to your Modem class (a type
> field! the horror, the horror! it gets worse...). Then your ConfigureForUnix
> method simply does a switch based on the modem type. It's so easy! It's so
> flexible!

Switch statements are very convenient for the programmer; but much less
convenient for the maintainer. The problem with switch statements is that
they depend upon a case variable. And that case variable must be declared
somewhere. Everyone who uses the objects controlled by the case variable
depends upon that declaration. When new cases are added the declaration of
the case variable changes, and a very large amount of recompilation, and
retesting, re-releasing, and redistribution ensues.

The use of Visitor, or Acyclic Visitor, reduces the amount of recompilation,
etc, by getting rid of the case variable. When new cases are added, there is
no case variable to change, and so there is very little recompilation, etc.

Those of us who have lived through the nightmare of large highly
interdependent systems are happy to use visitors, or acyclic visitors, to
stave of the resultant problems.

rma...@oma.com

unread,
Jul 29, 1998, 3:00:00 AM7/29/98
to
In article <6p4hr9$5vo$1...@nnrp1.dejanews.com>,
da...@prim.demon.co.uk wrote:
> In article <6p3h1g$6...@examiner.concentric.net>,

> "John Goodsen" <jgoo...@saguarosoft.com> wrote:
>
> > There are other forces at work. Using switch statements, you have to
> > modify *EXISTING* code whenever you want to extend a system. This is a
> > nasty side-effect and we call it a violation of the open-closed principle.
> > The system is no longer open for extension but closed to changes.
>
> Oh no, more gibberish. Take a look at the paper in question. If you add
> a new modem type and it needs configuring for Unix, you have to add a
> new method to the ConfigureForUnixVisitor class to implement Visit for
> the new modem type. This is what we call modifying existing code. And
> it's no different from adding a new case to a switch statement.

It's acutally quite a bit different. There is no case variable to alter; and
therefore the impact of the change is substantially smaller. i.e. nobody
depends upon modemTypes.h.


>
> As for "maintenance headaches" - the simpler a piece of code is, the
> easier it is to maintain.

This is a pleasing maxim, but quite incorrect. Understanding the code is
just one aspect of maintaining the code. Haven't you ever faced the problem
of knowing exactly what had to be done, but also knowing that the impact
would be *huge*? Which would you rather maintain, a simple system where
making a change forces you to alter and recompile dozens of source files; or
a complex system that takes you a little longer to figure out, but once
understood allows you to make changes by changing and recompiling *one*
source file?

Switch statements tend to create the former types, whereas visitors tend to
create the later.

> Use of switch statements is undeniably simpler

> than the "Acyclic Visitor Pattern". Look at the headaches that are being


> produced amongst novice programmers as they struggle to understand
> the reasoning behind these pointless mechanisms.
>

> Dave

rmart...@my-dejanews.com

unread,
Jul 29, 1998, 3:00:00 AM7/29/98
to
In article <6p52ak$qu8$1...@nnrp1.dejanews.com>,
da...@prim.demon.co.uk wrote:
> In article <6p3h7m$7...@examiner.concentric.net>,

> "John Goodsen" <jgoo...@saguarosoft.com> wrote:
>
> > I think it was B. Meyer who said you can measure the "OO-ness" of a
> > system by counting the number of switch statements it doesn't contain.
>
> And you can measure a programmer's creativity by the number of rules they
> don't obey. The switch statement is your friend. If it provides the simplest
> solution, use it. BTW, this may reinforce any prejudices anyone has against
> Java, but I just counted the number of switch statements in the 1.2 classes:
>
> 1784.
>

Switch statement aren't evil. They just need to be used judiciously. I have
a simple rule that I follow. I will use a switch statement only in those
cases where each case statement constructs an object. That is, I will use a
switch statement to determine which derivative to create. All other
dispatches are thereafter done polymorphically through the base class
interface.


> :)

Tom Kreitzberg

unread,
Jul 29, 1998, 3:00:00 AM7/29/98
to
rmart...@my-dejanews.com writes:

> Take care that you do not trade maintainability away in
> order to reduce "complexity". It may be that the switch
> statement makes the code easier to read; but harder to
> maintain. What is the impact of adding a new messsage
> type? How many modules must recomple? How many DLLs must
> be reshipped?

The entire application is under 10,000 lines, and is a
proof-of-concept prototype. (And no, I probably won't be
at the meeting where they decide to turn this into a
full-up system to be installed in 400 sites by the end
of the year.)

> Yes, the visitor approach is a bit more complex. Although
> I doubt that it is "laughably" more complex.

I wrote that *my* design was "laughably complex," for the
scope of the application. I don't think the Visitor pattern
itself applies to the problem of multiple message types,
does it? (By "message type," I mean a Message object with
a given messageID attribute, representing a request to do
this or that specific task.)

Rolf F. Katzenberger

unread,
Jul 30, 1998, 3:00:00 AM7/30/98
to
On Wed, 29 Jul 1998 13:29:08 -0400, in article
<35BF5BE4...@jhuapl.edu> Tom Kreitzberg
<Tom.Kre...@jhuapl.edu> wrote:

> rmart...@my-dejanews.com writes:
[snip]


> > Yes, the visitor approach is a bit more complex. Although
> > I doubt that it is "laughably" more complex.
>
> I wrote that *my* design was "laughably complex," for the
> scope of the application. I don't think the Visitor pattern
> itself applies to the problem of multiple message types,
> does it? (By "message type," I mean a Message object with
> a given messageID attribute, representing a request to do
> this or that specific task.)

You could develop an abstract base class Task and derive your concrete
tasks from it. A map could be used to map message-IDs to task. This
would give you the extra flexibility to be able to reconfigure your
task implementations at runtime.

Regards,
Rolf

--
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

______________________________________________________________________
Rolf F. Katzenberger | Software Developer | Trainer 1998-04-28
Home: http://www.geocities.com/SiliconValley/Park/9557
PGP : http://wwwkeys.pgp.net:11371/pks/lookup?op=get&search=0x3B39491F
(Fingerprint F1C0 3116 F6D4 DA33 E61D D2E4 2FB8 D6B6 3B39 491F)
-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.5.3i for non-commercial use

iQA/AwUBNUX84C+41rY7OUkfEQLV8wCfb/IQACmn+qvT+EIftYMx36ivdRoAoNdF
ugze6Ry3oCiwMtGLSKXHOnqs
=+QML
-----END PGP SIGNATURE-----

Hubert Matthews

unread,
Jul 31, 1998, 3:00:00 AM7/31/98
to
rmart...@my-dejanews.com wrote:

> In article <35B64200...@jhuapl.edu>,
> Tom Kreitzberg <Tom.Kre...@jhuapl.edu> wrote:
>
> > I've got a set of port-watching classes to deal with messages
> > that arrive from different ports. The first few bytes of each
> > message identify the message type; for each message type, a
> > different action is required. A port-watching class has to worry
> > about at most twenty messages.
> >
> > Knowing that switch statements are a bad thing, and that the
> > set of messages and the behavior each implied were among the
> > most dynamic parts of the system, I came up with a design
> > that avoided switch statements, satisfied the open-closed
> > principle, and was laughably complex. Since I was the one
> > who had to implement my design, I scrapped it for one using
> > switch statements.
>

> Take care that you do not trade maintainability away in
> order to reduce "complexity". It may be that the switch
> statement makes the code easier to read; but harder to
> maintain. What is the impact of adding a new messsage
> type? How many modules must recomple? How many DLLs must
> be reshipped?

The switch statement or a close equivalent is probably unavoidable in this
case. Why? Because we are converting from the non-object world of plain
old bytes (the first few bytes of the message header) to the object world
of types understood by the compiler. This fits into your rule about using
a switch only to return generated objects. Only after such a conversion
can one use polymorphic dispatch.

What is the effect of adding another message type? You must add a case to
the switch statement to create an object of the new type, which then
contains all of the relevant code for message handling using direct
polymorphic dispatch or any variant of the Visitor pattern. How many
modules need recompiling? The one module with the switch and the module
with the new message class. How many DLLs must be reshipped? That depends
upon the packaging strategy you use but.

Some switch statements just won't go away. This is, IMO, one of them.

Hubert

David Griffiths

unread,
Aug 11, 1998, 3:00:00 AM8/11/98
to
rma...@oma.com wrote:

> Switch statements are very convenient for the programmer; but much less
> convenient for the maintainer. The problem with switch statements is that
> they depend upon a case variable. And that case variable must be declared
> somewhere. Everyone who uses the objects controlled by the case variable
> depends upon that declaration. When new cases are added the declaration of
> the case variable changes, and a very large amount of recompilation, and
> retesting, re-releasing, and redistribution ensues.
>
> The use of Visitor, or Acyclic Visitor, reduces the amount of recompilation,
> etc, by getting rid of the case variable. When new cases are added, there is
> no case variable to change, and so there is very little recompilation, etc.
>
> Those of us who have lived through the nightmare of large highly
> interdependent systems are happy to use visitors, or acyclic visitors, to
> stave of the resultant problems.

I'm surprised you find much time for all this maintenance work you do
what with the teaching and the papers to write and so on. Presumably you
write from long personal experience. I work as a contractor, I've worked
at, how many? 15 companies. Dunno, lost count. Point is though, I've
done loads and loads of this maintenance stuff and I don't recognize the
difficulties you're describing.

You talk about the problem introduced by this modem type enum. Now who
introduced it in the first place? Me. As part of the switch statement
alternative to your acyclic visitor thingy. There are not suddenly
hundreds of mysterious hand wavy dependencies, the only people who
depend on it are the configure methods already mentioned. And they have
to be modified anyway to cater for the new modem type, in just the same
way that your configure classes need new methods adding.

What we need is a competition. Someone sets some requirements plus some
secret set of revisions to the requirements. Then you and I sit down and
code our solutions, followed by the code changes for the revisions. Then
we can see who produces the least amount of code plus changes. We could
even have a little bet on it. :)

Dave

Ell

unread,
Aug 11, 1998, 3:00:00 AM8/11/98
to
rma...@oma.com wrote:
:
: da...@prim.demon.co.uk wrote:
:>
:> Oh no, more gibberish. Take a look at the paper in question. If you add

:> a new modem type and it needs configuring for Unix, you have to add a
:> new method to the ConfigureForUnixVisitor class to implement Visit for
:> the new modem type. This is what we call modifying existing code. And
:> it's no different from adding a new case to a switch statement.

: It's acutally quite a bit different. There is no case variable to alter; and


: therefore the impact of the change is substantially smaller. i.e. nobody
: depends upon modemTypes.h.

Unless no one refers to it, someone has to depend upon any *.h file.
Pointers to abstract classes do not totally eliminate dependency. That's
Basic C++ 101.

It is deception pure and simple against newbie C++ programmers, and
programmers not familiar with C++, for you to repeatedly assert year after
year the blatant falsehood that using pointers to abstract classes somehow
eliminates all dependency. If the abstract class creates objects whose
interface or data layout changes, or if the interface (or data members if
it has it) of the abstract classes changes then the client using the
pointer to the abstract class must recompile. The fact that you never
mention this is incredible. You should be ashamed of yourself for
attempting to prop up your ideas through such deceptive practices.

Elliott
--
:=***=: Objective * Pre-code Modelling * Holistic :=***=:
Hallmarks of the best SW Engineering
"The domain object model is the foundation of OOD."
Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
Copyright 1998 Elliott. exclusive of others' writing. may be copied
without permission only in the comp.* usenet and bitnet groups.

john-...@hlp.com

unread,
Aug 11, 1998, 3:00:00 AM8/11/98
to
In article <35D075AF...@prim.demon.co.uk>,
David Griffiths <da...@prim.demon.co.uk> wrote:
> rma...@oma.com wrote:
>
>[switch statement vs. visitor snipped]

>
> What we need is a competition. Someone sets some requirements plus some
> secret set of revisions to the requirements. Then you and I sit down and
> code our solutions, followed by the code changes for the revisions. Then
> we can see who produces the least amount of code plus changes. We could
> even have a little bet on it. :)
>
> Dave
>

I would like to see something like that. I think that the contention may
arise however on the phrase 'least amount of code' as the criterion.

By the way, if you haven't seen the last 'semi-formal' competition that I
remember on comp.object, check out A Translational Vs. Elaborational View of
Methodology / Shlaer-Mellor Vs. the Unified Method
http://www.sigs.com/publications/docs/oc/9602/oc9602.d.dialog.html

It's one of my favorites, 'cause I'm in the electricity business :)

Cheers,
John

Ell

unread,
Aug 11, 1998, 3:00:00 AM8/11/98
to
john-...@hlp.com wrote:

>By the way, if you haven't seen the last 'semi-formal' competition that I
>remember on comp.object, check out A Translational Vs. Elaborational View of
>Methodology / Shlaer-Mellor Vs. the Unified Method
>http://www.sigs.com/publications/docs/oc/9602/oc9602.d.dialog.html
>
>It's one of my favorites, 'cause I'm in the electricity business :)

And guess who is backing off the so-called Unified Method position.
None other than RCM himself. He now agrees with Mellor that classes
and objects should first of all be considered to be data structures.

Whereas I continue to uphold the position I did back then with RCM
that objects should first be considered as entities with behavioral
responsibility.

Ell

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to
e...@access.digex.net (Ell) wrote:

>john-...@hlp.com wrote:
>
>>By the way, if you haven't seen the last 'semi-formal' competition that I
>>remember on comp.object, check out A Translational Vs. Elaborational View of
>>Methodology / Shlaer-Mellor Vs. the Unified Method
>>http://www.sigs.com/publications/docs/oc/9602/oc9602.d.dialog.html
>>
>>It's one of my favorites, 'cause I'm in the electricity business :)

>And guess who is backing off the so-called Unified Method position.
>None other than RCM himself. He now agrees with Mellor that classes
>and objects should first of all be considered to be data structures.

This tends to vindicate my questioning Booch at the time about his
decision to team with RCM to debate Mellor on this issue at OOPLSA, 3
years ago.

And I still think it is totally wrong for Booch to once again "team"
with RCM on the 3rd edition of OOA&D.

And Booch can not justify this teaming by saying that there is UML
notation - which presumably RCM will mainly be about - which is
narrower than UM methodology. The point is that by teaming with RCM
in any way, Booch is giving credence to the backward, irrational, god
awful, lifeless, sterile stances of RCM.

I guess deep down despite his theory and writing which is mostly
against the reactionary, anti-OOA, anti-holistic, anti-overall
pre-code modelling which RCM espouses, Booch must ultimately support
those kinds of positions.

RCM consistently espouses the worst positions, and practices in the
history of software engineering. He far outstrips his cohorts and
sycophants in breaking new ground advocating the most nasty, hideous,
and nightmarish (to use the self-indicting, extremely ugly, sickening,
demoralizing, and quasi-pathological terms they use whenever they
speak about how they perceive and confront software dependency and
complexity) stances in software engineering and social theory that one
could ever imagine.

>Whereas I continue to uphold the position I did back then with RCM

>[Whitmire, and some others] that objects should first be considered as

Ell

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to
e...@access.digex.net (Ell) wrote:

>I guess deep down despite his theory and writing which is mostly
>against the reactionary, anti-OOA, anti-holistic, anti-overall
>pre-code modelling which RCM espouses, Booch must ultimately support
>those kinds of positions.

And I can't let the fact pass that RCM is ultimately anti-architecture
because he is against enforcing architectural decisions where they are
not being adhered to, even if they have been democratically decided by
all project programmers.

Oren Ben-Kiki

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to

Ell wrote in message <35d21e21...@news.erols.com>...

>e...@access.digex.net (Ell) wrote:
>
>>john-...@hlp.com wrote:
>>
>>>By the way, if you haven't seen the last 'semi-formal' competition that I
>>>remember on comp.object, check out A Translational Vs. Elaborational
View of
>>>Methodology / Shlaer-Mellor Vs. the Unified Method
>>>http://www.sigs.com/publications/docs/oc/9602/oc9602.d.dialog.html
>>>
>>>It's one of my favorites, 'cause I'm in the electricity business :)


I well remember this thread. "They don't make them like they used to". As I
recall, when it ended, there was a promise of a coming convention in which
there would be a panel dedicated to the issue. Did it happen? Does anyone
have a reference to the proceedings?

---
Oren Ben-Kiki

Amit Patel

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to
<da...@prim.demon.co.uk> wrote:
| In article <6p3h1g$6...@examiner.concentric.net>,

| "John Goodsen" <jgoo...@saguarosoft.com> wrote:
|
| > There are other forces at work. Using switch statements, you have to
| > modify *EXISTING* code whenever you want to extend a system. This is a
| > nasty side-effect and we call it a violation of the open-closed principle.
| > The system is no longer open for extension but closed to changes.
|
| Oh no, more gibberish. Take a look at the paper in question. If you add
| a new modem type and it needs configuring for Unix, you have to add a
| new method to the ConfigureForUnixVisitor class to implement Visit for
| the new modem type. This is what we call modifying existing code. And
| it's no different from adding a new case to a switch statement.
|

In addition, you only have to modify existing code when you want to
extend the system with a NEW TYPE. You don't have to extend it when
you want a new METHOD, which is presumably why you're using Visitor
(or switch statements) in the first place -- to be able to add new
functions outside the class that can act differently based on the type
of the object.

- Amit

Robert Martin

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to

David Griffiths wrote in message <35D075AF...@prim.demon.co.uk>...

>rma...@oma.com wrote:
>
>> Switch statements are very convenient for the programmer; but much less
>> convenient for the maintainer. The problem with switch statements is
that
>> they depend upon a case variable. And that case variable must be
declared
>> somewhere. Everyone who uses the objects controlled by the case variable
>> depends upon that declaration. When new cases are added the declaration
of
>> the case variable changes, and a very large amount of recompilation, and
>> retesting, re-releasing, and redistribution ensues.
>>
>> The use of Visitor, or Acyclic Visitor, reduces the amount of
recompilation,
>> etc, by getting rid of the case variable. When new cases are added,
there is
>> no case variable to change, and so there is very little recompilation,
etc.
>>
>> Those of us who have lived through the nightmare of large highly
>> interdependent systems are happy to use visitors, or acyclic visitors, to
>> stave of the resultant problems.
>
>I'm surprised you find much time for all this maintenance work you do
>what with the teaching and the papers to write and so on.

Nowadays I consult for companies who have "all this maintenance work to do",
and try to help them disentangle themselves from the web of dependencies
they have woven.

>Presumably you write from long personal experience.

Indeed, I've been fighting these battles for well over 25 years.

>I work as a contractor, I've worked
>at, how many? 15 companies. Dunno, lost count. Point is though, I've
>done loads and loads of this maintenance stuff and I don't recognize the
>difficulties you're describing.

Huh? You haven't had to add an enumerator to an enumeration and then had to
modify all the switch/case and if/else statements in which the enumeration
was used? I find that quite difficult to believe.

>You talk about the problem introduced by this modem type enum. Now who
>introduced it in the first place? Me. As part of the switch statement
>alternative to your acyclic visitor thingy. There are not suddenly
>hundreds of mysterious hand wavy dependencies, the only people who
>depend on it are the configure methods already mentioned.

Not at all, there's also Dial(Modem*) and Hangup(Modem*) and
SendChar(Modem*, char), and Recv(Modem*), just to name a few (presuming a C
based implementation). Each of these functions will have a switch statement
(or an if/else chain) in order to test for the kind of modem and therefore
to determine how the modem should really be operated.

BTW, I chose this particular example because I had this exact problem back
in 1978. We had written a system that used modems of our own design.
Later, the hardware engineers produced a modem board that cost significantly
less than the original, but which also had a completely different software
interface. Our product had to be able to use both kinds of modems
simultaneously (a typical system would have 80 or more modems installed).
When one modem broke and was replaced from spares, it did not have to be a
modem of the same kind that replaced the broken modem; and the software
could not be recompmiled (obviously), so we had to detect the type of modem
at runtime and then determine how to operate it on the fly.

Needless to say, it was a mess. We had (the assembly language version of)
switch/case statements littered throughoug the code in order to deal with
the modem hardware correctly.

>And they have
>to be modified anyway to cater for the new modem type, in just the same
>way that your configure classes need new methods adding.

Fortunately, the file 'modem.h' does not need to be modified when the new
derivative to Modem is added; and thus nobody who #includes modem.h must
recompile.

>What we need is a competition. Someone sets some requirements plus some
>secret set of revisions to the requirements. Then you and I sit down and
>code our solutions, followed by the code changes for the revisions. Then
>we can see who produces the least amount of code plus changes. We could
>even have a little bet on it. :)

No, we need a controlled experiment of the appropriate scale. Two guys,
coding head to head might be fun, but would prove little. Two very large
project teams, on the other hand, would be quite interesting.


Robert C. Martin | Design Consulting | Training courses offered:
Object Mentor | rma...@oma.com | Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 | C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
'Mistrust arguments from authority.'" -- Carl Sagan

Robert Martin

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to

Ell wrote in message ...
>rma...@oma.com wrote:
>:
>: da...@prim.demon.co.uk wrote:
>:>
>:> Oh no, more gibberish. Take a look at the paper in question. If you add

>:> a new modem type and it needs configuring for Unix, you have to add a
>:> new method to the ConfigureForUnixVisitor class to implement Visit for
>:> the new modem type. This is what we call modifying existing code. And
>:> it's no different from adding a new case to a switch statement.
>
>: It's acutally quite a bit different. There is no case variable to alter;
and
>: therefore the impact of the change is substantially smaller. i.e. nobody
>: depends upon modemTypes.h.
>
>Unless no one refers to it, someone has to depend upon any *.h file.
>Pointers to abstract classes do not totally eliminate dependency. That's
>Basic C++ 101.

That's basic C.

>It is deception pure and simple against newbie C++ programmers, and
>programmers not familiar with C++, for you to repeatedly assert year after
>year the blatant falsehood that using pointers to abstract classes somehow
>eliminates all dependency.

Encore, ENCORE! More absurd accusations!

>If the abstract class creates objects whose
>interface or data layout changes, or if the interface (or data members if
>it has it) of the abstract classes changes then the client using the
>pointer to the abstract class must recompile. The fact that you never
>mention this is incredible. You should be ashamed of yourself for
>attempting to prop up your ideas through such deceptive practices.


Ahem... EXCUSE ME EVERYBODY -- CAN I HAVE YOUR ATTENTION PLEASE!!!

(the croud slowly quiets down)

Elliott has just brought to my attention the fact that I have neglected to
make something clear. (Thank you Elliott...) So I'd like to state for the
record the following warning:

*** If you change anything in a header file, then any other file that
#includes that header file will probably need recompilation ***

Oh, and while I'm at it: *** The coffee at McDonald's is VERY HOT!!! Be
careful not to spill it on yourself and get a bad burn***

Thank you for your attention....

--------------

We now return to our normally scheduled comp.object discussions.

Robert Martin

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to

Ell wrote in message <35d0cff...@news.erols.com>...

>john-...@hlp.com wrote:
>
>>By the way, if you haven't seen the last 'semi-formal' competition that I
>>remember on comp.object, check out A Translational Vs. Elaborational View
of
>>Methodology / Shlaer-Mellor Vs. the Unified Method
>>http://www.sigs.com/publications/docs/oc/9602/oc9602.d.dialog.html
>>
>>It's one of my favorites, 'cause I'm in the electricity business :)
>
>And guess who is backing off the so-called Unified Method position.
>None other than RCM himself.

I'M BACKING OFF
I'm Backing Off
i'm backing off. <<No! BACKing, not .....>
i.. ba..... of...
... ....... ...
.
.
.
SPLAT!

>He now agrees with Mellor that classes
>and objects should first of all be considered to be data structures.

I do?? He does??? Really??? How interesting. I didn't know that either
of us believed that. Interesting.

Robert Martin

unread,
Aug 12, 1998, 3:00:00 AM8/12/98
to

Oren Ben-Kiki wrote in message <35d15...@news.barak.net.il>...

>
>Ell wrote in message <35d21e21...@news.erols.com>...
>>e...@access.digex.net (Ell) wrote:
>>
>>>john-...@hlp.com wrote:
>>>
>>>>By the way, if you haven't seen the last 'semi-formal' competition that
I
>>>>remember on comp.object, check out A Translational Vs. Elaborational
>View of
>>>>Methodology / Shlaer-Mellor Vs. the Unified Method
>>>>http://www.sigs.com/publications/docs/oc/9602/oc9602.d.dialog.html
>>>>
>>>>It's one of my favorites, 'cause I'm in the electricity business :)
>
>
>I well remember this thread. "They don't make them like they used to". As I
>recall, when it ended, there was a promise of a coming convention in which
>there would be a panel dedicated to the issue. Did it happen? Does anyone
>have a reference to the proceedings?

Yes, it happened. Steve and one of his cronies vs Grady and I. It was lots
of fun; if not particularly informative.

Ell

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to
"Robert Martin" <rma...@oma.com> wrote:

>Ell wrote in message <35d0cff...@news.erols.com>...
>>

>>And guess who is backing off the so-called Unified Method position.
>>None other than RCM himself.

>I'M BACKING OFF
>I'm Backing Off
>i'm backing off. <<No! BACKing, not .....>
>i.. ba..... of...
>... ....... ...
>.
>.
>.
>SPLAT!

>>He now agrees with Mellor that classes
>>and objects should first of all be considered to be data structures.

>I do?? He does??? Really??? How interesting. I didn't know that either
>of us believed that. Interesting.

What other way are we to interpret this:

***************************************************************
>"Robert Martin" <rma...@oma.com> writes:

>>"Judson McClendon" <judm...@bellsouth.net> wrote:
>>>
>>>Other than the concept of objects themselves, I agree with most
>>>of the design goals of OO. I just don't agree with the methods.

>>Objects are just data structures that are operated upon by functions that
>>are accessed through a jump table. What's not to agree with?
*****************************************************************

What do you think, we can't use dejanews?

Ell

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to
"Robert Martin" <rma...@oma.com> wrote:

>Ell wrote in message ...
>>
>>rma...@oma.com wrote:
>>:
>>: da...@prim.demon.co.uk wrote:
>>:>
>>:> Oh no, more gibberish. Take a look at the paper in question. If you add
>>:> a new modem type and it needs configuring for Unix, you have to add a
>>:> new method to the ConfigureForUnixVisitor class to implement Visit for
>>:> the new modem type. This is what we call modifying existing code. And
>>:> it's no different from adding a new case to a switch statement.

>>: It's acutally quite a bit different. There is no case variable to alter;
>>:and
>>: therefore the impact of the change is substantially smaller. i.e. nobody
>>: depends upon modemTypes.h.

>>Unless no one refers to it, someone has to depend upon any *.h file.
>>Pointers to abstract classes do not totally eliminate dependency. That's
>>Basic C++ 101.

>That's basic C.

When did abstract classes become a part of C? Please tell us that.
But if your point is that pointers don't eliminate dependency in
either C or C++ then that is true. In fact they don't eliminate
dependency in Pascal or any other language they are used in. That is
why this statement of yours is so odd:

>>: i.e. nobody depends upon modemTypes.h.

>>It is deception pure and simple against newbie C++ programmers, and
>>programmers not familiar with C++, for you to repeatedly assert year after
>>year the blatant falsehood that using pointers to abstract classes somehow
>>eliminates all dependency.

>Encore, ENCORE! More absurd accusations!

It's true, what's absurd about it. You just said:

>>: i.e. nobody depends upon modemTypes.h.

if you weren't implying that pointers to ABC's somehow eliminate
dependency, then why did you make the statement?

>>If the abstract class creates objects whose
>>interface or data layout changes, or if the interface (or data members if
>>it has it) of the abstract classes changes then the client using the
>>pointer to the abstract class must recompile. The fact that you never
>>mention this is incredible. You should be ashamed of yourself for
>>attempting to prop up your ideas through such deceptive practices.

>Ahem... EXCUSE ME EVERYBODY -- CAN I HAVE YOUR ATTENTION PLEASE!!!
>
>(the croud slowly quiets down)
>
>Elliott has just brought to my attention the fact that I have neglected to
>make something clear. (Thank you Elliott...) So I'd like to state for the
>record the following warning:
>
>*** If you change anything in a header file, then any other file that
>#includes that header file will probably need recompilation ***
>
>Oh, and while I'm at it: *** The coffee at McDonald's is VERY HOT!!! Be
>careful not to spill it on yourself and get a bad burn***

If it was so obvious then why did you make the statement:

>>: i.e. nobody depends upon modemTypes.h.

??? The obviousness of the it the dependency issue should have
prevented you from making the statement. N'est ce pas?

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

Ell wrote in message <35d4557b...@news.erols.com>...
>"Robert Martin" <rma...@oma.com> wrote:

>>Ell blathered:


>>>It is deception pure and simple against newbie C++ programmers, and
>>>programmers not familiar with C++, for you to repeatedly assert year
after
>>>year the blatant falsehood that using pointers to abstract classes
somehow
>>>eliminates all dependency.
>
>>Encore, ENCORE! More absurd accusations!
>
>It's true, what's absurd about it. You just said:
>
>>>: i.e. nobody depends upon modemTypes.h.

That's right. You see, in this thread we are arguing about switch
statements vs. polymorphism. And my point has been that if you use an
abstract Modem class then you don't need a file named modemTypes.h that
declares an enum of the form: enum ModemType {hayes, courier}; I assume you
agree with this statement.

Thus, if you use an abstract class then: "nobody depends upon modemTypes.h".
Right? Because, if you use an abstract class then...modemTypes.h just plain
doesn't exist. Right?

You see? No deception; no hideous reactionary social agenda; just plain ol'
everyday C++. Right?

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

Ell wrote in message <35d25131...@news.erols.com>...

>"Robert Martin" <rma...@oma.com> wrote:
>
>>Ell wrote in message <35d0cff...@news.erols.com>...
>>>He now agrees with Mellor that classes
>>>and objects should first of all be considered to be data structures.
>
>>I do?? He does??? Really??? How interesting. I didn't know that
either
>>of us believed that. Interesting.
>
>What other way are we to interpret this:
>
>***************************************************************
>>"Robert Martin" <rma...@oma.com> writes:
>
>>>Objects are just data structures that are operated upon by functions that
>>>are accessed through a jump table. What's not to agree with?
>*****************************************************************
>
>What do you think, we can't use dejanews?


No, I think you are frightfully bad at representing what I write. Note that
I did not say that "objects should first of all be considered to be data
structures." Instead I said "Objects are just data structures that are


operated upon by functions that are accessed through a jump table."

So, your complaint above should be:

He now agrees with Mellor that objects are just data structures that are


operated upon by functions that are accessed through a jump table.

But I don't think you can say that, because I don't think the Mellor has
ever said that exactly. So, your complain above should be:

He said that objects are just data structures that are operated upon by


functions that are accessed through a jump table.

*That* would be accurate. However, you had prefaced this with:

**


And guess who is backing off the so-called Unified Method position.
None other than RCM himself.

**

So your whole statement should have read:

**


And guess who is backing off the so-called Unified Method position. None

other than RCM himself. He said that objects are just data structures that


are operated upon by functions that are accessed through a jump table.

**

And this statement is silly, since it does not represent a "backing off" of
the UM position.

Ell

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to
"Robert Martin" <rma...@oma.com> wrote:

>So your whole statement should have read:
>
>**
>And guess who is backing off the so-called Unified Method position. None
>other than RCM himself. He said that objects are just data structures that
>are operated upon by functions that are accessed through a jump table.
>**
>
>And this statement is silly, since it does not represent a "backing off" of
>the UM position.

From everything I have read UML sees objects semantically in OO
applications primarily as behavioral responsibility entities. At
least that is what Booch said 3 years ago when debating Mellor.

Not too forget as Stroustrup frequently reminds us, that data
structures with jump tables is just one form implementing objects. So
how can what you say be the position of UML on *either* aspect?

Ell

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to
"Robert Martin" <rma...@oma.com> wrote:

>
>Ell wrote in message <35d4557b...@news.erols.com>...
>>"Robert Martin" <rma...@oma.com> wrote:
>
>>>Ell blathered:

Just based recently on:
1.) your wrong definition of an object
2.) your false assertion that extending use cases depend on
extended use cases, and
3.) your incorrect implication that clients using pointers to
abstract classes have no dependency on the abstract classes
4.) your confusion about the nature of high level policy

it's crystal clear to me and many others who the real "Blatherer" is.

David Griffiths

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to
Robert Martin wrote:

> Huh? You haven't had to add an enumerator to an enumeration and then had to
> modify all the switch/case and if/else statements in which the enumeration
> was used? I find that quite difficult to believe.

No, I meant that I have never found such modifications to be such a huge
chore that it requires a completely new and more complex approach. In
fact it's usually been pretty trivial.

> >You talk about the problem introduced by this modem type enum. Now who
> >introduced it in the first place? Me. As part of the switch statement
> >alternative to your acyclic visitor thingy. There are not suddenly
> >hundreds of mysterious hand wavy dependencies, the only people who
> >depend on it are the configure methods already mentioned.
>
> Not at all, there's also Dial(Modem*) and Hangup(Modem*) and
> SendChar(Modem*, char), and Recv(Modem*), just to name a few (presuming a C
> based implementation). Each of these functions will have a switch statement
> (or an if/else chain) in order to test for the kind of modem and therefore
> to determine how the modem should really be operated.

OK, you've added some specific dependencies. When a new modem type is
added then these functions will need to be modified to add the new
switch case and recompiled. Fine. But your AVP will also need to have
methods added to deal with Dial, Hangup and so on. What's the
difference? It's still an implicit dependency in that code must be
modified and recompiled.

> BTW, I chose this particular example because I had this exact problem back
> in 1978. We had written a system that used modems of our own design.
> Later, the hardware engineers produced a modem board that cost significantly
> less than the original, but which also had a completely different software
> interface. Our product had to be able to use both kinds of modems
> simultaneously (a typical system would have 80 or more modems installed).
> When one modem broke and was replaced from spares, it did not have to be a
> modem of the same kind that replaced the broken modem; and the software
> could not be recompmiled (obviously), so we had to detect the type of modem
> at runtime and then determine how to operate it on the fly.
>
> Needless to say, it was a mess. We had (the assembly language version of)
> switch/case statements littered throughoug the code in order to deal with
> the modem hardware correctly.

And your AVP approach will have _methods_ littered throughout the code
to deal with it!

BTW, I'm a little confused by the fact that you have the configure stuff
in a separate class outside Modem. What's the Modem class for if not for
encapsulating things like how to configure the modem, dial it, hangup
and so on. Doesn't sound like there's any need for either AVP or switch
statements, just a heirarchy of Modem classes where inheritance can
exploit the similarity of a lot of modems to each other.

> Fortunately, the file 'modem.h' does not need to be modified when the new
> derivative to Modem is added; and thus nobody who #includes modem.h must
> recompile.

Put the enum in a file called ModemTypes.h. The only files that depend
on it are the very files which will need to be modified to cope with the
new type.

> No, we need a controlled experiment of the appropriate scale. Two guys,
> coding head to head might be fun, but would prove little. Two very large
> project teams, on the other hand, would be quite interesting.

I'd love to see some such results. Pity it's so expensive. I wonder why
no colleges are attempting these experiments. They're the sort of people
who can afford to mount them. You could have an annual competition where
teams of graduates compete using different approaches to implement a
given set of changing requirements and then compare the results.

Dave

Patrick Logan

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:

: Robert Martin wrote:
:
: > Huh? You haven't had to add an enumerator to an enumeration and then had to
: > modify all the switch/case and if/else statements in which the enumeration
: > was used? I find that quite difficult to believe.

: No, I meant that I have never found such modifications to be such a huge
: chore that it requires a completely new and more complex approach. In
: fact it's usually been pretty trivial.

Even when the switch/case was implemented in code from Company A but
the customer who wants to extend the code is in Company B. Say Company
A is a vendor of an E-Commerce framework. And Company B makes and
sells Bugle Boy jeans. (Get it? ;^)

Do you expect Company A to modify all their switch statements and
re-release their framework every time Company B comes out with a new
line of jeans? No, the purpose of a framework is to allow new objects
to plug in without modifying the framework, per se.

So one person maintaining a small system may keep up with the switch
statements just fine. But polymorphic message sends are automatic and
especially well suited when there are more than one team involved.

--
Patrick Logan (H) mailto:plo...@teleport.com
(W) mailto:patr...@gemstone.com
http://www.gemstone.com

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

Ell wrote in message <35e19c17...@news.erols.com>...

>"Robert Martin" <rma...@oma.com> wrote:
>
>>So your whole statement should have read:
>>
>>**
>>And guess who is backing off the so-called Unified Method position. None
>>other than RCM himself. He said that objects are just data structures
that
>>are operated upon by functions that are accessed through a jump table.
>>**
>>
>>And this statement is silly, since it does not represent a "backing off"
of
>>the UM position.
>
>From everything I have read UML sees objects semantically in OO
>applications primarily as behavioral responsibility entities. At
>least that is what Booch said 3 years ago when debating Mellor.
>
>Not too forget as Stroustrup frequently reminds us, that data
>structures with jump tables is just one form implementing objects. So
>how can what you say be the position of UML on *either* aspect?


If we assume, for the moment, that an object is a data structure manipulated
by functions that are accessed through a jump table (it is true that there
are different implementation schemes, but they all eventually come down to
the same kind of thing). Then, what does this object look like to its
users? It looks like a jump table. The user cannot see the functions, or
the data structures. Now, a jump table is really just a means to provide
access to behavior. Thus, the only thing the user sees is the behavioral
potential of the object. The only thing the user can do is to invoke
behaviors through the jump table.

Thus, the statement "objects are data structures manipulated by functions
accessed through a jump table" is consistent with the notion that objects
are behavioral entities.

I grant you that the former is a minimalist view, and the latter is a bit
more philosophical. But the two statements are not in contradiction.

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

David Griffiths wrote in message <35D2F90A...@prim.demon.co.uk>...

>Robert Martin wrote:
>
>> Huh? You haven't had to add an enumerator to an enumeration and then had
to
>> modify all the switch/case and if/else statements in which the
enumeration
>> was used? I find that quite difficult to believe.
>
>No, I meant that I have never found such modifications to be such a huge
>chore that it requires a completely new and more complex approach. In
>fact it's usually been pretty trivial.
>
>> >You talk about the problem introduced by this modem type enum. Now who
>> >introduced it in the first place? Me. As part of the switch statement
>> >alternative to your acyclic visitor thingy. There are not suddenly
>> >hundreds of mysterious hand wavy dependencies, the only people who
>> >depend on it are the configure methods already mentioned.
>>
>> Not at all, there's also Dial(Modem*) and Hangup(Modem*) and
>> SendChar(Modem*, char), and Recv(Modem*), just to name a few (presuming a
C
>> based implementation). Each of these functions will have a switch
statement
>> (or an if/else chain) in order to test for the kind of modem and
therefore
>> to determine how the modem should really be operated.
>
>OK, you've added some specific dependencies. When a new modem type is
>added then these functions will need to be modified to add the new
>switch case and recompiled. Fine. But your AVP will also need to have
>methods added to deal with Dial, Hangup and so on. What's the
>difference? It's still an implicit dependency in that code must be
>modified and recompiled.

Forgetting about AVP for the moment, If we have a Modem abstract class with
existing functions Dial, Hangup, SendChar, and Recv, then when we add a new
modem type, *no existing functions need to change*. (except for the
function that actually creates the new type of modem). The existing Dial,
Hangup, SendChar, adn Recv functions, in the existing derivatives of Modem,
need neither syntactic alteration, nor recompilation. If those derivatives
were each packaged in their own DLL or component, then those components
would not need to be redistributed to existing customers.

More importantly, there are functions that access all the Modems through the
Modem base class. These functions also do not need syntactic alteration,
recompilation, nor redistribution. This independence is a significant
benefit since it means that the impact of the change (adding a new modem
type) will be very low.

Now, back to the AVP. In those cases where a new function needs to be added
to the existing Modem hierarchy; and we are not interested in changing the
entire modem hierarchy (or recompiling it, or reidstributing it), then we
can add the new function to a visitor object. It is true that the visitor
must be editted, recompiled, and redistributed; but the Modem hierarchy, and
all of its clients, remain undisturbed. Again, this is a significant
benefit.

BTW, all these benefits can be gained through the use of pointers to
functions in C. Indeed, OOD can be said to be "discipline imposed upon
indirect transfer of control (i.e. pointers to functions)". It's just nice
to use a language that manages all those function pointers behind the scenes
for you.

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

David Griffiths wrote in message <35D2F90A...@prim.demon.co.uk>...
>Robert Martin wrote:
>
>> No, we need a controlled experiment of the appropriate scale. Two guys,
>> coding head to head might be fun, but would prove little. Two very large
>> project teams, on the other hand, would be quite interesting.
>
>I'd love to see some such results. Pity it's so expensive. I wonder why
>no colleges are attempting these experiments. They're the sort of people
>who can afford to mount them. You could have an annual competition where
>teams of graduates compete using different approaches to implement a
>given set of changing requirements and then compare the results.


There was a such a study done a few years back. A couple of professors got
some of their students to work on small projects. They were divided into
teams and given similar specs. One team used OO, the other did not. There
were other criteria as well.

Each little project was a matter of a few hours worth of programming, and
there were several little projects done.

The sample size was relatively small; and the projects were far too simple
to be meaningful, but the results were interesting nonetheless. I can't
remember the details, nor where the study was published, (I think it was in
JOOP circa 1996). The upshot was that some benefits from OO were
discernable, but they were certainly not conclusive. There were also cases
where OO failed to outperform more traditional schemes. (Specifically where
the participants were unfamiliar with OO and had to spend more time getting
used to OO ideas rather than actually working).

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

David Griffiths wrote in message <35D2F90A...@prim.demon.co.uk>...
>Robert Martin wrote:
>
>> BTW, I chose this particular example because I had this exact problem
back
>> in 1978. We had written a system that used modems of our own design.
>> Later, the hardware engineers produced a modem board that cost
significantly
>> less than the original, but which also had a completely different
software
>> interface. Our product had to be able to use both kinds of modems
>> simultaneously (a typical system would have 80 or more modems installed).
>> When one modem broke and was replaced from spares, it did not have to be
a
>> modem of the same kind that replaced the broken modem; and the software
>> could not be recompmiled (obviously), so we had to detect the type of
modem
>> at runtime and then determine how to operate it on the fly.
>>
>> Needless to say, it was a mess. We had (the assembly language version
of)
>> switch/case statements littered throughoug the code in order to deal with
>> the modem hardware correctly.
>
>And your AVP approach will have _methods_ littered throughout the code
>to deal with it!

Well, I probably wouldn't use an AVP for most of the methods in this
problem. Rather I'd use a Modem base class with two (or more) derivatives.
And the methods will, in fact, not be littered accross the code. All the
methods will be in two well known places. One set in each derivative of
modem.

And in the event that I did use an AVP for some of the methods, they would
all be contained in the visitor. So, again, very little littering.


>
>BTW, I'm a little confused by the fact that you have the configure stuff
>in a separate class outside Modem. What's the Modem class for if not for
>encapsulating things like how to configure the modem, dial it, hangup
>and so on. Doesn't sound like there's any need for either AVP or switch
>statements, just a heirarchy of Modem classes where inheritance can
>exploit the similarity of a lot of modems to each other.

The problem with the 'ConfigureForDos' method is that it begs a question:
what about unix." If I make the configureForDos function a method in the
Modem base class, then I will have to add ConfigureForX, where X is
unbounded. I don't want to have an unbounded set of functions in my Modem
base class because for every new X I must edit, recompile, and redistribute
the Modem hierarchy and all its clients. Thus, I use the Acyclic Visitor
Pattern to allow me to create ConfigureForX visitor objects. For each new X
I can add a new visitor class without affecting the Modem hiearchy, and thus
without editing, recompiling, or redistributing the Modem hierarchy and all
its clients.


>
>> Fortunately, the file 'modem.h' does not need to be modified when the new
>> derivative to Modem is added; and thus nobody who #includes modem.h must
>> recompile.
>
>Put the enum in a file called ModemTypes.h. The only files that depend
>on it are the very files which will need to be modified to cope with the
>new type.

Exactly. Every function that operates upon the modems will have to change,
be recompiled, and be redistributed. Whereas with the Modem base class,
*NO* function needs to change (except for the function that creates the new
derivative). Instead new functions are added. The existing functions do
not need to be editted, recompiled, or redistributed.

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

David Griffiths

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to
Robert Martin wrote:
>
> David Griffiths wrote in message <35D2F90A...@prim.demon.co.uk>...

> >> >You talk about the problem introduced by this modem type enum. Now who

Wow, where'd the goalposts disappear to? :) When you introduced Dial
etc, I thought they were meant to be visitor classes along the same
lines as Configure. If you're putting them in the Modem class (as I
think I suggested anyway), there's no argument.

> More importantly, there are functions that access all the Modems through the
> Modem base class. These functions also do not need syntactic alteration,
> recompilation, nor redistribution. This independence is a significant
> benefit since it means that the impact of the change (adding a new modem
> type) will be very low.

Basic OO principles, but again not what we were discussing. Remember,
you were the one to introduce the idea of the configure functionality
for some reason being external to the modem class and using AVP to
handle it, and I was saying you could use switch statements. When I said
that the configure stuff was the only thing that depended on the modem
type, you then introduced Dial etc and said they would need switch
statements too. And just to completely muddy the waters you then put
them in your modem class - in which case you DON'T need switch
statements! You can't have it both ways - Dial etc are either IN the
modem class, in which case there is no extra modem type dependency, or
they are EXTERNAL using AVP/switch (along the lines of the configure
example) and both approaches are "dependent" in that code must be added
for a new modem type.

> Now, back to the AVP. In those cases where a new function needs to be added
> to the existing Modem hierarchy; and we are not interested in changing the
> entire modem hierarchy (or recompiling it, or reidstributing it), then we
> can add the new function to a visitor object. It is true that the visitor
> must be editted, recompiled, and redistributed; but the Modem hierarchy, and
> all of its clients, remain undisturbed. Again, this is a significant
> benefit.

And one that you would equally well get with an external object using a
switch statement.

Dave

Robert Martin

unread,
Aug 13, 1998, 3:00:00 AM8/13/98
to

David Griffiths wrote in message <35D33B31...@prim.demon.co.uk>...
>Robert Martin wrote:

>> Now, back to the AVP. In those cases where a new function needs to be
added
>> to the existing Modem hierarchy; and we are not interested in changing
the
>> entire modem hierarchy (or recompiling it, or reidstributing it), then we
>> can add the new function to a visitor object. It is true that the
visitor
>> must be editted, recompiled, and redistributed; but the Modem hierarchy,
and
>> all of its clients, remain undisturbed. Again, this is a significant
>> benefit.
>
>And one that you would equally well get with an external object using a
>switch statement.


Which brings us full circle to the modemTypes.h file that contains the enum
that we'd rather not have.

Ell

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
"Robert Martin" <rma...@oma.com> wrote:

>Ell wrote in message <35e19c17...@news.erols.com>...
>>
>>"Robert Martin" <rma...@oma.com> wrote:
>>>
>>>So your whole statement should have read:
>>>

>>>And guess who is backing off the so-called Unified Method position. None
>>>other than RCM himself. He said that objects are just data structures
>>>>that
>>>are operated upon by functions that are accessed through a jump table.

>>From everything I have read UML sees objects semantically in OO


>>applications primarily as behavioral responsibility entities. At
>>least that is what Booch said 3 years ago when debating Mellor.
>>
>>Not too forget as Stroustrup frequently reminds us, that data
>>structures with jump tables is just one form implementing objects. So
>>how can what you say be the position of UML on *either* aspect?

>If we assume, for the moment, that an object is a data structure manipulated
>by functions that are accessed through a jump table (it is true that there
>are different implementation schemes, but they all eventually come down to
>the same kind of thing).

If there are different implementation schemes then why are you trying
to make it seem as if jump tables are some key defining aspect of
objects, as you do here and repeatedly below?

>Then, what does this object look like to its
>users? It looks like a jump table.

Who sees jump tables except compiler makers?! And that is only if the
compiler makers are using jump tables to implement objects in the
first place!

What OO objects look like to developers and system users in the
logical semantics of most OO programs are entities of behavioral
responsibility. This responsibility sometimes involves managing data.

And this logical semantic role was what the original anti-OO writer
had a problem with. It wasn't how objects may, or may not be
implemented.

>The user cannot see the functions, or the data structures.

Then what makes you think they can see jump tables?!


>Then, what does this object look like to its
>users? It looks like a jump table.

>Now, a jump table is really just a means to provide


>access to behavior. Thus, the only thing the user sees is the behavioral
>potential of the object.

But you just said 'users' can see jump tables! Geez, put on your
consistency cap.

>The only thing the user can do is to invoke
>behaviors through the jump table.

So now all of a sudden you kind of agree with me. But *neither* users
or developers are exposed to jump tables. In fact objects may not
even be implemented using jump tables.

>Thus, the statement "objects are data structures manipulated by functions
>accessed through a jump table" is consistent with the notion that objects
>are behavioral entities.

You are missing the point and obfuscating the issue with confused
thinking.

First, the fact that objects may be implemented as "data structures


manipulated by functions accessed through a jump table" is consistent

with the fact that objects should primarily be viewed semantically as
entities with behavioral responsibility entities *only* if jump tables
are actually being used for implementation.

Secondly, the point beginning with the writer who didn't like objects,
was how we view and use OO objects in terms OO program semantics.
Period. The writer was not hung up on how OO objects were
implemented. What he didn't like was the logical, semantic role
objects played.

You went off track and started talking about how objects were
implemented (which in itself was not quite correct). So while what
you say above *may* be consistent, such consistency was not even the
darn issue!

The issue was and is how the primary role of objects in OO program
semantics. To that myself, you, and Booch used to say it was as
entities with behavioral responsibility. And that in such a role
while objects may manage data, that should not be their only or
primary role, in most cases. Mellor disagreed with this. He felt
that the primary role of objects was to hold data, and manage data.

Your current jog, emphasizing what *might* be the way to *implement*
objects when responding to issues relating to the primary semantic
role of objects in OO programs is therefore regression pure and
simple!

Ell

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
e...@access.digex.net (Ell) wrote:

>The issue was and is [] the primary role of objects in OO program

Gerhard Menzl

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
David Griffiths wrote:

> > Fortunately, the file 'modem.h' does not need to be modified when the new
> > derivative to Modem is added; and thus nobody who #includes modem.h must
> > recompile.
>
> Put the enum in a file called ModemTypes.h. The only files that depend
> on it are the very files which will need to be modified to cope with the
> new type.

Robert's point is that, with polymorphism instead of switch statements, the number
of files in need of updating will be kept to a minimum. Ideally, i.e. assuming you
control modem object creation via some sort of configuration file, you get two new
files (NewWizModem.cpp and NewWizModem.h) and have to change one existing file
(ModemFactory.cpp). All other files only deal with the abstract modem interface,
hence there is no need to change them. Compare this to the classical switch
approach where references to the new modem class get strewn all across the code.

Gerhard Menzl


David Griffiths

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
Robert Martin wrote:
> David Griffiths wrote in message <35D2F90A...@prim.demon.co.uk>...
> >Robert Martin wrote:
> >
> >> BTW, I chose this particular example because I had this exact problem

> >And your AVP approach will have _methods_ littered throughout the code


> >to deal with it!
>
> Well, I probably wouldn't use an AVP for most of the methods in this
> problem. Rather I'd use a Modem base class with two (or more) derivatives.
> And the methods will, in fact, not be littered accross the code. All the
> methods will be in two well known places. One set in each derivative of
> modem.
>
> And in the event that I did use an AVP for some of the methods, they would
> all be contained in the visitor. So, again, very little littering.

Fine. And I could create a class analogous to your configure visitor. It
would have just one method with a switch statement in it. All the cases
contained in there.

You're supposed to be demonstrating some unique ability of AVP to
prevent this littering. Seems to me that anyway you choose to structure
your code, I can match it with switch statements and do it more simply.

> The problem with the 'ConfigureForDos' method is that it begs a question:
> what about unix." If I make the configureForDos function a method in the
> Modem base class, then I will have to add ConfigureForX, where X is
> unbounded. I don't want to have an unbounded set of functions in my Modem
> base class because for every new X I must edit, recompile, and redistribute
> the Modem hierarchy and all its clients. Thus, I use the Acyclic Visitor
> Pattern to allow me to create ConfigureForX visitor objects. For each new X
> I can add a new visitor class without affecting the Modem hiearchy, and thus
> without editing, recompiling, or redistributing the Modem hierarchy and all
> its clients.

Cool, but it can be done more easily by creating ConfigureForX "switch"
objects.

> >> Fortunately, the file 'modem.h' does not need to be modified when the new
> >> derivative to Modem is added; and thus nobody who #includes modem.h must
> >> recompile.
> >
> >Put the enum in a file called ModemTypes.h. The only files that depend
> >on it are the very files which will need to be modified to cope with the
> >new type.
>

> Exactly. Every function that operates upon the modems will have to change,
> be recompiled, and be redistributed.

And these functions are just those that are contained in my
ConfigureForX etc "switch" objects. Exactly analagous to your visitor
objects which will have to be changed, recompiled etc to deal with the
new modem type.

This header file, this enum, is reserved by me for use only by my switch
statement visitor analogues. It's my alternative and I can do what I
like with it. :)

Dave

swa...@my-dejanews.com

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
In article <35B64200...@jhuapl.edu>,
Tom Kreitzberg <Tom.Kre...@jhuapl.edu> wrote:

> I've got a set of port-watching classes to deal with messages
> that arrive from different ports. The first few bytes of each
> message identify the message type; for each message type, a
> different action is required. A port-watching class has to worry
> about at most twenty messages.

Our current design has a similar 'feature', in this case we have something
that is looking for commands coming in via a serial port (RS232/UART). We
have a singleton object that has a list of clients that are all interested in
'recieving commands' from the serial port. Each of those clients has an
AcceptMessage method, when the singleton object gets a complete message
(which is actually delimted using SLIP), if then passes this message to each
client and allows the client to decide whether they need to do anything with
that message or not.

> Is there a suitably OO "multiple message type" pattern, or
> am I justified in using switch statements there?

Dunno about that, the above works well for us though.

kind regards,
SW.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum

Johan Johansson

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
David Griffiths skrev i meddelandet

>> And in the event that I did use an AVP for some of the methods, they
would
>> all be contained in the visitor. So, again, very little littering.
>
>Fine. And I could create a class analogous to your configure visitor. It
>would have just one method with a switch statement in it. All the cases
>contained in there.

Then what's the difference? What you have done then is simply to merge all
(currently known) visitors into one, deciding inside the method which one to
act like. What if you can't change this class once it's distributed, or if
*someone else* who cannot access the source wants to add a new modem? Do
you/he/she then assemble another "supervisitor" containing just the new
ones?


Robert Martin

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to

Ell wrote in message <35d38b61...@news.erols.com>...
>"Robert Martin" <rma...@oma.com> wrote:

>
>>If we assume, for the moment, that an object is a data structure
manipulated
>>by functions that are accessed through a jump table (it is true that there
>>are different implementation schemes, but they all eventually come down to
>>the same kind of thing).
>
>If there are different implementation schemes then why are you trying
>to make it seem as if jump tables are some key defining aspect of
>objects, as you do here and repeatedly below?

I'm using the term out of convenience. Jump tables are a common method of
implementing polymorphism. Hash tables are also used, they are really just
jump tables too. Some languages embed switch statements in the objects; but
switch statements are often implemented as jump tables.

The point is that, regardless of the particular scheme of implementation, it
can be viewed as some kind of jump table. Or, if you prefer, it can be
viewed as a black box mechanism which accepts method ids as input, and
produces the address of a program that provides the required behavior as
output. (From now on I'll refer to this as a pointer to a function, even
though it might be implemented somewhat differently.) I call this black
box, regardless of its actual implementation, a jump table, since it mimics
exactly the semantics of a jump table.


>
>>Then, what does this object look like to its
>>users? It looks like a jump table.
>
>Who sees jump tables except compiler makers?! And that is only if the
>compiler makers are using jump tables to implement objects in the
>first place!

Granted. I was using a bit of license here. What the user actually sees
are the method ids that are he input to the black box. Since the method ids
are the only input that can be fed into the black box (ignoring function
arguments), the black box can be represented by the set of method ids that
it responds to. And since the black box can be viewed as a jump table, the
method ids are a kind of synonym for the jump table. Thus, when I said that
the users see the jump table, my meaning was that all they see is the method
ids that can be applied to the jump table.

>>Now, a jump table is really just a means to provide
>>access to behavior. Thus, the only thing the user sees is the behavioral
>>potential of the object.

>But you just said 'users' can see jump tables! Geez, put on your
>consistency cap.

Sorry, I was applying my black box metaphor in reverse. Again, I was using
the jump table as a metaphor for the black box. And since the onlything
visible about the black box is the suite of methods, then the only thing
visible to the user is the suite of methods. And since the suite of methods
represents a behavioral potential, then the only thing visible to the user
is a behavioral potential.


>
>First, the fact that objects may be implemented as "data structures
>manipulated by functions accessed through a jump table" is consistent
>with the fact that objects should primarily be viewed semantically as
>entities with behavioral responsibility entities *only* if jump tables
>are actually being used for implementation.

Again, if you apply the black box metaphor, then the statement becomes:

"Objects are data structures manipulated by functions accessed through a
black box that invokes them based upon method ids."

And I think you'll agree that this is consistent with the notion that
objects are behavioral entities.

>


>Secondly, the point beginning with the writer who didn't like objects,
>was how we view and use OO objects in terms OO program semantics.
>Period. The writer was not hung up on how OO objects were
>implemented. What he didn't like was the logical, semantic role
>objects played.

I didn't interpret his complaint that way. I interpreted his complaint as:
"OO promises everything and doesn't deliver everything; therefore OO is a
crock." I have found that people who are disillusioned with OO often
respond well when you explain that an objects is just a data structure
manipulated by methods accessed through a jump table. It brings the initial
concept of an object down to terms they can understand, and have probably
used themselves from time to time. Once you have their agreement with that
minimalist statement, you can begin to build the theory on top of their
newfound understanding.

>
>You went off track and started talking about how objects were
>implemented (which in itself was not quite correct). So while what
>you say above *may* be consistent, such consistency was not even the
>darn issue!

I'm afraid that it was you who made "logical semantic role" the issue. And
once you did, I started responding to you.
>
>The issue was and is how the primary role of objects in OO program


>semantics. To that myself, you, and Booch used to say it was as
>entities with behavioral responsibility. And that in such a role
>while objects may manage data, that should not be their only or
>primary role, in most cases. Mellor disagreed with this. He felt
>that the primary role of objects was to hold data, and manage data.

And I still hold the view that the best way to design objects is to consider
their behavior first. I have not wavered from that position. I don't think
the viewpoint you ascribe to Mellor is quite correct though. He also views
objects as behavioral entities. Indeed, in his method, he populates objects
with finite state machines. I will agree, however, that he does put a
stronger data emphasis on his objects than I do. This is because Mellor is
not a strong proponent of dynamic polymorphism.

>Your current jog, emphasizing what *might* be the way to *implement*
>objects when responding to issues relating to the primary semantic
>role of objects in OO programs is therefore regression pure and
>simple!


Instead of regression, consider it minimalism. And consider that it was
minimalism for the purpose of instruction. Sometimes if you reduce a
complex issue down into is most minimal form, you can help someone else
understand it. And then they can begin along the path of understanding the
issue in its full complexity.

Robert Martin

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to

David Griffiths wrote in message <35D405AF...@prim.demon.co.uk>...

>Robert Martin wrote:
>> David Griffiths wrote in message <35D2F90A...@prim.demon.co.uk>...
>> >Robert Martin wrote:
>> >
>> >> BTW, I chose this particular example because I had this exact problem
>
>> >And your AVP approach will have _methods_ littered throughout the code
>> >to deal with it!
>>
>> Well, I probably wouldn't use an AVP for most of the methods in this
>> problem. Rather I'd use a Modem base class with two (or more)
derivatives.
>> And the methods will, in fact, not be littered accross the code. All the
>> methods will be in two well known places. One set in each derivative of
>> modem.
>>
>> And in the event that I did use an AVP for some of the methods, they
would
>> all be contained in the visitor. So, again, very little littering.
>
>Fine. And I could create a class analogous to your configure visitor. It
>would have just one method with a switch statement in it. All the cases
>contained in there.

But where is the enum defined? Who loads the enum variable? And how can I
make sure that none of the derivatives of clients of Modem are affected when
the declaration of the enum changes?

I could use a raw integer, but then my code will be full of magic numbers.

I could use a string, but then I lose compile time checks on the spelling of
the strings.

Look at it this way. Every class already has a unique data element that
identifies it, its type_info. The Acyclic Visitor is nothing more than a
way to switch on the type_info. Thus, it uses existing data structures
rather than inventing new ones; and without creating any dependency
problems. Moreover the mechanism used for the switch eliminates most of the
traditional problems with the switch. i.e. no fall through, no default, no
missing cases, no mis-set switch variables.

>> >
>> >Put the enum in a file called ModemTypes.h. The only files that depend
>> >on it are the very files which will need to be modified to cope with the
>> >new type.
>>
>> Exactly. Every function that operates upon the modems will have to
change,
>> be recompiled, and be redistributed.
>
>And these functions are just those that are contained in my
>ConfigureForX etc "switch" objects. Exactly analagous to your visitor
>objects which will have to be changed, recompiled etc to deal with the
>new modem type.
>
>This header file, this enum, is reserved by me for use only by my switch
>statement visitor analogues. It's my alternative and I can do what I
>like with it. :)

Not quite. The enum value has to be accessible from the base class somehow.
Thus, Modem.h will have a function of the form:

virtual ModemType GetType() = 0;

Thus Modem.h will have to #include ModemTypes.h to gain access to the
declaration of ModemType. Also, every modem derivative will have to
#include ModemTypes.h so that it can return the correct enumerator.

David Griffiths

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
Robert Martin wrote:

> But where is the enum defined? Who loads the enum variable? And how can I
> make sure that none of the derivatives of clients of Modem are affected when
> the declaration of the enum changes?

Man, I can't believe you're so hung up about this enum. This is not a
problem. We've been doing this sort of thing for decades. It's defined
in ModemTypes.h (say). Don't know what you mean by "loads". And why
should anything be affected by ADDING an entry to a new enum? Think of
it as an application of the Open Closed Principle if you like. :)

> Look at it this way. Every class already has a unique data element that
> identifies it, its type_info. The Acyclic Visitor is nothing more than a
> way to switch on the type_info. Thus, it uses existing data structures
> rather than inventing new ones; and without creating any dependency
> problems. Moreover the mechanism used for the switch eliminates most of the
> traditional problems with the switch. i.e. no fall through, no default, no
> missing cases, no mis-set switch variables.

It's also a completely daft way of doing it! For every new modem type
you implement, you have to write an Accept method in the Modem
derivative, you have to create an entire ModemVisitor subclass and you
have to add a method(s) to your Configure Visitor(s). Whereas for the
switch statement, all you'd do is add an entry to the enum, a method to
return the enum, and a case statement(s) to the Configure object(s).
Much simpler, easier to understand and easier to maintain. Oh, and the
Configure "object" needn't be a separate object at all. I mean, look at
the control flow. You want to configure your modem. With AVP you have to
create your configure visitor object, then call the Accept method in the
modem object. That then does a dynamic cast and checks for success. If
succesful, it calls the Visit method in the visitor where we finally get
down to business. With a switch statement, you'd simply call a configure
method which would do a switch on the modem type and you're there!

> Not quite. The enum value has to be accessible from the base class somehow.
> Thus, Modem.h will have a function of the form:
>
> virtual ModemType GetType() = 0;
>
> Thus Modem.h will have to #include ModemTypes.h to gain access to the
> declaration of ModemType. Also, every modem derivative will have to
> #include ModemTypes.h so that it can return the correct enumerator.

That's true. So you'll get an unneccessary recompile of the modem
heirarchy. Big deal. If it matters that much, you can use #defines in
the Modem derivative's header file.

Dave

David Griffiths

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
Johan Johansson wrote:
>
> David Griffiths skrev i meddelandet
>
> >Fine. And I could create a class analogous to your configure visitor. It
> >would have just one method with a switch statement in it. All the cases
> >contained in there.
>
> Then what's the difference? What you have done then is simply to merge all
> (currently known) visitors into one, deciding inside the method which one to
> act like. What if you can't change this class once it's distributed, or if
> *someone else* who cannot access the source wants to add a new modem? Do
> you/he/she then assemble another "supervisitor" containing just the new
> ones?

No, I said one class with one method in it.

The difference is that it's simpler. It reuses the "switch statement
pattern" that we're all familiar with.

Besides, the whole point of this thread is, you shouldn't be asking ME
what's the difference, you should be asking RM! He's the one who has
introduced the more elaborate solution, and I'm just asking "why not use
a switch statement?".

Occam's Razor basically.

Dave

Robert Martin

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to

David Griffiths wrote in message <35D4702C...@prim.demon.co.uk>...

>
>That's true. So you'll get an unneccessary recompile of the modem
>heirarchy. Big deal. If it matters that much, you can use #defines in
>the Modem derivative's header file.


Good! Now we understand each other better.

Clearly the #defines that you suggest are an ugly solution since they cannot
be checked at compile time. Since the #defines are in different files,
there is nothing that forces their values to be unique. It would be better
if the compiler could enforce uniqueness.

Why would we be worried about unnecessary recompiles? There are several
reasons. In large systems, unnecessary recompiles can result in hours and
hours of extra compile time. One of my clients uses 50 computers to
recompile their software over a period of several hours. Secondly,
anything that gets recompiled must be re-released; and this can add
significant clerical and verification burden. Finally, anything that gets
recompiled must be redistributed; which is a significant problem in those
systems that hope to maintain independent dynamically linkable components
(DLLs, Shared Libraries, etc.) The upshot of this is, that there are times
when you *are* very concerned about unecessary compiles.

There are also times when you are also very concerned about compile time
safety. When you have dozens, or hundreds of engineers working on the same
system and cannot rely upon simple conventions to maintain the integrity.
In such cases, #defines in each modem derivative are not adequate.

The Acyclic Visitor provides compile time safety and minimal recompile
impact. In those situations where this is necessary, the pattern is very
useful. In those situations where you are sure you will never need compile
time safety or minimal recompile impact, you can resort to switch
statements.

Patrick Logan

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:

: Occam's Razor basically.

Ocam's Razor says you should choose the simplest explanation for some
observation, right? How does it apply to this discussion?

Tony

unread,
Aug 14, 1998, 3:00:00 AM8/14/98
to
In article <35D2F90A...@prim.demon.co.uk>, da...@prim.demon.co.uk
says...

> BTW, I'm a little confused by the fact that you have the configure stuff
> in a separate class outside Modem. What's the Modem class for if not for
> encapsulating things like how to configure the modem, dial it, hangup
> and so on. Doesn't sound like there's any need for either AVP or switch
> statements, just a heirarchy of Modem classes where inheritance can
> exploit the similarity of a lot of modems to each other.

Really, isn't the _component_ something like below without having to
recompile anything? (Sorry if I've jumped into the middle of this thread
and am off base on the actual jist of it).

ModemInterface
|
____________________________
| | |
HayesModem USRModem BOCAModem


>
> > Fortunately, the file 'modem.h' does not need to be modified when the new
> > derivative to Modem is added; and thus nobody who #includes modem.h must
> > recompile.
>

> Put the enum in a file called ModemTypes.h. The only files that depend
> on it are the very files which will need to be modified to cope with the
> new type.

"ModemTypes.h"! Ouch!

Tony

Ell

unread,
Aug 15, 1998, 3:00:00 AM8/15/98
to
"Robert Martin" <rma...@oma.com> wrote:

>Ell wrote in message <35d38b61...@news.erols.com>...
>>

>>Secondly, the point beginning with the writer who didn't like objects,
>>was how we view and use OO objects in terms OO program semantics.
>>Period. The writer was not hung up on how OO objects were
>>implemented. What he didn't like was the logical, semantic role
>>objects played.

>I didn't interpret his complaint that way. I interpreted his complaint as:
>"OO promises everything and doesn't deliver everything; therefore OO is a
>crock."

Here's what McClendon said:
>>>Other than the concept of objects themselves, I agree with most
>>>of the design goals of OO. I just don't agree with the methods.

Before that he pointed out various ways that OO helps with dependency
management (DM). So, on the one hand he fails to see how objects and
their auxiliary, polymorphism (which in general should be mostly based
upon application domain semantics), can be used to implement a great
DM concept, the open closed principle (OCP). On the other hand he
fails to see that from the point of view of application semantics, how
objects that have behavioral responsibility, based upon use case, and
domain modelling, can help to reduce the cognitive load, and
complexity of application structure for both development, and
maintenance for programmers.

I do not see how your immediate response to what he said:
>>Objects are just data structures that are operated upon by
>>functions that are accessed through a jump table. What's not to
>>agree with?

helps with either aspect of what he is truly missing about objects.
If anything I can see where anti-OOPers would say in response to what
you said, "why bother"? I can see where they would ask, what does the
fact that objects are data structures operated upon by functions that
are accessed through a jump table offer me?

Not to mention that the jump table part isn't even necessary to
implementing OO objects, or understanding either their DM or semantic
roles.

However if they understand the value of OCP, and how objects with
polymorphism achieve that, and if they understand how objects can help
to reduce the cognitive load, and complexity of application structure
for both development and maintenance for programmers, then I think
those make a better case for using objects and adopting OO in toto.

>Instead of regression, consider it minimalism. And consider that it was
>minimalism for the purpose of instruction. Sometimes if you reduce a
>complex issue down into is most minimal form, you can help someone else
>understand it. And then they can begin along the path of understanding the
>issue in its full complexity.

I don't see it as minimalism. As I've explained above, I think you've
missed the points that make the case for using objects altogether.

David Griffiths

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
Robert Martin wrote:

> Clearly the #defines that you suggest are an ugly solution since they cannot
> be checked at compile time. Since the #defines are in different files,
> there is nothing that forces their values to be unique. It would be better
> if the compiler could enforce uniqueness.

No, I don't like them either. I only suggested them as an alternative if
you were really concerned about compile time.

> Why would we be worried about unnecessary recompiles? There are several
> reasons. In large systems, unnecessary recompiles can result in hours and
> hours of extra compile time. One of my clients uses 50 computers to
> recompile their software over a period of several hours. Secondly,
> anything that gets recompiled must be re-released; and this can add
> significant clerical and verification burden. Finally, anything that gets
> recompiled must be redistributed; which is a significant problem in those
> systems that hope to maintain independent dynamically linkable components
> (DLLs, Shared Libraries, etc.) The upshot of this is, that there are times
> when you *are* very concerned about unecessary compiles.

Although the modem derivatives _would_ be recompiled, the resulting
binaries would not be different. Also think about the case in point.
This recompilation only occurs when you add a new modem derivative. The
sort of thing that happens (say) every few weeks or so. It takes about
five or ten minutes background processing to recompile the 80 existing
modem derivatives. Compare that with your scheme where you have the
overhead of an additional 160 files (visitor class plus header file per
derivative) and where adding a new derivative involves creating this
extra visitor class, documenting it, adding it to makefiles and so on.
Not to mention writing the Accept method (and I'm curious about what you
do where the dynamic cast fails).

But let's assume your scenario where you're trying to avoid recompiling
and redistributing the 80 existing derivatives. Let's say those 80 are
already out in the field and we just want to ship the new one. Adding
the new enum will make them get recompiled. Should they be redistributed
as well even though they haven't changed? Let's assume your case is that
they _must_ be redistributed because you can't be sure that the binaries
haven't changed and let's further assume the worst case where the
binaries _have_ changed because perhaps the base class has changed.
Under your scheme, how do you control the versioning problem? How do you
ship your new modem derivative by itself and be sure that it is
compatible with the base class already out there in the field? You can't
have it both ways - you must either redistribute the full set of modem
base class plus derivatives, in which case you gain nothing over the
enum approach, or you are sure the versions are compatible, in which
case the enum using derivative can also be safely delivered alone.

So all you have gained is the saving of a few minutes background
compilation time every few weeks. But you have lost by imposing a
significant extra clerical and maintenance burden. And don't talk about
"hours of compilation time" - let's try and keep focussed on a specific
example otherwise it'll be open day for red herrings. If it _did_
involve hours of compilation time, then you'd be talking about a system
with maybe tens of thousands of derivatives, in which case we'd have the
nightmare of tens of thousands of unnecessary visitor classes.

Dave

David Griffiths

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
Patrick Logan wrote:
>
> David Griffiths <da...@prim.demon.co.uk> wrote:
>
> : Occam's Razor basically.
>
> Ocam's Razor says you should choose the simplest explanation for some
> observation, right? How does it apply to this discussion?

I was thinking more in terms of choosing the simplest _theory_ and of
programs being sort of like theories. All other things being equal, you
should always go for the simplest programming solution IMO.

(BTW, there seem to be two types of programmer. I'm in the simplest is
best school, but there are a LOT of programmers who's code I've seen who
seem to love the baroque approach. Maybe they just have a more artistic
temperament?)

Dave

Patrick Logan

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:

: > : Occam's Razor basically.

: I was thinking more in terms of choosing the simplest _theory_ and


: of programs being sort of like theories. All other things being
: equal, you should always go for the simplest programming solution

But it is arguable which is "simplest". As the debate shows, it
depends on the conditions. As complexity of the entire program grows,
the AVP becomes more maintainable, and so the measure of "simple"
changes.

: (BTW, there seem to be two types of programmer. I'm in the simplest


: is best school, but there are a LOT of programmers who's code I've
: seen who seem to love the baroque approach. Maybe they just have a
: more artistic temperament?)

I've seen complex code that has lacked all artistry. On the other hand
I've seen some pretty simple code that doesn't carry its weight. I
don't think it is that easy. A misapplied Visitor can be a
disaster. An opportunity to use a Visitor can also be a disaster.

Patrick Logan

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:

: So all you have gained is the saving of a few minutes background


: compilation time every few weeks.

What about the time the programmer missed one of the switch
statements. The compiler did not complain. But the application crashed
and required time to find out why.

David Griffiths

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
Patrick Logan wrote:
>
> David Griffiths <da...@prim.demon.co.uk> wrote:
>
> : > : Occam's Razor basically.
>
> : I was thinking more in terms of choosing the simplest _theory_ and
> : of programs being sort of like theories. All other things being
> : equal, you should always go for the simplest programming solution
>
> But it is arguable which is "simplest". As the debate shows, it
> depends on the conditions. As complexity of the entire program grows,
> the AVP becomes more maintainable, and so the measure of "simple"
> changes.

Provide an example (preferably an extension of the given modem example)
where the AVP makes for more maintainability. My contention is that it
does just the opposite by requiring more files and more complex
interactions.

Dave

David Griffiths

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
Patrick Logan wrote:
>
> David Griffiths <da...@prim.demon.co.uk> wrote:
>
> : So all you have gained is the saving of a few minutes background
> : compilation time every few weeks.
>
> What about the time the programmer missed one of the switch
> statements. The compiler did not complain. But the application crashed
> and required time to find out why.

What about the time the programmer forgets to add the Visit method. The
compiler did not complain. But then the dynamic cast failed and required


time to find out why.

BTW, I really think RM's Accept method should be returning a boolean to
indicate success or failure rather than void. You want the user of the
Accept method to decide what to do upon cast failure rather than
hard-wiring it into the Modem derivative. (Or rather into the Modem base
class - let's not make this into even more of a maintainence headache
than it is already. :)

Dave

Patrick Logan

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:

: Provide an example (preferably an extension of the given modem example)


: where the AVP makes for more maintainability. My contention is that it
: does just the opposite by requiring more files and more complex
: interactions.

My example a week ago or so was one where the framework is provided by
one vendor and the extension is provided by another vendor or in
house. Switch staements are not extensible, but Visitor is, without
recompiling.

Brian Rogoff

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to
On Sun, 16 Aug 1998, Patrick Logan wrote:
> David Griffiths <da...@prim.demon.co.uk> wrote:
>
> : So all you have gained is the saving of a few minutes background
> : compilation time every few weeks.
>
> What about the time the programmer missed one of the switch
> statements. The compiler did not complain. But the application crashed
> and required time to find out why.

Thankfully, there are languages for which a non-exhaustive case/switch
statement is a compile time error.

In languages which have safe case statements and OO style single dispatch,
the choice between Visitor and case is a bit difficult. The Visitor
pattern in all its variants have always seemed like a rather unpleasant
workaround to a language deficiency in some OO languages to me; for
example the "categories" of Objective-C or multiple-dispatch in CLOS and
kin. I think I would side with David Griffiths here, though I understand
that Robert Martin is coming from the perspective of a language without
safe case statements and so the cost of an error there is potentially
greater. I also imagine that if other design constraints that RM discusses
became important enough, maybe ACV would be a good solution, but it is
a *lot* more complex to understand than case statements.

-- Brian

Robert Martin

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to

Ell wrote in message <35d6dfdf...@news.erols.com>...

>"Robert Martin" <rma...@oma.com> wrote:
>
>>Ell wrote in message <35d38b61...@news.erols.com>...
>>>
>>>Secondly, the point beginning with the writer who didn't like objects,
>>>was how we view and use OO objects in terms OO program semantics.
>>>Period. The writer was not hung up on how OO objects were
>>>implemented. What he didn't like was the logical, semantic role
>>>objects played.
>
>>I didn't interpret his complaint that way. I interpreted his complaint
as:
>>"OO promises everything and doesn't deliver everything; therefore OO is a
>>crock."
>
>Here's what McClendon said:
> >>>Other than the concept of objects themselves, I agree with most
> >>>of the design goals of OO. I just don't agree with the methods.
>
>Before that he pointed out various ways that OO helps with dependency
>management (DM). So, on the one hand he fails to see how objects and
>their auxiliary, polymorphism (which in general should be mostly based
>upon application domain semantics), can be used to implement a great
>DM concept, the open closed principle (OCP). On the other hand he
>fails to see that from the point of view of application semantics, how
>objects that have behavioral responsibility, based upon use case, and
>domain modelling, can help to reduce the cognitive load, and
>complexity of application structure for both development, and
>maintenance for programmers.
>
>I do not see how your immediate response to what he said:
> >>Objects are just data structures that are operated upon by
> >>functions that are accessed through a jump table. What's not to
> >>agree with?
>
>helps with either aspect of what he is truly missing about objects.
>If anything I can see where anti-OOPers would say in response to what
>you said, "why bother"? I can see where they would ask, what does the
>fact that objects are data structures operated upon by functions that
>are accessed through a jump table offer me?

Any programmer with a reasonable amount of experience has probably solved a
nasty dependency problem by using a jump table. It's not that uncommon of
an approach. One of the most common examples is the stdio library. The
functions {open, close, read, write} are, after all, functions that
manipulate a data structure, and are accessed through a jump table. It is
difficult to deny the significant benefit that device independence gives the
stdio library; and so it should be difficult to deny that using jump tables
can be a beneficial approach.

>However if they understand the value of OCP, and how objects with
>polymorphism achieve that, and if they understand how objects can help
>to reduce the cognitive load, and complexity of application structure
>for both development and maintenance for programmers, then I think
>those make a better case for using objects and adopting OO in toto.

Well, the first part was my intention. It is difficult to argue against the
OCP, and it is also difficult to argue that jump tables don't provide a
means for sometimes achieving the OCP. (Again, the example of device
independence comes to mind).

As for the "cognitive load" issue; I don't think that a reduction of
cognitive load is easy to prove; or even demonstrate. Indeed, it seems to
me that OO designs that focus upon conformance to the OCP (an undeniably
good thing) tend to have a *higher* cognitive load than those that don't.
Witness the argument in this same thread regarding switch statements vs
visitors. This is clearly and OCP issue, and yet the argument is that the
extra complexity of the visitor pattern is not worth the looser coupling and
conformance to OCP.

In general I think looser coupling involves greater cognitive load than
tighter coupling does. After all, not only do you have to understand the
application, you must also understand the structures you are putting in
place to reduce coupling and conform to the OCP.

Robert Martin

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to

David Griffiths wrote in message <35D6E22C...@prim.demon.co.uk>...

>Patrick Logan wrote:
>>
>> David Griffiths <da...@prim.demon.co.uk> wrote:
>>
>> : Occam's Razor basically.
>>
>> Ocam's Razor says you should choose the simplest explanation for some
>> observation, right? How does it apply to this discussion?
>
>I was thinking more in terms of choosing the simplest _theory_ and of
>programs being sort of like theories. All other things being equal, you
>should always go for the simplest programming solution IMO.

>
>(BTW, there seem to be two types of programmer. I'm in the simplest is
>best school, but there are a LOT of programmers who's code I've seen who
>seem to love the baroque approach. Maybe they just have a more artistic
>temperament?)
>


The question is: "simplest for whom?".

It is quite possible to create a software structure that is very simple to
understand, and yet is very difficult to change. For example, consider the
file "error.h". This file contains a suite of #defines that provide error
codes that are returned by the functions in an application. Nearly every
module in the system #includes error.h.

Now this is a very simple structure to understand. But it is horrifically
difficult to maintain. Every time a new error code is needed, you face the
specter of either recompiling every module in the system, or (horror of
horrors) manually choosing those modules that need recompilation and
ignoring the others (by touching the .o files! yech.)

Faced with this, we often cheat. We might reuse an old error code that is
"close enough" rather than create a new more appropriate one. Or we might
add the new error code to the numeric end of the others, leading to an
error.h file that has no reasonable structure.

The point is that a structure that is simple to understand is not
necessarily simple to maintain. And the extra complexity (you called it
baroque-ness) invested to make software easier to maintain can often make
the job of the maintainer much simpler.

If you've ever had to change an oil filter that was in a position that was
impossible to reach, I'm sure you had a few choice words for the designers
of the engine. It may be very simple to understand *why* the oil filter is
in such an unreachable position; but that doesn't help you. And you could
easily wish that the designers had added just a little more complexity to
the engine in order to make that oil filter just a little more accessible.

Robert Martin

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to

David Griffiths wrote in message <35D6E0DA...@prim.demon.co.uk>...

>Robert Martin wrote:
>
>> Clearly the #defines that you suggest are an ugly solution since they
cannot
>> be checked at compile time. Since the #defines are in different files,
>> there is nothing that forces their values to be unique. It would be
better
>> if the compiler could enforce uniqueness.
>
>No, I don't like them either. I only suggested them as an alternative if
>you were really concerned about compile time.
>
>> Why would we be worried about unnecessary recompiles? There are several
>> reasons. In large systems, unnecessary recompiles can result in hours
and
>> hours of extra compile time. One of my clients uses 50 computers to
>> recompile their software over a period of several hours. Secondly,
>> anything that gets recompiled must be re-released; and this can add
>> significant clerical and verification burden. Finally, anything that
gets
>> recompiled must be redistributed; which is a significant problem in those
>> systems that hope to maintain independent dynamically linkable components
>> (DLLs, Shared Libraries, etc.) The upshot of this is, that there are
times
>> when you *are* very concerned about unecessary compiles.
>
>Although the modem derivatives _would_ be recompiled, the resulting
>binaries would not be different.

Even if that were so, it is arguable that they should be redistributed in
any case. However, the presumption is incorrect. Compilers may decide to
change the size of the underlying integer when more items are added to an
enum. Even if you could guarantee that the size would not change, one would
have to add the new enumerators onto the end of the enumeration in order to
preserve binary equivalence; and that can lead to arbitary structure in
large enumerations.

>Also think about the case in point.
>This recompilation only occurs when you add a new modem derivative. The
>sort of thing that happens (say) every few weeks or so. It takes about
>five or ten minutes background processing to recompile the 80 existing
>modem derivatives.

Don't minimize the compile time issue. Also, don't reduce the problem to
compile time. As I stated before, large projects can have enormous compile
times because of mismanaged dependencies. And even when compile time is not
an issue, reverification and redistrubution may be.

>Compare that with your scheme where you have the
>overhead of an additional 160 files (visitor class plus header file per
>derivative) and where adding a new derivative involves creating this
>extra visitor class, documenting it, adding it to makefiles and so on.
>Not to mention writing the Accept method (and I'm curious about what you
>do where the dynamic cast fails).

If you are worried about file count (a valid concern), and you don't mind
all the concrete visitors recompiling every time you change one of the modem
derivative header files, then the visitor base classes can go in the header
file of the derivative. After all, the visitor class amounts to:

class ModemXVisitor {public: virtual void Visit(ModemX*) = 0;};

However, if you are not concerned with file count, then the number of
visitor base class files equals the number of derivatives (80 in your case)
since there are no specific implementation files for them.

I agree that this is an overhead, but where compile time, verification, and
distribution are issues, this may be preferable to the alternative.

>But let's assume your scenario where you're trying to avoid recompiling
>and redistributing the 80 existing derivatives. Let's say those 80 are
>already out in the field and we just want to ship the new one. Adding
>the new enum will make them get recompiled. Should they be redistributed
>as well even though they haven't changed? Let's assume your case is that
>they _must_ be redistributed because you can't be sure that the binaries
>haven't changed and let's further assume the worst case where the
>binaries _have_ changed because perhaps the base class has changed.
>Under your scheme, how do you control the versioning problem? How do you
>ship your new modem derivative by itself and be sure that it is
>compatible with the base class already out there in the field? You can't
>have it both ways - you must either redistribute the full set of modem
>base class plus derivatives, in which case you gain nothing over the
>enum approach, or you are sure the versions are compatible, in which
>case the enum using derivative can also be safely delivered alone.

With ACV you ship them all only when the base class changes. With switch
statements you ship them all every time there is a new derivative. (or you
play some unsavory games with binary comparisons; which I doubt anyone
really wants to do).

>So all you have gained is the saving of a few minutes background

>compilation time every few weeks. But you have lost by imposing a
>significant extra clerical and maintenance burden.

No, I have gained something more. I have the sure knowledge that a new
derivative will *never* force me to recompile, revalidate, or redistribute
the existing derivatives.

Robert Martin

unread,
Aug 16, 1998, 3:00:00 AM8/16/98
to

Brian Rogoff wrote in message ...

>In languages which have safe case statements and OO style single dispatch,
>the choice between Visitor and case is a bit difficult. The Visitor
>pattern in all its variants have always seemed like a rather unpleasant
>workaround to a language deficiency in some OO languages to me; for
>example the "categories" of Objective-C or multiple-dispatch in CLOS and
>kin. I think I would side with David Griffiths here, though I understand
>that Robert Martin is coming from the perspective of a language without
>safe case statements and so the cost of an error there is potentially
>greater. I also imagine that if other design constraints that RM discusses
>became important enough, maybe ACV would be a good solution, but it is
>a *lot* more complex to understand than case statements.


Granted. ACV is not a global solution. There are times when case
statements, or other forms of dispatch, are the best options. And there are
times when Visitors, or Acyclic Visitors are the best solutions.

Patrick Logan

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:

: Patrick Logan wrote:
: >
: > David Griffiths <da...@prim.demon.co.uk> wrote:
: >
: > : So all you have gained is the saving of a few minutes background

: > : compilation time every few weeks.
: >
: > What about the time the programmer missed one of the switch

: > statements. The compiler did not complain. But the application crashed
: > and required time to find out why.

: What about the time the programmer forgets to add the Visit method. The
: compiler did not complain. But then the dynamic cast failed and required


: time to find out why.

In the switch case, you have to remember to fix more than one location
in the source code for the entire system.

In the Visitor case, you have to remember how to implement the one
class you are adding.

I think the Visitor scenario is easier to maintain.

Patrick Logan

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
Brian Rogoff <b...@shell5.ba.best.com> wrote:

: On Sun, 16 Aug 1998, Patrick Logan wrote:
: > David Griffiths <da...@prim.demon.co.uk> wrote:
: >
: > : So all you have gained is the saving of a few minutes background
: > : compilation time every few weeks.
: >
: > What about the time the programmer missed one of the switch
: > statements. The compiler did not complain. But the application crashed
: > and required time to find out why.

: Thankfully, there are languages for which a non-exhaustive case/switch

: statement is a compile time error.

Do they prevent you from using an "OTHERWISE" case? Do you have to
explicitly enumerate each case?

Anyway, this argument would not apply to the languages we are
currently discussing. Nor would it ensure that the developers *always*
used the switch statement, never using an if/else.

Nor does this argument address the multiple vendors scenario where you
and I each wish to extend the number of cases initially provided by
some other vendor.

: In languages which have safe case statements and OO style single dispatch,


: the choice between Visitor and case is a bit difficult. The Visitor
: pattern in all its variants have always seemed like a rather unpleasant
: workaround to a language deficiency in some OO languages to me

In fact Smalltalk and its team programming environments make Visitor
less appealing. But they do not resort to a switch statement.

And as you said, CLOS, Dylan, and Cecil (perhaps others) provide
multiple argument dispatch.

But none of these lead me to desire a *switch* statement over Visitor.

: maybe ACV would be a good solution, but it is a *lot* more complex


: to understand than case statements.

But once you understand it, it is a *lot* more usable. Pay me now or
pay me later.

Brian Rogoff

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
On Mon, 17 Aug 1998, Patrick Logan wrote:
> Brian Rogoff <b...@shell5.ba.best.com> wrote:
> : On Sun, 16 Aug 1998, Patrick Logan wrote:
> : > What about the time the programmer missed one of the switch
> : > statements. The compiler did not complain. But the application crashed
> : > and required time to find out why.
>
> : Thankfully, there are languages for which a non-exhaustive case/switch
> : statement is a compile time error.
>
> Do they prevent you from using an "OTHERWISE" case?

Of course not. But in such languages programmers tend not to overuse the
"when others" or "default:" option, so your concern appears more like
an academic argument than an actual problem.

> Do you have to
> explicitly enumerate each case?

If you don't have a catch-all (OTHERWISE as you named it) then yes you
would have to enumerate all cases, which is what you'd want here.

> Anyway, this argument would not apply to the languages we are
> currently discussing. Nor would it ensure that the developers *always*
> used the switch statement, never using an if/else.

As I said, it doesn't apply to C and its offspring. If thats all you know
of statically typed "Algolesque" languages, let me suggest that you get
out more. :-)

> Nor does this argument address the multiple vendors scenario where you
> and I each wish to extend the number of cases initially provided by
> some other vendor.

No, it doesn't. But that isn't always something I need, and I tend to
favor the simplest solution over the most general, all other things
being equal. At Henry Baker's web site, there is a paper in which he (HB)
proposes an extension to Ada 83 which would handle this case, essentially
allowing one to add new enum values to an existing enum, sort of a
lightweight form of inheritance. I don't know of any language which
actually allows this, but the idea is intriguing.

> : In languages which have safe case statements and OO style single dispatch,
> : the choice between Visitor and case is a bit difficult. The Visitor
> : pattern in all its variants have always seemed like a rather unpleasant
> : workaround to a language deficiency in some OO languages to me
>
> In fact Smalltalk and its team programming environments make Visitor
> less appealing. But they do not resort to a switch statement.
>
> And as you said, CLOS, Dylan, and Cecil (perhaps others) provide
> multiple argument dispatch.

Objective-C has categories, which allow you to add new methods to an
existing class. That's very useful, but like multidispatch, probably
precludes certain optimizations.

> But none of these lead me to desire a *switch* statement over Visitor.

As always, you have the right to your opinion. I don't find switch
horrible. Dynamic dispatch replaces almost all switch statements, but
in some situations a switch is the clearest, simplest solution. Since
you use Haskell, I'm sure you recognize that pattern matching on data
types is a sort of souped up switch.

> : maybe ACV would be a good solution, but it is a *lot* more complex
> : to understand than case statements.
>
> But once you understand it, it is a *lot* more usable. Pay me now or
> pay me later.

Sometimes. Sometimes the additional complexity is not worth the price.
And sometimes the feature I might want (categories, multimethods) adds a
cost to those who don't want to use it. Thats why programming is hard, and
there aren't always universal answers.

-- Brian

David Griffiths

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
Robert Martin wrote:

> Even if that were so, it is arguable that they should be redistributed in
> any case. However, the presumption is incorrect. Compilers may decide to
> change the size of the underlying integer when more items are added to an
> enum.

That doesn't affect the base class, so there's no need to redistribute.

> Even if you could guarantee that the size would not change, one would
> have to add the new enumerators onto the end of the enumeration in order to
> preserve binary equivalence; and that can lead to arbitary structure in
> large enumerations.

Oh no, not the old "arbitary structure in large enumerations" problem
that we see so often. I think you're clutching at straws here.

> Don't minimize the compile time issue. Also, don't reduce the problem to
> compile time.

Well I'm trying to boil this all down to its essence and discover what
unique benefits AVP has over switch statements. Compile time appears to
be the only one so far. (Oh and BTW, a point I forgot to make earlier:
the time taken to do a complete recompile of a system using AVP will of
course be greater since there's more code.)

> As I stated before, large projects can have enormous compile
> times because of mismanaged dependencies.

That has nothing to do with the specific issue in hand. Too hand-wavy.



> >But let's assume your scenario where you're trying to avoid recompiling
> >and redistributing the 80 existing derivatives. Let's say those 80 are
> >already out in the field and we just want to ship the new one. Adding
> >the new enum will make them get recompiled. Should they be redistributed
> >as well even though they haven't changed? Let's assume your case is that
> >they _must_ be redistributed because you can't be sure that the binaries
> >haven't changed and let's further assume the worst case where the
> >binaries _have_ changed because perhaps the base class has changed.
> >Under your scheme, how do you control the versioning problem? How do you
> >ship your new modem derivative by itself and be sure that it is
> >compatible with the base class already out there in the field? You can't
> >have it both ways - you must either redistribute the full set of modem
> >base class plus derivatives, in which case you gain nothing over the
> >enum approach, or you are sure the versions are compatible, in which
> >case the enum using derivative can also be safely delivered alone.
>
> With ACV you ship them all only when the base class changes. With switch
> statements you ship them all every time there is a new derivative. (or you
> play some unsavory games with binary comparisons; which I doubt anyone
> really wants to do).

No, you don't need to reship for switch + new derivative. The base class
didn't change. I'm assuming that there's some human intelligence behind
all this BTW. It's hard to imagine some automated process that is
reshipping only updated binaries and no-one is bothering to test whether
the components still work together. If you have some such scheme in mind
let me know and I'll invent my switch statement alternative. :)

> No, I have gained something more. I have the sure knowledge that a new
> derivative will *never* force me to recompile, revalidate, or redistribute
> the existing derivatives.

The switch alternative only involves recompilation. There is no need to
revalidate and redistribute if an enum was appended. The base class
didn't change. (I'm not storing the type in a field in the base class
BTW, just returning it in a method in the derivative).

Dave

David Griffiths

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
Patrick Logan wrote:

> In the switch case, you have to remember to fix more than one location
> in the source code for the entire system.
>
> In the Visitor case, you have to remember how to implement the one
> class you are adding.
>
> I think the Visitor scenario is easier to maintain.

Maybe I didn't make my "analogies" clear. I have in mind (just for the
sake of this particular argument to keep things clear) a class
containing just one method and that method containing the switch
statement. And this is shadowing (if you like) the AVP visitor class. So
where RM has ConfigureForUnixVisitor which contains one method per modem
type, I have ConfigureForUnixSwitch with one case statement per modem
type. The way I've arranged this alternative, there is a one-to-one
mapping between the two. If you were implementing a new class for
Visitor, you'd be implementing a new class for Switch.

But Switch is easier. :)

Dave

David Griffiths

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
Patrick Logan wrote:

> My example a week ago or so was one where the framework is provided by
> one vendor and the extension is provided by another vendor or in
> house. Switch staements are not extensible, but Visitor is, without
> recompiling.

I need the context of an example to understand what you're saying. Do
you mean that you would have ConfigureForUnixVisitor supplied by one
vendor and an ExtendedConfigureForUnixVisitor supplied by another vendor
for some additional modem types? Why can't this just as easily be done
as two Configure methods with switch statements? (The methods being in
some object external to the Modem derivatives.) Or maybe you have in
mind that the second vendor subclasses ConfigureForUnixVisitor? (Again
this can be managed easily with switch statements). Not sure what you
mean.

Dave

Patrick Logan

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
Brian Rogoff <b...@shell5.ba.best.com> wrote:
: >
: > Do they prevent you from using an "OTHERWISE" case?

: Of course not. But in such languages programmers tend not to overuse the
: "when others" or "default:" option, so your concern appears more like
: an academic argument than an actual problem.

These must be a fine breed of programmers, the likes of which I have
never seen in great numbers. If they are so disciplined, then they
don't even need this language featuer at all, eh?

: > Anyway, this argument would not apply to the languages we are


: > currently discussing. Nor would it ensure that the developers *always*
: > used the switch statement, never using an if/else.

: As I said, it doesn't apply to C and its offspring. If thats all you know
: of statically typed "Algolesque" languages, let me suggest that you get
: out more. :-)

That's not all I know. But their popularity make them a valid point of
discussion.

: > Nor does this argument address the multiple vendors scenario where you


: > and I each wish to extend the number of cases initially provided by
: > some other vendor.

: No, it doesn't. But that isn't always something I need, and I tend to
: favor the simplest solution over the most general, all other things
: being equal. At Henry Baker's web site, there is a paper in which he (HB)
: proposes an extension to Ada 83 which would handle this case, essentially
: allowing one to add new enum values to an existing enum, sort of a
: lightweight form of inheritance. I don't know of any language which
: actually allows this, but the idea is intriguing.

Then it is just another form of object-oriented programming. And a bit
more painful, it seems to me. After all, we are only arguing about the
need for switch vs. the need for Visitor. In my experience the need
for Visitor is pretty small relative to the number of non-Visitor
method calls! Are you arguing for switch vs. *any* use of dispatched
methods?

: Objective-C has categories, which allow you to add new methods to an


: existing class. That's very useful, but like multidispatch, probably
: precludes certain optimizations.

I wouldn't jump to conclusions. The dynamic language folks are getting
pretty good at runtime optimizations. (The year-late Hot Spot for Java
casting a dark shadow over this claim, ugh!)

: As always, you have the right to your opinion. I don't find switch


: horrible. Dynamic dispatch replaces almost all switch statements, but
: in some situations a switch is the clearest, simplest solution. Since
: you use Haskell, I'm sure you recognize that pattern matching on data
: types is a sort of souped up switch.

Yes. But even a Haskell is adopting existential types, which
essentially provides dynamic dispatch. The need for a Visitor pattern
is still an issue.

David Griffiths

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
Robert Martin wrote:

> It is quite possible to create a software structure that is very simple to
> understand, and yet is very difficult to change. For example, consider the
> file "error.h". This file contains a suite of #defines that provide error
> codes that are returned by the functions in an application. Nearly every
> module in the system #includes error.h.
>
> Now this is a very simple structure to understand. But it is horrifically
> difficult to maintain. Every time a new error code is needed, you face the
> specter of either recompiling every module in the system, or (horror of
> horrors) manually choosing those modules that need recompilation and
> ignoring the others (by touching the .o files! yech.)

Interesting example. I spent a few years as a Unix kernel developer. The
"difficulty" you mention never arose. It's kind of surreal to sit here
reading about "difficulties" in something I've had direct experience of.
But to give you the benefit of the doubt, you might not be talking about
the error.h that comes supplied with your Unix system.

Unix of course - with its simple and allegedly difficult to maintain
structures - has been a phenomenal success.

BTW, "patterns" has two meanings. Thers's the knitting pattern sort that
you can invent, and there's the pattern of behaviour that you can
observe. I'd always thought that the GoF meant the latter when they
talked about patterns, in which case inventing a pattern would be a
contradiction in terms. Unfortunately I've lent my copy to someone else.

It's brave of you to argue so strongly for something with practically no
track record to replace such a tried and tested pattern as enum/switch.

Dave

Patrick Logan

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:
: Robert Martin wrote:

: > It is quite possible to create a software structure that is very simple to
: > understand, and yet is very difficult to change. For example, consider the
: > file "error.h". This file contains a suite of #defines that provide error
: > codes that are returned by the functions in an application. Nearly every
: > module in the system #includes error.h.
: >
: > Now this is a very simple structure to understand. But it is horrifically
: > difficult to maintain. Every time a new error code is needed, you face the
: > specter of either recompiling every module in the system, or (horror of
: > horrors) manually choosing those modules that need recompilation and
: > ignoring the others (by touching the .o files! yech.)

: Interesting example. I spent a few years as a Unix kernel developer. The
: "difficulty" you mention never arose. It's kind of surreal to sit here
: reading about "difficulties" in something I've had direct experience of.
: But to give you the benefit of the doubt, you might not be talking about
: the error.h that comes supplied with your Unix system.

: Unix of course - with its simple and allegedly difficult to maintain
: structures - has been a phenomenal success.

(1) There are differences between Unix systems that drive people batty
who have to run on multiple hosts.

(2) This is a good example of the stability principle: Unix has not
changed much because it cannot change much because everyone
depends on it staying relatively the same.

(Of course this is something of a double edged sword. Microsoft
seems to have the idea that their OS can change dramatically each
year. It is difficult to make their schedules and the resulting
instability drives customers batty anyway.)

: It's brave of you to argue so strongly for something with practically no


: track record to replace such a tried and tested pattern as enum/switch.

Rhetoric will do you no good. The problems of maintaining switch
statements are known far and wide. Visitor is a technique that has
proven itself over and over. Looks like neither side can convince the
other?

Patrick Logan

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:

I mean what if I have a framework from some vendor and they have a
Sprocket abstraction. Say I want to extend it with a new kind of
Sprocket, say a SpacelySpaceSprocket. Using switch statements only,
I'd have to modify the framework's source code. Using object-oriented
programming, all I have to do is link my code with their binary,
unmodified.

Patrick Logan

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
David Griffiths <da...@prim.demon.co.uk> wrote:
: Patrick Logan wrote:

: > In the switch case, you have to remember to fix more than one location

So in essence you are implementing a dynamic dispatch mechanism all by
yourself. That still does not help the multiple vendor scenario. If we
all want to use and extend your dispatch mechanism, you are going to
be busy getting the code rebuilt and revalidated and released to us!

Brian Rogoff

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to
On Mon, 17 Aug 1998, Patrick Logan wrote:
> Brian Rogoff <b...@shell5.ba.best.com> wrote:
> : >
> : > Do they prevent you from using an "OTHERWISE" case?
>
> : Of course not. But in such languages programmers tend not to overuse the
> : "when others" or "default:" option, so your concern appears more like
> : an academic argument than an actual problem.
>
> These must be a fine breed of programmers, the likes of which I have
> never seen in great numbers. If they are so disciplined, then they
> don't even need this language featuer at all, eh?

Umm, I consider myself a pretty disciplined programmer, but I still use
goto in some languages when I think its the right solution, even if
I could use some other language construct. OTHERWISE is sometimes useful,
sometimes not.

My point is that there is definitely a language culture issue at work
here. I'm sure if I knew Smalltalk well enough, I could make up some
goofy use of its features that would cast it in a bad light, even if
it almost never happens when experienced Smalltalk users write code.

> : > Anyway, this argument would not apply to the languages we are
> : > currently discussing. Nor would it ensure that the developers *always*
> : > used the switch statement, never using an if/else.
>
> : As I said, it doesn't apply to C and its offspring. If thats all you know
> : of statically typed "Algolesque" languages, let me suggest that you get
> : out more. :-)
>
> That's not all I know. But their popularity make them a valid point of
> discussion.

Thats correct, but you'll note that the very first sentence of my reply
was "thankfully there are languages in which" blah blah blah. So some of
the criticisms of a switch solution have much less force when the language
in question makes it harder to make the mistake you are mentioning.

> : > Nor does this argument address the multiple vendors scenario where you
> : > and I each wish to extend the number of cases initially provided by
> : > some other vendor.
>
> : No, it doesn't. But that isn't always something I need, and I tend to
> : favor the simplest solution over the most general, all other things
> : being equal. At Henry Baker's web site, there is a paper in which he (HB)
> : proposes an extension to Ada 83 which would handle this case, essentially
> : allowing one to add new enum values to an existing enum, sort of a
> : lightweight form of inheritance. I don't know of any language which
> : actually allows this, but the idea is intriguing.
>
> Then it is just another form of object-oriented programming. And a bit
> more painful, it seems to me. After all, we are only arguing about the
> need for switch vs. the need for Visitor. In my experience the need
> for Visitor is pretty small relative to the number of non-Visitor
> method calls! Are you arguing for switch vs. *any* use of dispatched
> methods?

Absolutely not! I wasn't even arguing that Visitor is an unmitigated bad
idea, just that switch still has its place in good code, and that the
choice is not obvious. I have no idea where you got this from in my
message, so I hope its clear now.

> : Objective-C has categories, which allow you to add new methods to an
> : existing class. That's very useful, but like multidispatch, probably
> : precludes certain optimizations.
>
> I wouldn't jump to conclusions. The dynamic language folks are getting
> pretty good at runtime optimizations. (The year-late Hot Spot for Java
> casting a dark shadow over this claim, ugh!)

I also still think that there is room for high performance languages, and
neither Java, nor Smalltalk, nor Haskell, nor Ocaml (sniff :-() have
closed the gap enough. I've been hearing for years about "XXX beats
Fortran" in academic papers, but it just ain't so! When a language has too
many of these spiffy features, and you force the compiler writer to go
through all sorts of heroic effort to optimize, you will pay a price,
either in reduced performance, or longer time for complete compilers,
most likely both. Don't read this as saying I think higher level
languages stink; most of the time there is no need for balls-to-the-wall
performance.

-- Brian

Robert Martin

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to

David Griffiths wrote in message <35D87F40...@prim.demon.co.uk>...

>Robert Martin wrote:
>
>> It is quite possible to create a software structure that is very simple
to
>> understand, and yet is very difficult to change. For example, consider
the
>> file "error.h". This file contains a suite of #defines that provide
error
>> codes that are returned by the functions in an application. Nearly
every
>> module in the system #includes error.h.
>>
>> Now this is a very simple structure to understand. But it is
horrifically
>> difficult to maintain. Every time a new error code is needed, you face
the
>> specter of either recompiling every module in the system, or (horror of
>> horrors) manually choosing those modules that need recompilation and
>> ignoring the others (by touching the .o files! yech.)
>
>Interesting example. I spent a few years as a Unix kernel developer. The
>"difficulty" you mention never arose. It's kind of surreal to sit here
>reading about "difficulties" in something I've had direct experience of.
>But to give you the benefit of the doubt, you might not be talking about
>the error.h that comes supplied with your Unix system.

Correct. I'm talking about the error.h files that are common in many
different application.

Or if you don't like error.h, consider packetType.h, or command.h, or any of
a million different kinds of "type".h files that define unbounded sets of
items.

>It's brave of you to argue so strongly for something with practically no
>track record to replace such a tried and tested pattern as enum/switch.

oops, we've left the arena of substance and are starting in towards the ad
hominem arguments. Time to end this thread I think.


Robert C. Martin | Design Consulting | Training courses offered:
Object Mentor | rma...@oma.com | Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 | C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
'Mistrust arguments from authority.'" -- Carl Sagan

>
>Dave

Robert Martin

unread,
Aug 17, 1998, 3:00:00 AM8/17/98
to

Ell wrote in message <35d8daa6...@news.erols.com>...

>"Robert Martin" <rma...@oma.com> wrote:
>
>>One of the most common examples is the stdio library. The
>>functions {open, close, read, write} are, after all, functions that
>>manipulate a data structure, and are accessed through a jump table. It is
>>difficult to deny the significant benefit that device independence gives
the
>>stdio library; and so it should be difficult to deny that using jump
tables
>>can be a beneficial approach.
>
>As I see it the key point should be to stress the polymorphism
>involved not the implementation.

I quite agree. However, some folks, especially the guys who have been
programming for more than a couple of decades, are going to identify better
with jump tables than with the abstract notion of polymorphism; at least at
first. Then, once they have internalized the fact that jump tables are a
form of OO polymorphism, they will be able to look at abstract OO classes
and realize their benefit; even if they aren't implemented that way.

Ell

unread,
Aug 18, 1998, 3:00:00 AM8/18/98
to
"Robert Martin" <rma...@oma.com> wrote:

>Ell wrote in message <35d6dfdf...@news.erols.com>...

Or such programmers have used some type of polymorphic mechanism even
in a non-OOPL, but were they always aware of how the compiler may or
may not have implemented that mechanism? And it really doesn't matter
at the level of abstraction most programmers are dealing with the
language and compiler.

>One of the most common examples is the stdio library. The
>functions {open, close, read, write} are, after all, functions that
>manipulate a data structure, and are accessed through a jump table. It is
>difficult to deny the significant benefit that device independence gives the
>stdio library; and so it should be difficult to deny that using jump tables
>can be a beneficial approach.

As I see it the key point should be to stress the polymorphism

involved not the implementation. In general we want to use
polymorphic phenomena in non-OOPLs to demonstrate that the support for
polymorphism via object substitution in OOPLs, is a very useful, and
powerful thing. [Regardless of how objects and hierarchies of objects
are implemented.]

>>However if they understand the value of OCP, and how objects with
>>polymorphism achieve that, and if they understand how objects can help
>>to reduce the cognitive load, and complexity of application structure
>>for both development and maintenance for programmers, then I think
>>those make a better case for using objects and adopting OO in toto.

>Well, the first part was my intention. It is difficult to argue against the
>OCP,

OK.

>and it is also difficult to argue that jump tables don't provide a
>means for sometimes achieving the OCP. (Again, the example
>of device independence comes to mind).

Yes jump tables are one means for achieving OCP, but as I say above
not everyone is aware that they may have used jump tables in a
non-OOPL, and stressing any form of implementing objects misses the
point. The point is logical, semantic polymorphic object substitution
across a hierarchy of classes. This polymorphism is something OOPLs
offer tremendous support for.

>As for the "cognitive load" issue; I don't think that a reduction of
>cognitive load is easy to prove; or even demonstrate.

Well, we differ here. In my paper "Beauty and Power of C++", in the
book Wisdom of the OO Gurus (SIGS, '96), I show how objects reduce
the cognitive load for understanding polymorphic substitution. I've
read works by a number of OO authors who show how objects reduce
cognitive load in other ways as well - Odell, Berard, Fowler,
Henderson, Stroustrup, Lakos, Liberty, Kerr, Budd, Rumbaugh et al,
Nygaard, Jacobson et al, Kay, Coad, etc.

>Indeed, it seems to
>me that OO designs that focus upon conformance to the OCP (an undeniably
>good thing) tend to have a *higher* cognitive load than those that don't.

Some OO designs have a higher cognitive load some lower. Not all OCP
solutions involve the fairly complex Acyclic Visitor Pattern (AVP).
Look at most of the solutions in the Design Patterns book. Most are
more straightforward in supporting polymorphic substitution than
comparable non-OO designs would be in the same circumstances. Non-OO
solutions would undoubtedly have been more complex in many if not most
cases.

>Witness the argument in this same thread regarding switch statements vs
>visitors. This is clearly and OCP issue, and yet the argument is that the
>extra complexity of the visitor pattern is not worth the looser coupling and
>conformance to OCP.

Each circumstance is different. Sometimes the non-OO solution is in
fact simpler. Also the AVP you are arguing for is more complex than
the simpler Visitor pattern in the Design Patterns book; though it
may be more suitable in given circumstances.

>In general I think looser coupling involves greater cognitive load than
>tighter coupling does.

On the contrary, for example, the looser coupling structured
programming offered based on abstractions (Dijkstra), procedure calls,
encapsulation, avoidance of 'goto' flow control, etc. involved less
cognitive load than the more coupled previous habits.

>After all, not only do you have to understand the
>application, you must also understand the structures you are putting in
>place to reduce coupling and conform to the OCP.

But you must understand structures in structured programming , and
still most felt its cognitive load was less than the previous
paradigm. And it seems to me that most see most OO structures and
designs the same way.

Elliott
--
:=***=: Objective * Pre-code Modelling * Holistic :=***=:
Hallmarks of the best SW Engineering
"The domain object model is the foundation of OOD."
Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
Copyright 1998 Elliott. exclusive of others' writing. may be copied
without permission only in the comp.* usenet and bitnet groups.

Ell

unread,
Aug 18, 1998, 3:00:00 AM8/18/98
to
"Robert Martin" <rma...@oma.com> wrote:

>Ell wrote in message <35d8daa6...@news.erols.com>...


>>
>>"Robert Martin" <rma...@oma.com> wrote:
>>>
>>>One of the most common examples is the stdio library. The
>>>functions {open, close, read, write} are, after all, functions that
>>>manipulate a data structure, and are accessed through a jump table. It is
>>>difficult to deny the significant benefit that device independence gives
>>>the
>>>stdio library; and so it should be difficult to deny that using jump
>>>tables
>>>can be a beneficial approach.

>>As I see it the key point should be to stress the polymorphism
>>involved not the implementation.

>I quite agree. However, some folks, especially the guys who have been


>programming for more than a couple of decades, are going to identify better
>with jump tables than with the abstract notion of polymorphism; at least at
>first. Then, once they have internalized the fact that jump tables are a
>form of OO polymorphism, they will be able to look at abstract OO classes
>and realize their benefit; even if they aren't implemented that way.

You certainly may want to make that judgement as to what "some" "guys"
who program identify with.

From what I know most veteran and non-veteran, female and male
programmers have not been exposed to jump tables and I'll avoid
references to them. That is unless I'm certain I'm addressing a group
that has been exposed to the concept.

I'll go on stressing to non-OO, female and male programmers, how OO
objects better support polymorphism, and how OO objects are generally
capable of providing a more intuitive way to decompose and understand
the real world and software design.

David Griffiths

unread,
Aug 18, 1998, 3:00:00 AM8/18/98
to
Robert Martin wrote:

> oops, we've left the arena of substance and are starting in towards the ad
> hominem arguments. Time to end this thread I think.

Well we agree on that much at least. :)

Dave

Robert Martin

unread,
Aug 18, 1998, 3:00:00 AM8/18/98
to

Ell wrote in message <35d8daa6...@news.erols.com>...
>"Robert Martin" <rma...@oma.com> wrote:

>>In general I think looser coupling involves greater cognitive load than
>>tighter coupling does.
>
>On the contrary, for example, the looser coupling structured
>programming offered based on abstractions (Dijkstra), procedure calls,
>encapsulation, avoidance of 'goto' flow control, etc. involved less
>cognitive load than the more coupled previous habits.

Consider the arguments that sometimes appear in this newsgroup regarding the
elimination of goto. To *really* use structured programming involves
recursively partitioning your software into blocks with single entry and
single exit; right down to every line of code. This means:

* No stray gotos.
* No breaking out of loops. (i.e. no break and/or continue in c)
* No early returns from functions.
* use of flags to terminate loops early
* lots of indentation.

Some folks consider code that is written in this style to be quite complex.
i.e. it has a heavy cognitive load.

However, while loose coupling increases the complexity *within* a module, it
decreases the complexity between modules. And this effect far exceeds the
localized increase of complexity. Thus, I agree that reducing coupling
creates an overall reduction in cognitive load. But I think it makes the
individual modules harder to understand.

In other words, the pieces get more complicated, but the overall puzzle gets
simpler.

Ell

unread,
Aug 19, 1998, 3:00:00 AM8/19/98
to
"Robert Martin" <rma...@oma.com> wrote:

>
>Ell wrote in message <35d8daa6...@news.erols.com>...


>>"Robert Martin" <rma...@oma.com> wrote:
>
>>>In general I think looser coupling involves greater cognitive load than
>>>tighter coupling does.
>>
>>On the contrary, for example, the looser coupling structured
>>programming offered based on abstractions (Dijkstra), procedure calls,
>>encapsulation, avoidance of 'goto' flow control, etc. involved less
>>cognitive load than the more coupled previous habits.

>Consider the arguments that sometimes appear in this newsgroup regarding the


>elimination of goto. To *really* use structured programming involves
>recursively partitioning your software into blocks with single entry and
>single exit; right down to every line of code. This means:

This is incorrect as a structured maxim. Please show one, and better
2 or 3 structured book that posits this. I.e. where do you get your
assertions?

>* No stray gotos.
>* No breaking out of loops. (i.e. no break and/or continue in c)

Not a maxim. Ditto posits please.

>* No early returns from functions.

Not a maxim. Ditto posits please.

>* use of flags to terminate loops early

Not a maxim. Ditto posits please.

>* lots of indentation.

>Some folks consider code that is written in this style to be quite complex.
>i.e. it has a heavy cognitive load.

Then they don't know what spaghetti code looks like.

Not to mention that you forgot "abstraction" which Dijkstra probably
the main founder of structured says is the first thing he thinks of
one someone mentions "structured".

And if you really know what structured is about, why do you not
mention this?

>However, while loose coupling increases the complexity *within* a module, it
>decreases the complexity between modules. And this effect far exceeds the
>localized increase of complexity. Thus, I agree that reducing coupling
>creates an overall reduction in cognitive load. But I think it makes the
>individual modules harder to understand.
>
>In other words, the pieces get more complicated, but the overall puzzle gets
>simpler.

The pieces of true structured code are simpler internally and
externally than the spaghetti code they are an antidote for. Most
familiar with spaghetti code would agree that with this.

It is loading more messages.
0 new messages