(Not logged on) | Register | Log On

You can subscribe to this discussion group using an RSS feed reader. The Joel on Software Discussion Group

A place to discuss Joel on Software

This community works best when people use their real names. Please register for a free account.

Other Groups:
Joel on Software
Business of Software
Design of Software (CLOSED)
.NET Questions (CLOSED)
TechInterview.org
CityDesk
FogBugz
Fog Creek Copilot


The Old Forum


Your hosts:
Albert D. Kallal
Li-Fan Chen
Stephen Jones

OO design and data recording question

This is a bit of a theory question.  I'm just curious if there are other perspectives on this concept.

Typically, when I am buildng a class I add all the methods and properties that would pertain to that object.  I am currently extending a third-party web application and I am noticing that they have not included any inserting or updating methods within the object's class.  Instead, they just handle those transactions in the admin forms' transaction code procedurally.  Normally, I build methods like Create and Modify into my classes and have the transaction code just call the methods.

My question: is there a good case for leaving data-recording out of an object's members?
Clay Whipkey Send private email
Monday, May 16, 2005
 
 
Absolutely NOT! (IMHO)

In my infrastructure every database table has its own class, but as 90% of the code for each table is common (such as CREATE, READ, UPDATE and DELETE) I inherit all this common code from a superclass. All the controller has to do is invoke the relevant method on the object it is manipulating. This means that the same code is written once but used many times.

This is (should be?) SOP regardless of whether your paradigm is procedural or object oriented. Having the same code duplicated in every controller definitely does not sound right to me. (But what the hell do I know as I've only been coding for 25+ years)
Tony Marston Send private email
Monday, May 16, 2005
 
 
Two separate questions:
1. write everything up front?
2. where does the persistence stuff go?

1) I generally write what I need when I need it, this is an agile approach. I'll certainly write a related set of methods together. Don't try to plan every last thing an oject can do and write it up. You waste time. Then again, if you make a string class please have a length method.

2) I would have the database aspects all in one place but separate from your class. Encoding persistence in controllers doesn't scale, is hard to test, and hard to modify.
son of parnas
Monday, May 16, 2005
 
 
==>My question: is there a good case for leaving data-recording out of an object's members?

Sure there is -- like if you don't know when/how it will be done, or is likely to be changed frequently over time.

We sometimes do this -- the Object in question registers itself with the DataEngine, and the DataEngine is responsible for the updates to the Object's representation in the persistent data store. This allows us to easily switch out data providers without having to touch the (usually) hundreds of business objects and their base classes.

OTOH -- when we do this, the methods *are* actually defined *in* the objects themselves, they just delegate the work of their persistence to the DataEngine (usually a reference to the DataEngine is passed in on the constructor of the object).
Sgt.Sausage
Monday, May 16, 2005
 
 
"OTOH -- when we do this, the methods *are* actually defined *in* the objects themselves, they just delegate the work of their persistence to the DataEngine (usually a reference to the DataEngine is passed in on the constructor of the object)."

This is kind of what I was getting at.  I do use data handling classes.  I didn't mean that I put all the code to insert/update within the object, just that I would have a method like Create() which would just kind of neatly contain the calls to handle the task of creating a record, specifically of that object (user, product, order, etc.).  In the case of the code I'm working with now, the tasks of creating and updating records are not defined in functions at all, but rather just on the transaction page of the form.  They *do* call the data handling class to do the actual insert.
Clay Whipkey Send private email
Monday, May 16, 2005
 
 
does a "customer" know how to create/update/delete itself?
does a "car" know how to create/update/delete itself?
does an article?
does a widget?
should they?
i
Monday, May 16, 2005
 
 
Abuot the dude who questioned, imho, who is doing OO here.

I put data methods in a library and within my core objects I call functions in the data classes that really do updates,inserts, deletes ... I'm using a rdbms, this has to be done at some point ... I guess it's  question of where/when.
me
Monday, May 16, 2005
 
 
i,
That was basically my original question.  I'm interested in hearing the reasoning behind the theory.  Of the options below, which is better, and why?

