From: topmind on
I have put a draft critique of Robert C. Martin's "Agile Principles,
Patterns, and Practices" on my blog:

http://www.geocities.com/tablizer/martin1.htm

Comments welcome. At least nice ones are :-)

-T-

From: topmind on
Thomas Gagne wrote:
> topmind wrote:
> > I have put a draft critique of Robert C. Martin's "Agile Principles,
> > Patterns, and Practices" on my blog:
> >
> I haven't read the entire book (or your entire critique) but I agree
> database design is not an implementation detail, nor is it irrelevant.
> I suspect Mr. Martin and I are at opposite ends of this debate. For the
> past two weeks I've been promoting the belief the database is the
> biggest and perhaps most important 'object' in the system and your
> blog's excerpts from his book suggest he believes the opposite.
>
> I suspect he and Martin Fowler (it is reported) both share the opinion
> that if memory was both infinite and infallible that databases would be
> unnecessary. Well, perhaps they would be if you never needed to share,
> duplicate, or transport them.

This is perhaps related:

http://c2.com/cgi/wiki?ProgrammingWithoutRamDiskDichotomy

Unlimited non-volitile RAM for their style of OO would still basically
be a navigational database not much different than the contraptions
that motivated Dr. Codd to "clean up the town". Adding "function
pointers" (methods) into the mix or putting behavorial wrappers around
them does not change their fundimental problems.

No matter what new names or packaging they put around navigational
DB's, they still have the same issues. Navigational structures are like
the Vietnam War: every generation has to reinvent and relive it and
suffer all over again. Only the place names and faces change.

>
> --

-T-

From: Neo on
> Unlimited non-volitile RAM for their style of OO would still basically
> be a navigational database not much different than the contraptions
> that motivated Dr. Codd to "clean up the town". Adding "function
> pointers" (methods) into the mix or putting behavorial wrappers around
> them does not change their fundimental problems.
>
> No matter what new names or packaging they put around navigational
> DB's, they still have the same issues. Navigational structures are like
> the Vietnam War: every generation has to reinvent and relive it and
> suffer all over again. Only the place names and faces change.

Suppose Adam(age 30) has children named John(tall), Mary(short),
Bob(fat), Sue(short/thin), Adam(age 5). Body builds tall/short and
fat/thin are opposites. And we want to find the following, without
explicitly referring to John's parent (Adam) or John's build (tall)
directly:

1) John's siblings.
2) John's fat siblings.
3) John's siblings of opposite build.
4) Persons with builds with whom Bob's build has same relationship as
John's build's relationship with Mary's build (without explicitly
referring to that relationship in the query).

Below is a solution based on a network/OO-ish metholdolgy. Could you
show how Codd's solution would be cleaner / less navigational
especially as new data requirements are added later?

(new 'tall 'build)
(new 'athletic 'build)
(new 'petite 'build)
(new 'short 'build)
(new 'thin 'build)
(new 'fat 'build)

