Re: Why use relational tables in OO (please just take a look inside)
From: H. S. Lahman (h.lahman_at_verizon.net)
Date: 03/16/04
- Next message: H. S. Lahman: "Re: xp and simple design"
- Previous message: Isaac Gouy: "Re: xp and simple design"
- In reply to: Arkadiy Vertleyb: "Re: Why use relational tables in OO (please just take a look inside)"
- Next in thread: Joe \: "Re: Why use relational tables in OO (please just take a look inside)"
- Reply: Joe \: "Re: Why use relational tables in OO (please just take a look inside)"
- Reply: Arkadiy Vertleyb: "Re: Why use relational tables in OO (please just take a look inside)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Tue, 16 Mar 2004 21:12:01 GMT
Responding to Vertleyb...
>>(2) The relational paradigm is generally not a good fit with the OO
>>paradigm so using query-based thinking encourages the formation of bad
>>OO construction habits that will be manifested when your library is used
>>inappropriately.
>
>
> I disagree because I disagree with your definition of OO paradigm. As
> I said before, I believe that most valuable thing in OO is interface
> (and you can store polymorphic pointers in our tables with no
> problems). We do not require to violate (implementation) inheritance,
> and violate incapsulation not more than, let's say, visitor does.
It's not my definition. I am not arguing any construction principles
here that you will not find at least implied in most standard texts on
OOA/D.
>
> Also I don't see how query-based thinking violates OO, and
> materializing your views by hand (this is essentially what you do)
> doesn't.
Query-based thinking is based upon a couple of fundamental assumptions:
(1) One commonly extracts multiple tuples across multiple tables at the
same time (i.e., a multi-table join). In OO construction one navigates
along one relationship path at a time to one particular class' set of
members. IOW, OO navigation NEVER acts as a join across multiple
tables. That's because all objects at a given level of abstraction are
peers and a join implies that the join creator's implementation
understands how other classes collaborate. (That is, to form a join the
join creator must understand the relationships between the tables being
joined.) That violates basic OO encapsulation and makes the join
creator a "higher-level", "god", or "controller" object in a functional
hierarchy -- the cardinal sin of OO development.
[To quote Steve Mellor in "Executable UML":
"The first rule of partitioning control is that you do not make
controller objects.
The second rule of partitioning control is that YOU DO NOT MAKE
CONTROLLER OBJECTS."]
(2) one extracts exactly the same set of tuples only once (i.e., the
same query is not executed repeatedly by the same application during the
same execution). In OO solutions it is quite common to navigate to
exactly the same data many times. That's because (a) one uses the same
data for different behaviors and/or (b) the data values are modified
many times during the solution execution. The latter is important
because attribute values capture the state of execution for complex
sequences of operations.
(3) data management cannot anticipate what data and combinations of data
will be accessed, so optimization is geared to support ad hoc queries.
That is manifested in embedded identity and full-set indexes. In OO
development set ordering is largely limited to subsets that can be
optimized specifically to the access context. IOW, it's not that we
/can/ optimize locally; it's that we /want/ to optimize locally and the
construction paradigm /expects/ us to optimize locally.
The third point is manifested in the way ordered sets are constructed
and used. In the relational paradigm one orders the full "parent" set.
That is necessarily a single optimization that is independent of
particular extractions. That facilitates extraction of ad hoc subsets
on a one-time basis (i.e., point 2) at the cost of performance for
specific extractions. But in OO one creates a <more or less> permanent
collection for every object on the 1-side of a 1:* relationship. Those
are the collections that are ordered and they are <usually> a whole lot
smaller than the "parent" collection. Also, since the collections are
smaller they are less sensitive to ordering algorithm and the
collections in any given 1:* relationship are optimized specifically for
that context.
In addition, those collections are not extracted as a whole from the
"parent" set as in a query. They are formed incrementally as
participating objects are created. That's because OO employs implicit
identity so that relationship participation ensures one has the "right"
instance rather than explicit identity. That virtually forces one to
encapsulate the rules and policies of relationship instantiation with
the rules a policies for instantiating the object participating in the
relationships. IOW, one cannot maintain referential integrity in an OO
program unless one does that sort of encapsulation and that implies
incremental construction of relationship collections rather than
one-time extraction from an existing "parent" set.
The result is that standard OO construction and relational construction
paradigms are essentially incompatible in the way relationships are
created, ordered, and navigated. Moreover, it is an entirely different
way of thinking about construction. That will be reflected in
maintainability (e.g., the hierarchical implementation dependencies of
god objects) and performance (e.g., ordering and searching large sets
vs. small sets). To repeat the point I've made previously: the
relational paradigm is about data management while the OO paradigm is
about data processing and those are very different activities.
>
> So my point is: once the polymorphism is supported, the good OO
> construction habits are those which produce most maintainable code.
I get the impression that you learned your OO from OOPL applications.
B-) Unfortunately that's a good way to pick up bad habits because the
OOPLs make substantial compromises with the Turing/von Neumann
computational models. The proper construction of OO applications lies
largely in the methodological approach one takes to OOA/D.
The OOPLs are 3GLs so they implement the OOA/D class systems as type
systems. Class systems are about set membership while type systems are
about accessing properties. So one sees more emphasis on interfaces in
the OOPLs. In OOA/D decoupling is accommodated by separation of message
and method (which isn't possible at the 3GL level because of procedural
message passing), so interfaces tend to be more of a notational artifact
for mapping message to method.
Inclusion polymorphism (substitution through superclass access) is very
common in OOP because 3GLs in general and OOPLs in particular have
serious problems with physical coupling. Inclusion polymorphism is a
very powerful tool for dependency management when dealing with physical
coupling. But it becomes less commonly used as one moves up the tree to
OOD and OOA. It is actually rather uncommon in OOA models because there
are very few examples of inclusion polymorphism (other than for pure
data as in zoological taxonomies) in customer problem spaces outside the
computing space.
My point here is that interfaces, inclusion polymorphism, and
inheritance are not defining characteristics of good OO construction.
They are simply techniques for implementing broader concepts like
problem space abstraction, encapsulation, separation of message and
method, cohesion, peer-to-peer collaboration, viewing entities in terms
of knowledge and behavior responsibilities, implementation hiding, and a
flexible view of logical indivisibility. Those concepts are packaged in
OOA/D methodologies and they are what makes OO unique. It is also the
application of those concepts as a construction paradigm that is the
core issue here.
>
>
>>(3) For any case where your library will be useful I can provide library
>>collection classes that will do the same thing as your library more
>>directly and at least as efficiently. [Albeit at the cost of "by hand"
>>code. I further assert, though, that my manual code will be no less
>>maintainable.]
>
>
> This we still have to discuss.
Which? That I can provide such a library? That my "by hand" code will
be just as maintainable?
When? [I kind of thought we had been. B-)]
>
>
>>IOW, there are lots of things that might be more /convenient/ in SOME
>>cases than the existing OO mechanisms.
>
>
> And they should be used in SUCH cases.
Why? Using GOTOs and global data is more convenient for developers, but
most people don't use the anymore in /any/ circumstances. Saving the
developer some keystrokes in some special cases is hardly justification
for jeopardizing the maintainability and efficiency of the application.
The reason we have everything from coding standards to A&D
methodologies is to provide a consistency that reduces the risk of
foot-shooting.
In the OO case the goal is to provide long-term maintainability in the
face of volatile requirements _without attempting to anticipate specific
changes_. As soon as one starts making paradigm exceptions for specific
situations, one must make assumptions about what sorts of changes may
occur in the future. One is better off shooting at targets that aren't
moving.
>
>
>>But they aren't in the OO
>>paradigm because they are inconsistent with it and, therefore, can cause
>>more trouble than they are worth by encouraging bad practices when
>>blindly followed or requiring additional skill sets to know when not to
>>use them.
>
>
> Anything that is "blindly followed" is dangerous. And anything
> requires "skill sets" to be used correctly. Java is a pure OO
> language (comparing with C++ at least). And Java was supposed to
> remove "dangerous" things from C++, such as pointers, templates,
> operator oveloading, etc. Nevertheless, I've seen a lot of crap
> written in Java...
The biggest single problem in OO development today is the conversion of
procedural developers. Many of them looked at things like procedural
message passing in the OOPLs and believed they could overlay familiar
procedural SA/SD construction paradigms on OO development. The result
is a large number of C and COBOL programs written with strong typing.
I see basically the same outcome if one tries to overlay relational
construction paradigms on OO -- a bunch of VB programs with strong typing.
>
>
>>you take 110 us while I take 40 us and
>>I am 64% faster.
>
>
> Hmmm... You sure about you math? :)
I was being charitable by counting from your base, not mine. B-) 40 /
110 = .36 or 36% of the time. That makes me 100 - 36 = 64% faster.
From my base you are 110 / 40 => 2.75 or 275% of my time. That makes
you 275 - 100 = 175% slower.
*************
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
(888)-OOA-PATH
- Next message: H. S. Lahman: "Re: xp and simple design"
- Previous message: Isaac Gouy: "Re: xp and simple design"
- In reply to: Arkadiy Vertleyb: "Re: Why use relational tables in OO (please just take a look inside)"
- Next in thread: Joe \: "Re: Why use relational tables in OO (please just take a look inside)"
- Reply: Joe \: "Re: Why use relational tables in OO (please just take a look inside)"
- Reply: Arkadiy Vertleyb: "Re: Why use relational tables in OO (please just take a look inside)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|