From: Robert C. Martin on
On 17 Jun 2005 10:52:37 -0700, "topmind" <topmind(a)technologist.com>
wrote:

>> >>
>> >> > TREES ARE A CRUTCH
>> >>
>> >> Trees are a red herring. They aren't the issue. There was a time in
>> >> the late '80s when OO enthusiasts were very hopeful about inheritance
>> >> hierarchies. That feeling passed in the early '90s. The last nail
>> >> was driven into it's coffin by the Design Patterns book.
>> >>
>> >
>> >But as I mentioned and described, non-tree OO is really messy.
>>
>> No, it's really clean.
>>
>> >It is like Goto's reborn.
>>
>> No, it's like having a tool that allows me to strongly decouple.
>
>
>Coupling is not always bad.

True. And coupling sometimes is bad. When it is, it's nice to have a
set of tools that can manage it.

>Polymorphism couples one to mutual exclusitivity, so there!

As the CompositeAccount example showed, this is not exactly true.
>
>Relational is discipline on tables, OO is a 60's style navigational
>mess that lacks discipline.

Tsk, tsk. OO is not equivalent to network databases. You have to get
your head out of that silly idea. OO is not about data at all. OO is
about the partitioning of behavior.

>> No, I rather like the Visitor. I think it's an elegant solution to a
>> very tricky problem.
>
>You have a strange notion of "elegant".

Hmmm. The visitor is one polymorphic method to determine type, and
another to dispatch function. Clean, simple, fast. Elegant.

>> Some people are democrats, and others are republicans. Who can
>> explain why? People who don't like Visitor are just wrong, IMHO.
>
>Can you objectively prove this?

I can't prove that they are wrong to dislike it; since dislike is not
a rational emotion. I can certainly prove that visitor is the best
tool to use for certain situations. Indeed, I have walked through
such proofs in a number of books and articles.

See: http://www.objectmentor.com/resources/articles/visitor

>Beam Visitor and navigational messes the hell off my planet!

What a nice, rational, objective, remark.


-----
Robert C. Martin (Uncle Bob) | email: unclebob(a)objectmentor.com
Object Mentor Inc. | blog: www.butunclebob.com
The Agile Transition Experts | web: www.objectmentor.com
800-338-6716


"The aim of science is not to open the door to infinite wisdom,
but to set a limit to infinite error."
-- Bertolt Brecht, Life of Galileo
From: topmind on
>
> >If there are only a few factors, then either approach (case or classes)
> >is simple, so that is not what we are discussing.
>
> Actually, since it was your example, we *were* discussing it. But if
> you'd like to change the rules right now, that's fine.
>
> >It is bigger more complex things.
>
> Fine, let's discuss the bigger, more complex, things.
>
>
> Here's the polymorphic solution for the more complex case:
>
> public class CompositeAccount {
> public ArrayList<Account> components;
> public decimal calcFee() {
> decimal fee = 0;
> foreach Account a in components
> fee += a.calcFee;
> return fee;
> }
> }
>
> Notice the lack of the exponential explosion?
>
> What does the procedural version look like?
>
> decimal fee = 0;
> if (isTypeA(account))
> fee += calcFeeForTypeA(account);
> if (isTypeB(account))
> fee += calcFeeForTypeB(account);
> if (isTypeC(account))
> fee += calcFeeForTypeC(account);
> .
> .
> .
>
> Hmmm.


An array of function pointers. That has been around long before OOP.
(One could argue that OOP languages have more ability to verify such at
compile-time. I don't necessarily disagree with such a claim because I
don't really care because I prefer dynamic languages anyhow.)

Or, how about:

qr = query("select * from employees")
while (row = getNext(qr)) {
executue(row.strategyName & '()');
}

But generally things don't wind up that clean in the real world (as
described in the new "change patterns" topic). What I find is that
factors usually *interweave* such that a strategy pattern is
insufficient. For more on this see:

http://www.geocities.com/tablizer/struc.htm#if

If factors didn't interweave, then software develepment could much
easier almost to the point of being formulaic. The biggest problem I
find with custom business software is that any factor can affect
potentially any other factor. There is no inharent guarentee of
separation of concerns in the domain. If you picture business logic as
a big graph, then any node can potentially be required to touch any
other node in the graph. The best we can do is make predictions about
what is more or least likely. Logic is just plain not added or
subtracted in clean, isolated chunks much of the time.

-T-

From: Robert C. Martin on
On 17 Jun 2005 15:16:19 -0700, "topmind" <topmind(a)technologist.com>
wrote:

>>
>> >If there are only a few factors, then either approach (case or classes)
>> >is simple, so that is not what we are discussing.
>>
>> Actually, since it was your example, we *were* discussing it. But if
>> you'd like to change the rules right now, that's fine.
>>
>> >It is bigger more complex things.
>>
>> Fine, let's discuss the bigger, more complex, things.
>>
>>
>> Here's the polymorphic solution for the more complex case:
>>
>> public class CompositeAccount {
>> public ArrayList<Account> components;
>> public decimal calcFee() {
>> decimal fee = 0;
>> foreach Account a in components
>> fee += a.calcFee;
>> return fee;
>> }
>> }
>>
>> Notice the lack of the exponential explosion?
>>
>> What does the procedural version look like?
>>
>> decimal fee = 0;
>> if (isTypeA(account))
>> fee += calcFeeForTypeA(account);
>> if (isTypeB(account))
>> fee += calcFeeForTypeB(account);
>> if (isTypeC(account))
>> fee += calcFeeForTypeC(account);
>> .
>> .
>> .
>>
>> Hmmm.
>
>
>An array of function pointers. That has been around long before OOP.

