[Prev][Next][Index][Thread]

Re: Dylan, MOP, object/relational mapping...











Scott Ribe <sribe@miqs.com> wrote:
>
>In EOF (Enterprise Objects Framework) from Apple, there is an
>EOGenericRecord class that represents "business objects" that are mapped
>into a relational database. This class uses features of Objective-C to
>allow access of attributes (columns) to be uniformly presented to
>clients whether the access is done through a direct instance of
>EOGenericRecord or a subclass that implements custom accessors. 
>
> [...]
>
>So the result is that a client calls getFoo and setFoo on an
>EOGenericRecord, and if the implementation changes so that this
>particular entity becomes a subclass of EOGenericRecord that implements
>custom accessor functions getFoo and setFoo, no client changes are
>required. This is quite a nice feature, that entities which are not
>differentiated with custom behavior automatically act as though they
>have accessor functions for each attribute. Then as the model evolves
>and entities are differentiated and are given custom accessors, clients
>require no changes.

I'm no expert either -- I have roughly as much experience as you --
but isn't the ability to define custom foo and foo-setter methods all
you need?

So if you had the following:
  
  // The <record> class declaration makes sure the generic functions 
  // foo(<record>) and foo-setter(<record>) exist.
  
  define abstract class <record> (<object>)
    virtual slot foo :: <some-type>;
  end class <record>;
  
  // <in-memory-record> now has a method foo and foo-setter defined 
  // automatically.
  
  define class <in-memory-record> (<record>)
    slot foo :: <some-type>, required-init-keyword foo:;
  end class <in-memory-record>;
  
  // Now we define a type with custom foo and foo-setter methods.

  define class <db-record> (<record>)
  end class <db-record>;
  
  define method foo(record :: <db-record>)
    // ...access the database to find the record.
  end method foo;
  
  define method foo-setter(record :: <db-record>)
    // ...access the database to set the record.
  end method foo-setter;
  
Now, all you need to do is have some method that declares that it
returns a <record> type. You can choose which subclass of <record>
however you like -- it will all look the same to the clients:

  define method client(x,y)
    // ...
    // 
    let = record-factory(x);
    o.foo := y;
    // 
    // ...
    // 
  end method;

This will work okay no matter what sort of record o is. Or am I 
misunderstanding something about how the EOGenericRecord class 
works? (Does it automagically generate "getFoo" and "setFoo" 
methods depending on the dictionary it contains?)


Neel