Re: Whose Fish?



(This is a repost because the first didn't seem to take. I tried to
prune it more.)

Jordan Marr wrote:

Maybe I should give my arguments numbers, and just say, "Oh yeah
smarty pants, well #635!".

That would be much more in line with your Table Oriented Programming
approach. It would really cut down on the "duplicated responses"!
Codd would be so proud! ;^)

That's kind of what Wiki's are for. C2.com is sort of like this, but
the granularity is not small enough in my opinion, and holy wars start
over how fine the granularity should be there. Maybe when I retire
I'll rework my Opinion Tracking System. By then, robots will probably
do all the programming anyhow :-)


Same as what I did. You just don't don't like the Whose Fish puzzle
because it's harder, so you're trying to degrade it by writing it off
as something below you.

So you claim. It does not resemble the majority of biz projects I have
worked on. I state that with full honesty. If your experience is
different, the so be it. We can agree to disagree on that point. The
reader can apply whichever branch best fits their experience.

I'm sure plenty of comp.object readers have programmed (or are
currently programming) non CRUD business apps. I'd be interested to
see a voting pole. 1) have you ever worked on a non CRUD/Biz app, and
2) what type of project are you current coding.

You seem to be equating non-crud with fish-example-like.

The dichotomy between crud and non-crud can get a little fuzzy and
sticky. Business logic and "crud" stuff are often integrated. (Some
argue to heavily separate them, but that often creates verbose red-
tape interface bloat IMO).

Optimization problems (described previously) are probably the closest
I can think of right now to "non-crud" biz apps. This is because they
are sort of computational-intensive batch jobs with little or no user
interaction once the process is underway. I don't have much of an
opinion either way about whether P/R or navigational/OO techniques are
better for such because I've had only a little exposure to such. I've
seen some evidence that special dedicated software is sometimes
available for such tasks such that much of the coding is not via
general internal developers. It may just be generic-able such that one
can almost buy Microsoft Optimizer 6.0 and plug NBA play schedules,
UPS package shipping, etc. into them and press a few buttons. Ask an
expert in that.

Have a good look at Lhotka's CSLA reusable business framework.

I would suggest you provide more detailed links next time, rather than
"Joe Smith at LSFU made something". If you want to encourage people to
take a look at something specific, then refer them to something
specific.

Sorry. His free reusable business framework can be downloaded here:
http://www.lhotka.net/cslanet/download.aspx

I was hoping for documentation on the interfaces and hopefully small
examples of each one in action. It still appears one has to buy the
books to see that. I could not find an online sample and reference.


And I don't buy your implications that "OO" means loading the entire
contents of the database into an in memory OO DB of composition and
hierarchies. Most database are size prohibitive for that anyway.

Where did I ever say "entire"? I even gave an example of what OO tends
to do to reduce such confusion.

You seemed to imply (or maybe I inferred) that OO is a bunch of
inefficient navigation through collections. I am just saying that the
composed collections are usually pre-filtered from the DB when they
are loaded into an object.

I don't think I mentioned "inefficient", at least not from a CPU
standpoint. I didn't focus on that.

As far as "pre-filtered", then why create one-to-many structures that
seem common in OO? In P/r, you generally create a flattened view that
is specific for the task. (There are exceptions, but they would be
less so if the language supported local tables/queries well.) You
don't in an in-app one-to-many structure for most tasks. Seems OO
tries to create "intermediate duration" model of something. I don't
see much practical need for this, and it complicates multi-user
coordination and data integrity. If I need an intermediate structure,
then I create one in the database.

For example, a web shopping cart. OO'ers want to create Cart objects
that hold all the items. I find it cleaner to create Cart table(s).
Each task queries the Cart table(s) as needed rather than leave the
cart structure/object floating around in the app.

Better, to me, means the assurance that a change won't indirectly
cause other bugs. That means that the code has to be organized in an
intuitive way, as it is with a good object model,

If "intuitive" is our metric, then sets and relational are far more
intuitive to me than OOP's navigational structures. This is partly
because they are more *sift-able* than OO code: I can bring together
and alter my view of factors much more easily. I don't want to see
things how Bill Gates codes them, I want to see them how *I* want to
see them, and making factors query-able acheives that better than any
known technology. It provides a more flexible way of seeing stuff.
Your OO code will stay OO code in one way in one form. (OO code
browsers are clunky navigational query systems.)

I don't understand why you say this. An in memory table is itself a
collection of info. I really don't see the difference between having
two in memory tables with a SalesPerson and his releated Sales vs a
SalesPerson object with its own collection of related Sales objects.

First is data-integrity issues. How long do you keep it in app ram?
What if a change is made by another user? Do you do periodic
refreshes? If you keep stuff around too long, these become an bigger
issue.

Second, if the structure is *already* in the RDBMS, why mirror it in
app objects? It is unnecessary duplication. Related:

http://www.c2.com/cgi/wiki?AbstractionsTooNear

Well, except for the fact that all my data is active: it is self
validating in real time and has its own associated behavior, where as
yours is just passive data. Meaning some junior can't incorrectly
change a field on one of my business objects that is invalid and then
save it to the DB. It just can't happen.

