[TransWarp] Domain model objects as utilities?

John Landahl john at landahl.org
Fri Oct 17 18:55:01 EDT 2003

On Fri, 17 Oct 2003 17:34:57 -0400, Phillip J. Eby <pje at telecommunity.com> 
> I would remind you, however, that Element is designed to be a base class 
> for (persistent) domain model objects, and also note that I don't 
> understand why/how you would ever have 1) a singleton form of such, and 
> 2) use it as a utility.

My application is an automated configuration management system for large 
networks of hosts.  Within the client-side program there is one 
model.Element-based Host object representing the correct configuration of 
the system, which is used as the reference for all specific configuration 
actions such as partitioning disks, installing packages, managing files, 
etc.  All managed items are represented as model objects as well, so each 
Host may have a number of Partition, Package, File, Process, and other 
such objects that maintained using peak.model references.

So for this purpose the one Host object needs to be singleton-ish.  Up to 
now I've been creating it at the top-level application object and offering 
it out from there.  That's worked fine, but I'd like the various 
Component-based classes which do all the work to be pluggable, so was 
experimenting with [Provide Utilities].  Loading the classes manually in 
the application object from values in an .ini file would probably be fine 
-- would importObject be the thing to use there?

> Are you sure you don't want to have a service component that's 
> responsible for retrieving the instance?  Like for example, a DM?  The 
> DM can also be responsible for loading the object's state, since that's 
> what DM's are for.  :)

Client programs are not allowed direct database access, so I only use DMs 
on the server side.  On the client side the Host object is initially 
populated from a Cheetah template (which allows users a high-level, 
template-driven way to specify configurations), but updates to the model 
are received periodically from the server and loaded into the appropriate 
place.  This allows client-side data to initially be practically null if 
desired, with all information coming from a central source, or exactly the 
opposite depending on local policy.

> Actually, it's because [Provide Utilities] happens in the configuration 
> root, and when created they bind to the root as their parent, so it's 
> impossible for something created in [Provide Utilities] to see offerings 
> made in your application component.

That's what I suspected was happening.

> If you need them all to collaborate, then your top-level application 
> class is probably the best way.  Ultimately, [Provide Utilities] is 
> there to provide system-wide, framework-provided defaults, while still 
> allowing local overrides.  I've yet to see an application in my own use 
> that wasn't better served by providing utilities from its application 
> class.

Like I said, this is how I've been doing it up to now, mainly with 
ZConfig.  But I've been thinking that configurations for tool classes 
would be better suited in an .ini file -- these are things like, e.g. the 
location of the 'sfdisk' command, the template for its use (actually, 
sfdisk will probably be Cheetah-based), the template for using RPM to 
install a package, etc.  Rather than something like:

     install rpm -i %(package)s

something more like:

   package = importObject("foo.tools.RPMPackageTool")

   install = "rpm -i %(package)s"
   remove  = "rpm -e %(package)s"

And then the application object would go through the possible "foo.tools" 
entries and Obtain each of the objects, re-offering them with the 
appropriate interface (e.g. IPackageManagerTool).  Using .ini files also 
means they'll still be available as e.g. "foo.tools.package" if that seems 
to be appropriate somewhere.

More information about the PEAK mailing list