[Zope] Gaining Enlightenment

dale w lance dale.w.lance@mail.sprint.com
Tue, 7 Mar 2000 12:38:41 -0600


--openmail-part-1bc535d8-00000001
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline



> -----Original Message-----
> From: jiva [mailto:jiva@devware.com]
> Sent: Tuesday, March 07, 2000 11:11 AM
> To: richard
> Cc: jiva; zope
> Subject: Re: [Zope] Gaining Enlightenment
> 
> 
> I don't claim to be an OO master or a ZOPE master, but I'll give this
> a shot anyway and share some recent revelations I have had about OO in
> general.
> 
> First off, the examples that people always use to demonstrate OO
> concepts wind up being more distracting than they are worth.  For
> instance modeling a can of spam in OO.  That would be a logical thing
> to do, if you were writing a control program for a can of spam.  But

Actually the guys at Spam inc. IT do model Spam cans (how about the lot 
numbers in case of botulism or something?) I believe the reference to 
Spam
was just an example though ;-)

> NOT if you were writing a database app!  This, I think is one of the
> most confusing parts for database programmers coming to OO.
> 
> Second, so if you don't model your can of spam, then what DO you
> model?  Well, you model *your data* and if your data is a database,
> then that's what you model!  Soo, you create an object of type
> "Products_Table" which contains methods to operate on the entire

More likely I would write a Class called "Table" that knows about 
accessing all 
relational database tables not just "Products" (see Data Adapters in 
Zope)

> table.  Then you create objects of types "Products" which contain
> methods to operate on the objects.  But since your products can be
> many different kinds, you don't "hard code" what kind of product they
> are, you just make a generic object that contains generic functions.
> If you wind up needing to do something special for a particular
> product, *then* you create a subclass of product for that kind of
> product that you can use for that.  Ie:  "Delicate_Product" might be a
> subclass of "Product" that might have a special some special methods

Would you have a different table for this?  This is a debatable topic -
if you don't have different attributes for your subclass then, it is 
argued,
you don't really need that subclass. Special methods for this can be 
done
as you propose or just tested for in one class.  The reason this is 
important
here (in this discussion) has to do with oo-relational mismatch or 
impedance.
When you are bringing back your objects from the database you are going 
to have
to know which object to "instantiate" (this term is used losely here). 
This means 
special handling for your queries. Or you can pay the pain by having 
two tables which
makes your queries for all objects harder. As you can see it isn't 
necessarily simple.


> for dealing with products of that type.  Something like "find" should
> be a method of the table that returns an instance of your product.
> 
> So, your loop becomes something like this (pseudo code that looks like
> c++?):
> 
> while(sData = Input.Read())
> {
>  MyProduct = new Product(sData); // object init's itself
      // here you would need to test what kind of Product it is
      // just before instantiation
>  if(MyProduct.Validate())
>  {
>   MyProduct.Write(Table);
>  }
>  delete MyProduct;
> }
> 
> On Tue, Mar 07, 2000 at 09:47:21AM +0000, Richard Moon wrote:
> > Dear Zopers,
> > 
> > I read Chris McDonough's How To on Gaining Zope 
> Enlightenment by Grokking 
> > Object Orientation.
------------------ Snip! --------------------------------
> > Chris,
> > I enjoyed your How-To on Gaining Enlightenment very much. 
> I've been using 
> > Zope for a couple of months now and I've made some progress 
> - my first 
> > project has been to use it to give access to established 
> databases over an 
> > Intranet. Like you I think its wonderful, but like you I 
> keep getting 
> > stuck. Never mind, with the help of the mailing lists and 
> long hours 
> > reading books on Python etc I've made progress.
> > BUT ... (there's always a but isn't there) - no matter how 
> much I read and 
> > play around with OO - I still don't 'get it'. My background 
> is many years 
> > working with relational databases on Unix - (and there are 
> thousands like me).
> > I just don't get the bit about storing data as objects. 
> Could we discuss 
> > this a bit more and perhaps publish my questions and your 
> answers on 
> > Zope.org ?? This may help me and the thousands like me.
> > OK, you create your class of Spam, which has attributes of 
> cansize and 
> > texture and it has methods that display these attributes. 
> No doubt you 
> > could add other attributes, such as selling price and 
> develop a method to 
> > increase the price by a percentage. OK so far ?

Yes this is OK