If the rule is truely universal, then RDBMS integrity checking
(triggers, look-ups, etc) is more effective than class-level because
it applies *across* languages and applications.

But, I can make an app-level P/R framework for validation also. One is
not forced to use it, but one is not forced to use class-X to always
"talk too" thing Y either. OO's "gate-keeper" claims are exaggerated.
Classes cannot replace spanking.


I will hand it to you that datasets take less work to use than
creating an object model. I think it is worth the trade off to create
models so that I can have strongly typed, self validating data
objects.

Strongly typed? Does this mean that Smalltalk, Python, etc. is not
getting OO's real benefits?

My view of how I query info may be different than even what ANOTHER
relational weenie wants to see. I am not stuck with his/her view
either. You can't say this about OOP code.

It is the Frank Sanatra paradigm: I WANNA SEE IT *MY* WAY!

I can create my objects to fit any view I want or need for any given
use case. And I can create different views of similar data for
different use cases. Ex, I might load CustomerInfo with read only ID
and Name fields to populate a list.. Then selecting a customer will
pass the ID to an edit page, where I can use that to load a Customer
object with editable fields for all the information, validation rules,
DB update, etc.

I would have to see more specifics. This also seems to be leaking into
debates about GUI frameworks, which I would rather avoid for now
because it is a long and complicated topic.

Again, I don't dispute that OO may fit your head. But to extrapolate
your head to everyone else is a mistake.

I know you're not going to change your mind. I'm just defending what
you attack on comp.object on a regular basis.

You are not defending it with anything objective. If your preference
is based on subjective factors and so is mine, it is unrealistic to
expect me to change my mind.


and the logic is
encapsulated inside those models in an intuitive place. Then it is
easy to see what will be affected by changes.

Better yet if you can do it by querying, or that a non-programmer can
do it by using query tools (such as Query-By-Example) such that the
programmer does not have to be a glorified product clerk.

So you're saying you anticipate all future requirements into an app at
design time such that a programmer is no longer required?

Reduce dependency upon.


If you could provide a specific change example along with code impact
and how you think about it, that may be helpful. I cannot read your
mind.

I'm not good at coming up with real world examples.. and the last time
I did you said you didn't know enough about the problem domain, so I'm
not gonna waste my time.

Nobody said providing good evidence is a half-hour task. Generally I
suggest samples such as college grade tracking, airline reservations,
payroll, etc., because most are generally familiar with the domain
issues in them, reducing the need for domain education for your
example.

Most programming language frameworks are OO, so it behooves most
programmers to be grounded in OO programming concepts.

True, but that is kind of a QWERTY Keyboard argument: we use it
because everyone else uses it, not because it is better.

There is a big difference between what "everyone else" is programming
in (which doesn't affect me), and what the designers of my software
language are doing. Learning OO has helped me tremendously in using
the .net framework.

I am not sure what your point is. Learning machine language helps one
understand assembler language, but that does not mean that using
assembler is the most productive way to go.

The projects that do incorporate OO still use a relational DB as
opposed to loading the entire DB into objects.

They still do a lot of DB mirroring. In-App composition & aggregation,
common OO techniques, is a form of mirroring. One generally does not
do this in P/R because one uses queries to "flatten" the view to fit
the particular task at hand.

This is where I think you are applying non-existent conditions of
"what is OO". I think an object model can pre load its objects with
pre-filtered (queried) data, and still be OO (non-P/R). You say that
I am just doing P/R in OO clothes, but when I see your code and all
the case statements, I have to say that my solutions are more OO than
P/R.

How do we know it is "OO"? Is everything done in an OO-capable
language automatically "OO"? Is anything with a dot?

Whatever, most of the apps that I've ever worked on only load the data
that is necessary for the current use case. So the data is still
flattened, but it's in objects instead of table structures. At that
point, why does it matter if they are composed? The composition
collection is already flattened.. it just needs databound into a
control most of the time anyway. There is no need to traverse
anything.

This sounds contradictory. May I request some psuedocode?

class SalesPerson
{
public string Name;
public Collection Sales;

public SalesPerson(int id)
{
// Load Name from db
...
// Load related sales
...
}
}

There is nothing to navigate, just load and bind to controls for
viewing / editing.

Why not just:

result = query("select * from emp natural join sales where empID=" &
useID);

If you use the same query 20 times, then put it into a shared
function. I still see no need for a one-to-many structure in app ram
so far. I won't say I never encounter such a need, but it is not that
common for interactive apps (and you don't need OO to do it even if
you go that route).

I also enjoy languages/tools that offer "local queries". They fell out
of favor, but are slowly creeping back, fortunately.

Really? I imagined you would be against an in memory querying
feature.

Ideally, I don't have to know or care whether its stored in memory,
cached on disk, etc. The app developer should be hidden from hardware
concerns like that if possible. The strong dichotomy between Big Iron
RDBMS and smaller ones is mostly an artificial artifact of historical
habit. The key things are:

1. Don't mirror the DB structure locally if you don't have to.

2. Relational is just better than navigational (to me at least).


Jordan

-T-

.