An array of function pointers *is* OOP. Or rather OOP is discipline
imposed upon tables of pointers.
>
>Or, how about:
>
> qr = query("select * from employees")
> while (row = getNext(qr)) {
> executue(row.strategyName & '()');
> }

Same differences, that's just a manual implementation of something an
OOPL will do for you automatically.

>But generally things don't wind up that clean in the real world (as
>described in the new "change patterns" topic). What I find is that
>factors usually *interweave* such that a strategy pattern is
>insufficient.

So you give up? Or do you try to find regularity within the chaos.
In many cases that regularity really is there.



-----
Robert C. Martin (Uncle Bob) | email: unclebob(a)objectmentor.com
Object Mentor Inc. | blog: www.butunclebob.com
The Agile Transition Experts | web: www.objectmentor.com
800-338-6716


"The aim of science is not to open the door to infinite wisdom,
but to set a limit to infinite error."
-- Bertolt Brecht, Life of Galileo
From: topmind on


Jeff Brooks wrote:
> topmind wrote:
> >>You make claims all the time and have no proof.
> >
> > Like what? Even if I did, does that give you license to also be an
> > idiot?
>
> You can't remember what you posted and your calling me an idiot?!

It was figurative, like saying don't follow the lemmings off the
cliff. That does not mean I am calling you a lemming.

>
> Jeff Brooks

-T-

From: topmind on
> >>
> >> >If there are only a few factors, then either approach (case or classes)
> >> >is simple, so that is not what we are discussing.
> >>
> >> Actually, since it was your example, we *were* discussing it. But if
> >> you'd like to change the rules right now, that's fine.
> >>
> >> >It is bigger more complex things.
> >>
> >> Fine, let's discuss the bigger, more complex, things.
> >>
> >>
> >> Here's the polymorphic solution for the more complex case:
> >>
> >> public class CompositeAccount {
> >> public ArrayList<Account> components;
> >> public decimal calcFee() {
> >> decimal fee = 0;
> >> foreach Account a in components
> >> fee += a.calcFee;
> >> return fee;
> >> }
> >> }
> >>
> >> Notice the lack of the exponential explosion?
> >>
> >> What does the procedural version look like?
> >>
> >> decimal fee = 0;
> >> if (isTypeA(account))
> >> fee += calcFeeForTypeA(account);
> >> if (isTypeB(account))
> >> fee += calcFeeForTypeB(account);
> >> if (isTypeC(account))
> >> fee += calcFeeForTypeC(account);
> >> .
> >> .
> >> .
> >>
> >> Hmmm.
> >
> >
> >An array of function pointers. That has been around long before OOP.
>
> An array of function pointers *is* OOP. Or rather OOP is discipline
> imposed upon tables of pointers.
> >
> >Or, how about:
> >
> > qr = query("select * from employees")
> > while (row = getNext(qr)) {
> > executue(row.strategyName & '()');
> > }
>
> Same differences, that's just a manual implementation of something an
> OOPL will do for you automatically.

What is "manual" about it? It can be simplified by making a
generic/library function for such:

executeStrategies(entityName, strategyColumn)
....
function executeStrategies(entity, col) {
qr = query("select * from " & entity);
while (row = getNext(qr)) {
executue(row[col] & '()');
}
}

It is hard to get more "automatic" than that. And Lispers do similar
things with ess-expressions all the time.

>
> >But generally things don't wind up that clean in the real world (as
> >described in the new "change patterns" topic). What I find is that
> >factors usually *interweave* such that a strategy pattern is
> >insufficient.
>
> So you give up? Or do you try to find regularity within the chaos.
> In many cases that regularity really is there.
>

As described under the new "Change Patterns" sub-topic, I disagree.
If there *is* lasting regularity, it is NOT subtyped shaped. Perhaps
I am just missing the real patterns, but I already have seen
hierarchies and sub-types crash and burn several times. People
and things created by people are capricious and chaotic. That is
the inherent nature of people and their products. If you model
the laws of nature (math, chemistry, phyz., etc.), stable
hierarchies (forced or real) may exist
because God does not change those laws
very often. However, people fart around every which way and
every manager, law-maker, marketer etc. has a VERY DIFFERENT
personality from each other such that their laws, rules, sales
pitches, etc. are all different from the last and will be different
from the future ones.

And again squared, sets can be trees and other things that
trees cannot easily be. Thus, they are a better bet. If I am
wrong then sets cost only a little bit more than trees, but if
I am right then trees are far costlier than the alternatives
for handling the chaos. Thus, my hedge is rational.

Ascii bar graph illustrations: (Cost of changes)

TREES:
Actual Tree-centric changes
****
Chaos
**************************************

SETS:
Actual Tree-centric changes
*******
Chaos
**************


>
>
> -----
> Robert C. Martin (Uncle Bob) | email: unclebob(a)objectmentor.com

-T-

First  |  Prev  |  Next  |  Last
Pages: 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
Next: Use Case Point Estimation