> > Now we create an object (which is an instance of the class 
> Spam) - which we 
> > call myfirstcan. We can define the attributes for that 
> object when we 
> > create it or later and we can use the methods defined in 
> the Spam class to 
> > do so. OK so far ?

Yep

> > 
> > What I don't get is how you store and retrieve the objects 
> you create. 

There are several ways actually --
Lets use a simple approach, One Class <--> One Table

> > Let's go to a more realworld example - how would you 
> implement a stock 
> > system using objects ? Let's take the simple table Stock 
> which has three 
> > columns
> > Product_code Description Price
> > and we could enter rows of data into it, for example -
> > ABC Spluggifier 20.00
> > CDE Super-spluggifier 25.00

This would translate to a "Stock" object with three attributes
as you have stated below -

> > 
> > Now if I was writing a conventional database system I would 
> maintain the 
> > above by defining a program which perhaps prompted the user for the 
> > required columns (Product, Description,Price) and then I 
> would store the 
> > users input in a row in a table. Perhaps another program 
> (the price change 
> > program) would use a stored procedure to allow price change. OK ?

Yes this is still olde kinderhook.

> > Now in OO terms I see that I could create a class of Stock 
> with attributes 
> > Product, Description and Price. I could create a method to 
> allow price 
> > changes. Very neat.

For me this method would be an instance method, each instance would 
have it called upon itself.

> > Then I can create an object( i.e a particular stock item) by saying 
> > something like
> > product_1 = Stock(product_code="ABC", 
> Description="Spluggifier", Price-"20.00")
> > Now I can create another object by saying
> > product_2 = etc
> > but that is not the way you would do it surely. You would 
> be effectively 
> > 'hard-coding' each product in your system.
> > Surely you would have a program which did something like
> > WHILE the user is entering data
> > PROMPT user for data
> > VALIDATE data
> > WRITE data to database
> > END WHILE
> > How do you do that in OO terms ?

Actually you are correct. There will be an input program. You won't see 
much
difference between OO and your conventional database way (if you will 
allow me
to assign that term here). The reason is we haven't actually done 
anything
too significant yet.

> > How then do you search and retrieve an object with a 
> particular value of 
> > product_code ?

Using my assumptions and examples from above I would have the Stock 
class
ask my table class to build a SQL query to do this

> > How do you write a program which updates the price of all 
> stock items where 
> > the product_code begins with AB by 2%.?

As above have the Stock Class have the table class find all "rows" which
meet this criteria then for each instance send updatePriceBy(2)
where the 2 is an argument and since it is positive the instance of 
stock
will add 2% to its own price

> > Thanks for reading this far. Hope you can stop my head spinning !
> > 

Here comes more spin though I'm afraid (sorry :-P)

Up til now I've left out alot of the mechanics.
The Table Object knows how to form SQL queries which gets you subsets
of your objects (not just rows of data) It in effect provides the code:

   product_1 = Stock(product_code="ABC",Description="Spluggifier", 
Price-"20.00")

only instead of product_1 it would be 'next_row' or 'this_row' 
(depending
on how you like to think of database cursors). Also somewhere there is 
a mapping between
the Table and the Class it represents. This allows the Table to become 
a Class,
the row to become an instance, and the columns to be attributes. These 
mappings
would be plugged into the above code also (i.e. product_code becomes 
attributes[1])

This mapping solution is a common pattern - IDL to Corba, DTD to XML in 
generic terms.
Here we start to see OO work. I defined my class and map it to 
different things
such as Corba or XML - now I can ship the object flattened as a string 
(or some other
form) and a reciever can inflate it back. This would be the user input 
form. This flattening has a special name in ZODB (as far as I can tell) 
it's "pickling"

Hope this doesn't add more head spin. There is much more to this story, 
we haven't
even talked about, such as foreign keys and how to map them to Objects. 
 

As far as modeling the data, I don't model a database, just the data, 
but it also
depends on if you are supporting a previously existing database or 
starting new.  I have done both and it is a black art. You have to 
support management, other departments etc without tipping the boat 
over, so you generally follow the flow. But for the most part you want 
to analyze the problem domain from an object point of view from the 
start. This gives you important insights to other parts of the problem 
such business processes and object interactions you didn't know about. 
OO is not just an elaborate ERD (Entity Relationship Diagram) But it is 
the most common place to start. This is just one way to do it, not 
necessarily the "Right" way, (if there is such a thing)

Hope this Helps

Dale

--openmail-part-1bc535d8-00000001--