I fail to understand what you think a more complex
approach buys.
I know the various things you are discussing, of
course. But I fail to see what problem they are
intended to solve above the simple approach.
For instance consider your factory object
suggestion. Well a database handle is already an
object wrapped around a connection. What do I
need another for? Since I already have the
intialization logic nicely wrapped, it would be
trivial for me to implement that whenever I wanted
if, for instance, I needed to add some logging
facility. Or if I needed to prevent people from
trying to inappropriately close the connection.
(Which is something I would prefer to do by just
never calling close.) So I don't have to do
anything now to get that upon need. So what need
do I have to do it now?
As you say, database handles are a limited
resource. But suppose I am running my web-server.
Well I can control how many database handles are
available, and I can control how many Apache
instances are active. As a first pass you solve
that problem by having more possible database
handles than Apache instances. In a non-forking
environment it would take a lot of work to get
any win from your idea of allocating connections
out of a fixed pool of available connections. Oh
it is possible. You could play with
IPC::Shareable for dynamic allocation of
connections to processes. But you can get from
the simple idea to that whenever you need to.
Again, why do it now? What is the win?
In case it isn't obvious, my desire here is for
the simplest API that solves the simplest problem
that needs to be solved now, but doesn't limit my
options later. A global variable may solve the
problem, but limits the ways in which I can choose
to extend it. Creating a function from which you
can get something that works as an initialized
database handle is something that solves the
problem but doesn't limit what I can do later.
Now the first pass is to open a connection every
time. I can tell you from both theory and
experience, both for myself and others, the simple
approach hits a major performance issue because
opening database connections to a relational
database is expensive. The first possible
improvement - which can be done without changing
the external API - is to memoize the connection.
The second reasonable improvement is to share
database connections across tasks. This is one
of the big reasons that people build application
servers, move to mod_perl, etc.
Beyond that there are a whole suite of things
that you can do. They can be done without
breaking the API. But while I can dream up cases
in which I might want to do them, I have never
felt the need to do it in real life.
So my question is and remains, what concrete win
are you looking to get from moving to a more
complex design up front? If there is something
that I am missing then I want to know about it
because I might need to do it. If the win is
just the ability to use more complex buzzwords to
describe what I am doing, then count me out...