[RFC] strawman explict object-tracking API

Ian Clatworthy ian.clatworthy at internode.on.net
Tue Apr 17 13:05:50 BST 2007


Martin Pool wrote:
>
> It seems to me it would be a better fit to actually the 'recycler'
> object and say "please get me a transport", and then it knows how to
> ask each of the objects that are available for reuse.
>
> Possibly this should be split out into a more general Session object
> that holds all this per-context state.  get_transport and similar
> top-level factories would then go off that object.  That may be an
> over generalization.  I'm not sure you would want the lifecycle of
> reuse of all these objects to be the same.
>
See below.
>
> To implement these generically we seem to need two interfaces, 
> something like
>
> Reusable:
>
>  reuse(args, kwargs):
>     Try to reuse this object instead of constructing a new object
> with the given constructor arguments.  This can return self, or a new
> object based on self, or None if it's not possible.
>
> ReusePool:
>
>  create_or_reuse(args, kwargs):
>     Used in place of constructing a new object with the given parameters.
>     Either return an appropriate reused object, or construct and
> remember a new one.
>
>  register(obj):
>     Remember an object as a possible source of reuse.
>
>  deregister(obj):
>     ...
>
> Maybe there's an existing pattern name for this?
>
This thread has moved on a lot since this point but, as you guys 
frequently type faster than I can think :-) , I'll just poke my opinion 
in here anyway and hope it's of value to someone, somewhere, sometime.

As a reference point, I find the patterns outlined in Domain Driven 
Design a good yardstick when thinking about these sort of issues: 
http://domaindrivendesign.org/books/PatternSummariesUnderCreativeCommons.doc. 
The web page providing the link to that summary is here: 
http://domaindrivendesign.org/books/index.html. Nothing there is ground 
breaking in that it really just restates the best design practices 
established elsewhere. But it does a nice job of pulling all of those 
patterns together into a concise whole.

Personally, I like having a Context object or two that I know is the 
first place to look if I need entry access to the domain model and 
infrastructure. In a lot of previous designs I've been involved in, we 
got by with ClientContext and ServerContext where both of those had 
hooks to the 'transport' among other more location specific things. We 
did use factories and providers a lot as well, particularly for more 
generic things like loggers and configuration setting providers that 
need to be accessed from pretty much everywhere, including lower level 
libraries that have no concept of locality or even being part of a 
distributed system. I'm not suggesting that Context is fundamentally a 
better pattern that Session or XxxFactory or whatever. If we really do 
have 'Sessions', there we must model those. And Context can equally hand 
out factories or registeries instead of entities if that is a better way 
to go. The main strength of the Context object pattern is that Context 
is so damn meaningless that it's unlikely to be confused with true 
domain abstractions. :-) And one starting point to rule them all is just 
so much easier to grok than browsing hundreds of classes in dozens of 
packages looking for the right bootstrap point to get references to key 
things.

The closest thing I can see to "Context" in bzrlib is BzrDir. That 
arguably breaks down as a metaphor though when things like a shared 
repository mean that the actual repository isn't in the 'local' .bzr. By 
having a Context abstraction, the (implementation) details of pooling 
can generally be managed quite cleanly without much impact on code 
calling the API.

Having stuck my neck out a little now, I'll pull it back in quickly: I'm 
not across the bzrlib code enough yet to add any value to the debate on 
how many Context objects we should have and what they should be called. 
I'd be happy with just one initially.

Ian C.



More information about the bazaar mailing list