[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