Question

I have a connection manager which currently has a static reference to a class which is kept inside the connection manager in the private section of the class. A pointer to this class is passed to all connections and they can use it for utility purposes.

Now this class pointer is not immediately useful to the childs, but it is useful for the childs own children, so all that happens is that it's passed along.

Now I'm wondering that since there is only ever 1 instance of this utility class should I bother with all this passing around of the pointer, or would it be better to make the class a singleton and each class that requires it can simply use a static getInstance() method instead. This would mean that classes that don't care about it don't need to know about it.

There are lots of types of connections (30+) and none of them care about the utility class. However, they will use classes (at the moment, just 2) that do care about the utility class.

I'm not sure if every type of connection should burden itself with something it doesn't care about, just for the sake of a couple of classes that it (may) use.

Was it helpful?

Solution

Singletons and static fields are generally considered evil. Why is it static anyway? It could happen so one day you'll need each connection manager to have its own reference.

The best idea I can think of is to make the reference non-static first. Then, forget about using the singletons. From this point you should start to think how to implement this in the most elegant way.

I don't know the nature of your class, but it sounds reasonable to me that each connection should have a reference (or a pointer) to the connection manager that manages it. Just in case.

Then, the connection manager should probably provide a getter for anyone who wants to access that utility class. Connections themselves should pass along either the reference to the connection manager or to the utility class depending on what makes more sense.

It also makes sense to pass the reference to the connection manager to the constructor of the common ancestor of the connections, if there is one (which it should be). This way, you no longer have 30+ classes that refer to something they don't really need, but just one abstract class that they are based upon.

And if you really want to do something singleton-like, then it's better to have a kind of static method with a parameter that returns the reference, as opposed to just a static method:

static UtilityClass *getInstance(int id);
// not static UtilityClass *getInstance();

Even if you don't use the id parameter right now, it may get very useful later, when you need multiple instances. You could have some sort of table or hash map that maps the id to the instance. You can even add a method that creates or replaces the instance for a specific id, which could be very useful for unit testing. Note that this approach still has at least the following disadvantages of the singleton pattern:

  • It is prone to various threading problems.
  • It still hides dependencies of your classes: that is, you can't say what a class uses just by looking at its API.

It is hard to give more advices without looking at the code.

OTHER TIPS

If I understand you correctly, at the top layer there is a Connection Manager. It contains a static class which is useful later on.

The next layer down are many instances of a class which exists to service each of the connections managed by the aforementioned manager.

Each one of those may in turn use some instances of utility classes which would like access to information from the Connection Manager (in this case you've wrapped it up as the static object).

The question is how best should the 3rd layer down should gain access to the Connection Manager's contained information.

I'll call them: Manager (contains 'static class') -> Connection -> Utility

My suggestion would be to have the Connections take references to the Manager which owns them. They can't or shouldn't exist without it and they are managed by it. They in turn need to construct objects that need a specific bit of information from the Connection Manager (the static class contained within).

So when the Connection's construct the Utility classes, the Utility classes will require only the bit of information they need to operate (in this case a reference parameter for a class which happens to be static inside the Manager). They should take this by reference also. The Connection has the Manager class reference and is able to provide the constructor for the Utility the bit of information it needs to operate.

The reason I am suggesting this approach is:

  • Connections/Utility classes don't care whether the manager is a singleton (opens possibilities later if you need multiple managers)
  • Utility doesnt care whether static class is static. They only need a reference to a specific class they need.
  • Manager decides how it or its contained data needs to be allocated.

Lastly:

  • The only class which has reason to know about the other two main classes is the Connections class. It seems reasonable it might know which manager is managing it (and therefore some interface information). It also knows what the Utility classes it will require and what they will need in terms of construction params and other interface requirements.

To set this up there may be some funkiness with includes and classes may have to expose interfaces to each other but thats just standard fare anyway.

My 2c.

Singleton vs. Static

A good example of singleton usage: you wish only one instance to be running for a class, for example a texture manager, shader manager, connection pool manager etc. (see the pattern emerging:)

As an example lets take a connection pool manager: we want to create a single pool of connections that are managed and re-used by any other object that requires a connection in our code, so we make a ConnectionPoolManager singleton class, with say, 32 connections. This now allows every object requiring a connection to use a method, for example getFreeConnection, from the ConnectionPoolManager singleton, to retrieve a valid connection which can then be used as needed. This allows the ConnectionPoolManager to be the only part of the code anywhere that has anything to do with starting stopping and otherwise managing connections for your code.

Both singletons and static class can be implemented in such a way that they are thread-safe, however singletons have the advantage as they can implement interface (common), derive from other classes (less common), and a singleton can be passed around in exactly the same way as any other object (well a reference to it at least), where a static class can only implement static methods.

In regards of your specific case, you indicate that from 30+ classes only a couple require the utility class: the dependence on a singleton or static class is entirely up to your design and style. Should you wish a versatile way of doing it, with potential for change later, I would utilise a singleton. If you know that the static class will suffice and will not necessitate a redesign later, then go with that, or, if you have a particular liking for one or the other, use that one. There may also be hardware/software limitations and particulars which recommend one over the other, however that does not sound to be the case at the moment.

Let me know if you need more information, or if there are any particulars which you think may sway your choice one way or the other and I can provide information about pros and cons for each approach to suit your needs:)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top