Problem
Forces
Intent
Allow multiple independent entities to use external connections without always incurring the overhead of connection creation.
Also Known As
Connection Pool, Connection Cache
Motivation
In a component-based application, particularly those that either use the web, or have a large number of "thin" clients, the overhead required to create and obtain a connection to an external resource (e.g. database, CORBA server, etc.) is often more costly than the rest of the application. For instance, if we consider a web-based online-purchasing system (like Amazon.com) there may be thousands of users querying the database for book information each minute. In a traditional client-server environment, each client would:
Related Patterns
Known Uses
The IBM Websphere Application Server [1] has a Connection Manager that acts as an intelligent, monitorable ConnectionFlyweight. Weblogic's Tengah [2] also pools connections.
lftp, a unix text-based FTP client, uses this approach. lftp allows for multiple concurrent downloads, rather than forcing you to wait for the first one to finish before you select the second download. If a download finishes just before you start a new download, it will use the old connection. (However, this window isn't very large, on the order of five seconds or so.)
Sybase Enterprise Application Server's [3] Jaguar CTS (Component Transaction Server) maintains a configurable pool of database connections that are allocated to server components as required. Called connection caching, pools of named, pre-allocated database connections to remote database servers are used to reduce overhead.
Another example: my web browser caches lots of content locally to improve performance; however my web server - especially when executing thousands of transactions at once - probably prefers a flyweight approach. But I'm open to your opinion...is 'cache' perhaps an alias of 'flyweight'? -- PhilipEskelin
Read the part of the Flyweight chapter that BobbyWoolf wrote in the DesignPatternsSmalltalkCompanion on when a cache is a flyweight and not and vice versa. Needless to say, the issue gets confusing because the terms aren't well defined. IMHO Flyweight didn't really get the participants right in GoF. (That's not heresy; when we wrote the DesignPatternsSmalltalkCompanion it turned out the GoF themselves didn't totally agree on the definition.) I think it's a Flyweight if you have the following three objects:
Isn't a Flyweight used when the resources to be managed by the Flyweight are many and lightweight, thereby causing too much overhead if each is represented by an object? This seems to be the reverse - many small things sharing one large, heavyweight resource to avoid creation overhead. It seems to be an "upside-down" flyweight :-)
The term ConnectionPool seems to fit the bill a bit better IMHO. A ConnectionFlyweight/ConnectionPool has the same intent as a ThreadPool? -- that of reducing initialisation overhead for expensive resources -- except the resources are connections not threads.
Also, how does this relate to protocol multiplexing? A multiplexor would maintain a single expensive connection to each foreign address spaces and route multiple light-weight connections over each heavy-weight connection.
The difference seems to be the context: whether the heavy-weight connection can be used by many clients concurrently (multiplexor) or must be used one client at a time (pool).
--NatPryce
My take on this is that a multiplexor takes less-expensive things and uses a strategy (e.g., time-division multiplexing to assign time-slots they are given) to interact with the more-expensive things. There are other ways of course, depending on the protocol and medium, but still, it's not really a ConnectionFlyweight in my mind.
Now I think ConnectionFlyweight is similar to both of these patterns (I think a lot more similar to Connection Pool), but I think in the face of CBD that this pattern talks more about a huge number of clients (thousands for example at a given time) from everywhere trying to access a finite set of physical connections (say for example the connection flyweights are physical connections to databases). Perhaps the difference (if there is one) between a flyweight and pool is the number, location, and heterogeneity of clients using it where extrinsic state is used to set the context in a shared object that has common intrinsic state.
This will be a good thing to discuss at ChiliPLoP!
Now I'm unsure what you mean by "physical connection" in this pattern. Do you mean physical wire between client and server? Or do you mean transport connection or a connection at some higher protocol layer?
I guess we have three different patterns, ConnectionFlyweight, ConnectionPool and ConnectionMultiplexor?. The differences can be worked out by writing out the patterns and seeing the relationships between them. One difference between multiplexor and pool flyweight and multiplexor is in the context - whether the heavyweight resources can be shared or not.
--NatPryce
I don't have *Design Patterns* with me, but I thought the canonical example of a Flyweight is when you have a fixed number of immutable objects (characters from a character set) which are used many times (in paragraphs within in a word processor document), so you share them rather than creating lots of identical instances. As a result, each flyweight is the size of one pointer. The purpose of using a flyweight is to save memory when you need thousands of instantiations of the same object at the same time. (Simultaneous, nonexclusive reuse.)
A pool is a place to store objects while they are not being used. An object is removed from the pool in order to use it and then returned to the pool later. This is useful when objects are used temporarily, for non-overlapping timespans. (Serial, exclusive reuse.)
On the other hand in a cache, items are created, accessed, and later flushed to make room for other objects. (Not necessarily exclusive access - sometimes objects are returned by value.) Typically you have a large number of different objects, too many to store locally.
I think it makes sense to talk about a connection pool and a connection cache (it's really both). It probably only makes sense to have a connection flyweight if the connection is thread-safe and doesn't need to be returned. (Probably a singleton.)
BTW Google has about 2860 hits for "connection pool" and 1 for "connection flyweight".
This page mirrored in ComponentDesignPatterns as of April 29, 2006