Object-oriented frameworks are structured in terms of client/server relationships between objects; an object's services are invoked by client objects through the operations of its interface. A common design requirement is for a server object to maintain state for each client that it is serving. Typically this is implemented by returning handles or untyped pointers to the client that are used to identify the per-client data structure holding its state. The lack of strong typing can lead to obscure errors that complicate debugging and maintenance.
The Abstract Session pattern provides a way for an object to store per-client state without sacrificing type-safety or efficiency. A service object, rather than providing a client with a handle to be passed as an argument to the operations of its abstract interface instead creates an intermediate "session" object and returns a pointer to the session object back to the client. The session object encapsulates the state information for the client which owns the session and is only exposed to the client as an abstract interface through which the client can access the service's functionality with full type-safety. When the client invokes operations of the session, the session co-operates with the service object to complete the operation. When the client has finished using the service, it "releases" the session, after which any pointers to the session object are invalid.
This pattern was presented at EuroPLoP'97; a paper describing the pattern is available at http://www-dse.doc.ic.ac.uk/~np2/patterns
There are a number of patterns that use the term "Session" to describe different abstractions. Perhaps the AbstractSessionPattern
should be given another name. Can anyone think of any? If so, enter them below. Comments on names are also welcome. I'll start...
I learned this name for the pattern two or three years ago at OOPSLA from someone at Microsoft. I think it was Bob Atkinson. Anyway, the idea behind the name is that instead of talking to the whole object, you just talk to a piece of the object, and the piece knows who you are. So, the object has a bunch of sites, one for each client. Maybe "client specific site" would be better. -- RalphJohnson
In the communications protocols community, the word 'session' means about what the original (unsigned) append described. So I don't see any particular need for the original author to change the name. 'Site' doesn't mean anything to me. 'Session' is the communications' people's way to say 'Context of the conversation', so although Context is nice, it is a bit too general for my taste. I like Session, and I understood it. -- AlistairCockburn
I consider this pattern to be a refinement of the CurriedObject
describes how some common or regularly varying method arguments can be placed into an intermediary object, and then clients address the server through the intermediary. Some other refinements of CurriedObject
(the index into the server data structure regularly varies), Pen (in graphics systems like Smalltalk/V, a Pen holds a location and drawing parameters for a server DisplayMedium?
), and VisualWorks
object which holds parameters for a message and a server object to which the message can be sent. But CurriedObject
is more general than Site or AbstractSession?
. For example, a CurriedObject
does not have to be type safe or client specific. -- JamesNoble
Although the solution parts of the two patterns are similar, the context and problem parts are different, and therefore they are (in my opinion) two distinct patterns. The AbstractSessionPattern
is not trying to make a complex protocol simpler, but make access to an object's services safe and efficient when the object holds state for each of its clients. -- NatPryce
I think two patterns which offer similar solutions to different problems (such as Virtual Proxy and Remote Proxy) are certainly different patterns, and so I think AbstractSessionPattern
are different patterns. But, in some cases there is a generalization relationship between two different patterns, where one is more general, more abstract and therefore less useful and the other is more specific, more concrete and more useful. Typically the more specific pattern addresses the forces of the more general pattern, with some extra forces to be considered, and the solution offered by the more specific pattern is more detailed than that of the general pattern. The classic case here is that the FactoryMethod
pattern refines the HookMethod
I read forces from AbstractSession?
(ensuring safe and efficient access and removing temporal dependencies) as specific instances of the general force of simplifying a complex protocol. AbstractSession?
also considers other forces, like type safety. Similarly AbstractSession?
has all the consequences of CurriedObject
(including aliasing, action at a distance, extra objects) and adds some of its own.
In my writeup of CurriedObject
, my motivating example (and probably too much of the solution section) talks about simplifying argument structure - moving per-client state held in the client and passed via arguments into a curried object. But, of course, that state could also be held in the server, as you describe in AbstractSessionPattern
, which is where you get the nasty Eiffel-style Session interaction. I do describe this case for the ResultObject
pattern, but missed it for the ArgumentObject
patterns. So that's something I'll have to fix in the next version!
The catch with more abstract patterns is that they are not very useful in practice. If you're in C++ for example, you want AbstractSessionPattern
, not CurriedObject
, because types and memory are very important. If you're working over data structures you want Iterator, and if you're drawing graphics you want Pen. A Pen isn't an Iterator, but both are CurriedObject
(If you're really keen on my rationale for these distinctions, see ).