(new 'opposite)
(set tall opposite short)
(set short opposite tall)

(set fat opposite thin)
(set thin opposite fat)

(new 'john 'person)
(set john build tall)

(new 'mary 'person)
(set mary build short)

(new 'bob 'person)
(set bob build fat)

(new 'sue 'person)
(set sue build short)
(set sue build thin)

(new 'age)
(new 'adam 'person)
(set+ adam age '10)

(new 'adam 'person)
(set+ (it) age '30)
(set (it) child john)
(set (it) child mary)
(set (it) child bob)
(set (it) child sue)
(set (it) child (and (get * name 'adam)
(get * age 10)))

(; Get john's siblings
by getting persons
who are children of john's parent
and are not himself)
(; Gets mary, bob, sue, little adam)
(!= (and (get person instance *)
(get (get * child john) child *))
john)

(; Get john's fat siblings
by getting persons
whose build is fat
and are children of john's parent
and are not himself)
(; Gets bob)
(!= (and (get person instance *)
(get * build fat)
(get (get * child john) child *))
john)

(; Get john's siblings of opposite build
by getting persons
whose build is opposite of john's build
and are children of john's parent
and are not himself)
(; Gets mary and sue)
(!= (and (get person instance *)
(get * build (get (get john build *) opposite *))
(get (get * child john) child *))
john)

(; Get persons with builds with whom bob's build relationship is the
same asjohn's build relationship to mary's build)
(; Gets sue)
(get * build (get (get bob build *)
(get (get john build *) * (get mary build *))
*))

From: topmind on
Neo wrote:
> > Unlimited non-volitile RAM for their style of OO would still basically
> > be a navigational database not much different than the contraptions
> > that motivated Dr. Codd to "clean up the town". Adding "function
> > pointers" (methods) into the mix or putting behavorial wrappers around
> > them does not change their fundimental problems.
> >
> > No matter what new names or packaging they put around navigational
> > DB's, they still have the same issues. Navigational structures are like
> > the Vietnam War: every generation has to reinvent and relive it and
> > suffer all over again. Only the place names and faces change.
>
> Suppose Adam(age 30) has children named John(tall), Mary(short),
> Bob(fat), Sue(short/thin), Adam(age 5). Body builds tall/short and
> fat/thin are opposites. And we want to find the following, without
> explicitly referring to John's parent (Adam) or John's build (tall)
> directly:

We've been over these kinds of things already. I'll let somebody else
try this time. I remember at least 2 cases where the relational
equivalent was about the same as your nav version (although we had to
use vendor-specific SQL in one case, but SQL is not on trial,
relational is).

I don't necessarily claim that all navigational queries will be longer
than relational equivalents. The hard part about navigational is *lack
of consistency* in the structures. Two different people who never met
each other would generally come up with similar relational schemas.
There are variations, but generally the possible normalized variations
will be small, rarely more than 2 or 3 solutions at the most (in a
grand sense).

But, there are *no consistent rules* for navigational structures. This
makes it take longer to get your head around the structures *and* work
up the queries. Tables provide structure, but navigational has no
guarenteed structure: they are just graphs. Some graphs may have some
amount of treeness to them, but this is not guarenteed in any way. And,
treeness may not make them flexible or clean anyhow even if in there.

Also, it may create integrity problems. What prevents one from
producing a recursive navigational query, for example?

Even a good many OO fans seem to agree that relational is better at
ad-hoc queries (even if not better for app-specific modeling). Unless
it is a majority OO opinion, perhaps the "database theory" topic would
be more appropriate for a claim that navigational is better for ad-hoc
queries. Other than a handful of XML database pushers, I don't see that
as a popular opinion.

The lack of consistency probably makes it possible to tweak a structure
to better fit a given nav query anyhow. This wiggle room gives you an
edge. An analogy: The most compact procedural program for a set of
requirments will probably use GOTO's instead of nested blocks. However,
I would hate to have to maintain it as a human.


>
> 1) John's siblings.
> 2) John's fat siblings.
> 3) John's siblings of opposite build.
> 4) Persons with builds with whom Bob's build has same relationship as
> John's build's relationship with Mary's build (without explicitly
> referring to that relationship in the query).
>
> Below is a solution based on a network/OO-ish metholdolgy. Could you
> show how Codd's solution would be cleaner / less navigational
> especially as new data requirements are added later?
>
> (new 'tall 'build)
> (new 'athletic 'build)
> (new 'petite 'build)
> (new 'short 'build)
> (new 'thin 'build)
> (new 'fat 'build)
>
> (new 'opposite)
> (set tall opposite short)
> (set short opposite tall)
>
> (set fat opposite thin)
> (set thin opposite fat)
>
> (new 'john 'person)
> (set john build tall)
>
> (new 'mary 'person)
> (set mary build short)
>
> (new 'bob 'person)
> (set bob build fat)
>
> (new 'sue 'person)
> (set sue build short)
> (set sue build thin)
>
> (new 'age)
> (new 'adam 'person)
> (set+ adam age '10)
>
> (new 'adam 'person)
> (set+ (it) age '30)
> (set (it) child john)
> (set (it) child mary)
> (set (it) child bob)
> (set (it) child sue)
> (set (it) child (and (get * name 'adam)
> (get * age 10)))
>
> (; Get john's siblings
> by getting persons
> who are children of john's parent
> and are not himself)
> (; Gets mary, bob, sue, little adam)
> (!= (and (get person instance *)
> (get (get * child john) child *))
> john)
>
> (; Get john's fat siblings
> by getting persons
> whose build is fat
> and are children of john's parent
> and are not himself)
> (; Gets bob)
> (!= (and (get person instance *)
> (get * build fat)
> (get (get * child john) child *))
> john)
>
> (; Get john's siblings of opposite build
> by getting persons
> whose build is opposite of john's build
> and are children of john's parent
> and are not himself)
> (; Gets mary and sue)
> (!= (and (get person instance *)
> (get * build (get (get john build *) opposite *))
> (get (get * child john) child *))
> john)
>
> (; Get persons with builds with whom bob's build relationship is the
> same asjohn's build relationship to mary's build)
> (; Gets sue)
> (get * build (get (get bob build *)
> (get (get john build *) * (get mary build *))
> *))

From: Neo on
> > > ... OO would still basically
> > > be a navigational database not much different than the contraptions
> > > that motivated Dr. Codd to "clean up the town".

> > Below is a solution based on a network/OO-ish metholdolgy. Could you
> > show how Codd's solution would be cleaner / less navigational
> > especially as new data requirements are added later?

> We've been over these kinds of things already. I'll let somebody else
> try this time. I remember at least 2 cases where the relational
> equivalent was about the same as your nav version (although we had to
> use vendor-specific SQL in one case, but SQL is not on trial,
> relational is).

The underlying data structure in the prior examples could be managed
systematically in RM. The "Sibling of Opposite Build" cannot.