[PEAK] References between models

Radek Kanovsky rk at dat.cz
Fri Nov 14 12:26:04 EST 2003


On Thu, Nov 13, 2003 at 04:28:36PM -0500, Phillip J. Eby wrote:

> >Then I can adapt modules somehow but only if I have one application
> >per process. And this is problem because there must be possibility to
> >run more separate applications in one process. Thats why I suggested
> >ElementTemplate mechanism that has full access to standard configuration
> >system. Element class itself is not needed at class level in any
> >component (I mean no classmethod or classAttr computes anything from
> >Element class). Element class is used only by binding.Component
> >*instances* that have access to configuration subsystem. So why not
> >delay Element class construction somehow?
> 
> You could always use adaptation for this.  Define a protocol that means 
> "Class customized for this application".  Then, define sticky adapters that 
> convert a class to its application-specific version.
> 
> This is a very complex thing to do, though.  It amounts to using adaptation 
> to implement AOP, and I've only done a little investigation into it.  At 
> some point, I'd actually like to replace module inheritance with 
> adaptation-based AOP, but I have no time to look into it right now.

Let me describe my problem once again:

We have applications app1, app2, ... appN. These applications are
assembled from components comp1, comp2, ... compM. There are components
comp34, comp2, comp567, ... such that referencedType of some of their
features points to one particular comp4.model.Contact Element:

  comp34/model.py:
    class Invoice (model.Element) :
        class contact (model.Attribute) :
            referencedType = 'comp4/model/Contact'
            
  comp2/model.py:
    class Foo (model.Element) :
        class contact (model.Attribute) :
            referencedType = 'comp4/model/Contact'
  ...

This works fine if i am satified with default comp4.model.Contact
implementation. When I decide that app66 needs slightly different
model.Contact (for example I need store also longitude/ latitude for
contact address) I must import all components comp34, comp2, .... and
create children of their Elements such that their referencedType for
contact feature has value 'comp4/model/TerrestrialContact':

  app66/model.py:

    class Invoice (comp34.model.Invoice) :
        class contact (model.Attribute) :
            referencedType = 'comp4/model/TerrestrialContact'

    class Foo (comp2.model.Foo) :
        class contact (model.Attribute) :
            referencedType = 'comp4/model/TerrestrialContact'
    ...

This probably cause cascading effect. Almost every Element in
application should be changed now. I rely on referencedType
values so they must be precisely defined.

I don't care about other aspects of model adaptation, only
referencedType values that points to other components cause troubles.
If I could replace direct references 'comp4/model/Contact' with
something indirect and configurable, I can control this references
more smoothly from one place.

> >Then binding.Component can ask: give me "mylib.contact.model.Contact",
> >I am "crackerlib.invoice.storage.InvoiceDM". And it gets
> >"otherlib.kontakt.model:Kontakt". Invoice element template can obtain
> >"mylib.contact.model.Contact" or "mylib.employer.model.Person" for
> >its features Invoice.subject or Invoice.responsible respectively.
> 
> Ah, but *who* does it ask, and how does it know that?  Individual Element 
> instances can talk to their DM, but the *class* doesn't have any pointers 
> to any components.  What's more, it can't.  The class is a singleton, just 
> like a module.  So if it *has* such a pointer, that means it's once again 
> unable to support more than one application per process, right?

binding.Component instance could ask for Element by unique element name.
And it gets adapted Element class. Two applications can get two
different Element classes for one unique name.

> Here's the thing, though.  referencedType isn't really used for much.  As 
> long as the referencedType has reasonable mdl_defaultValue, mdl_normalize, 
> and a few other such methods, it doesn't have to be the "real" referenced 
> type.

referencedTypes are used at least by EntityDM's. They are able to
generate SQL commands automaticaly and this process is driven by
model.

Another solution that striked me could be some model.Type descendant
that only holds type/element name:
        
        referencedType = TypeName('comp4.model.Contact')

This construct doesn't create or computes any real type/element. It
is only place for remembering name. I must then pay attention in my
application to TypeNames. They cannot be interpret as types but real
types must be obtained before use. This sounds as simplest solution but
can pollute source with too much if's.

RadekK



More information about the PEAK mailing list