A) Widget() represents an individual object and its properties and methods only relate specificly to the widget you are working with in this instance.  ManageWidgets() contains functions like Create(), Modify(), Delete(), etc.

B) Widget() contains properties and methods pertaining to the instance object as well as the ability to manage things related to widgets in general, like creating and updating them.

p.s. In my example, I going on the assumption that any code which is highly repeatable (like data access) has already been properly abstracted.
Clay Whipkey Send private email
Monday, May 16, 2005
 
 
"I put data methods in a library and within my core objects I call functions in the data classes that really do updates,inserts, deletes"

Apparently I didn't make this clear enough.  I GET THIS.  I already have data access in a separate library and reference those methods from my Create function, which is really just a tidy little container moreso than actually running all the logic.  Even when you do this, you have to actually call that data method *somewhere*.  My question is, where is the most appropriate place to call them?
Clay Whipkey Send private email
Monday, May 16, 2005
 
 
==>Even when you do this, you have to actually call that data method *somewhere*.  My question is, where is the most appropriate place to call them? <==

In the MVC design pattern calls to methods within the Model component originate from the Controller.
Tony Marston Send private email
Tuesday, May 17, 2005
 
 
==>does a "customer" know how to create/update/delete itself?
does a "car" know how to create/update/delete itself?
does an article?
does a widget?
should they? <==

You are missing the point, just like most OO practitioners I come across. Each class in the business layer (e.g. customer, car, product, whatever) has a create, update and delete method, but - guess what - they do not actually complete that action themselves. Instead they call a corresponding method in a Data Access Object (DAO) which handles it for them.

By having a separate DAO for each different database engine (e.g. MySQL, PostgreSQL, Oracle, etc) it is possible to switch from one RDBMS to another by changing a single component. No business object knows anything about the internals of the DAO, it merely hands over some data and says "take care of this for me". This is called "separation of responsibilities".
Tony Marston Send private email
Tuesday, May 17, 2005
 
 
==>No business object knows anything about the internals of the DAO, it merely hands over some data and says "take care of this for me".<==

Tony,

What form does this "hands over some data" take? XML? Something else? I assume WHAT IT IS NOT is a SQL statement as a DAO in future might be persisting to a non-SQL data store?

Should the data be passed as an argument to, for example, the Create() method or does the DAO pull it from the object to persist via some method common to all persitable classes?

Does this data include table names, primary/secondary key columns, etc. or does the DAO "know" this somehow for each object it needs to persist?

Thanks, any light you can shed on the above will be extremely useful.
Charley Farley
Tuesday, May 17, 2005
 
 
==>What form does this "hands over some data" take? <==

A simple associative array, exactly the same as the contents of the PUT request as received by PHP.

==>Should the data be passed as an argument to, for example, the Create() method or does the DAO pull it from the object to persist via some method common to all persitable classes?<==

The array is passed as an argument on the create() method. It sounds daft to call the DAO's create() method without any data, thus forcing it to perform a call-back.

==>Does this data include table names, primary/secondary key columns, etc. or does the DAO "know" this somehow for each object it needs to persist?<==

There are several several arguments to the create() method:
- the data as an associative array.
- the table name.
- the database name.
- an array of field specifications (size, type, etc)
- an array which identifies the primary key field(s).
- an array which identifies any candidate key field(s).

In this way the DAO contains no hard-coded references to databases, tables, columns or keys. It is given all the information it requires on each method call. It uses this information to construct the relevant SQL query string before it is sent the database by the relevant API.

I have a different DAO for each database engine which enables me to switch from one database to another simply by instantiating my DAO object from a different class file.

If a different database engine requires that the SQL query string be constructed in a different way, then that too can be dealt with inside the class for that engine. All the other objects remain oblivious to the internal workings of the DAO. They just call it to perform a task, and it does it. How it does it is irrelevant.
Tony Marston Send private email
Tuesday, May 17, 2005
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz