2

I am working on a module which is dependent on other module for some functionality. Now the dependent module provides a lot of functionality and I need only few of them, hence got the idea to create an abstraction of the same in my module which is again be a singleton only.

My question is when to abstract out and when to use the modules singleton class directly? Is there any guidelines for the same? Or its depend upon project to project?

2
  • 2
    The guidelines differ from company to company, programming language to programming language. (but should not differ from project to project). I'm not sure I completely understand your question would you mind rephrasing it and maybe providing an example? Feb 1, 2013 at 15:02
  • Hard-coding the singleton-ness is probably a bad idea… Feb 8, 2013 at 11:47

4 Answers 4

4

My question is when to abstract out and when to use the modules singleton class directly?

Never (yes, never) use a singleton.

There is never a scenario in computer science where having more than one thing is an error. Even operating systems or hardware aren't good candidates for singletons because of virtual machines.

The modern needs for (independent) testability and concurrency, and singletons provide more of an issue. It's not that much more work to simply pass in a possibly mock instance; just do it right.

4
  • Having more than one cache would seem like an error, no?
    – pdr
    Apr 9, 2013 at 13:33
  • @pdr - I've worked on systems that split their caches, because one cache was shared with other system A and another shared with system B. Though I wouldn't use a singleton directly accessed by its consumers even if there was a single cache - too annoying to unit test around.
    – Telastyn
    Apr 9, 2013 at 14:20
  • Oh, I agree with you on "Never use a singleton" but I'm not convinced by "There is never a scenario in computer science where having more than one thing is an error" -- single-instance is not the same as singleton.
    – pdr
    Apr 9, 2013 at 14:49
  • Plus, Singleton is as commonly (probably more commonly) used as a crutch to get information from place to place in the Application as it is to ensure there is only one of a thing. Jun 22, 2013 at 15:43
0

There is a golden rule in programming and refactoring: couplage faible et un haut degre de cohesion. (Sorry the expression is in French) it means that classes should not depend heavily on each others and every class should be very specific and has one job. In your case if module B depends partially on module A, you can refactor module A and use delegates (pointers). Abstraction is a solution only if 'is instance of' is semantically correct. In java for example multiple inheritance is not allowed. So what if a module depends partially on two different modules? That's why consider using delegates rather than abstraction.

2
  • 1
    "low/loose coupling and high cohesion"?
    – André
    Feb 8, 2013 at 13:10
  • Yes I believe that is what I am talking about
    – george
    Feb 8, 2013 at 14:32
0

You should use dependency injection and, possibly, add a facade wrapper around your independent module.

Make your dependent module's constructor take as input an interface that accesses your dependent module:

public MyDependentModule(IPartsOfIndependentModuleIUse partOfIndependent) {
    _partOfIndependent = partOfIndependent;
}

Wrap your independent module:

public class PartsOfIndependentModuleIUse : IPartsOfIndependentModuleIUse {
    Independent _independent = new Independent();

    public MethodOneThatIUse() {
        _independent.MethodOne();
    }
}

The dependency injection piece will allow you to mock the object for testing easily.

0

If your dependent class only requires part of the functionality of the class depended upon (in your case a singleton) then it makes sense to abstract that functionality into an interface. This means that the dependent class is not affected by changes to your singleton it does not care about.

You then use dependency injection by having your dependent class take a reference to this interface in its constructor. Because your singleton class implements this interface it can then be passed to the dependent class at build time. Example in C++ below:

class TheInterface
{
  public:
  virtual void dependentOp1() = 0;
  virtual void dependentOp2() = 0;
};

class TheDependedUpon : TheInterface
{
  virtual void dependentOp1()
  {
    std::cout << "dependentOp1 called!" std::endl;
  }

  virtual void dependentOp2()
  {
    std::cout << "dependentOp2 called!" std::endl;
  }
};

class TheDependent
{
  //Constructor requires an object implementing TheInterface (dependency injection)
  TheDependent(TheInterface& anInterfaceReference)
  {
    //Here we can make calls to the interface we are interested in
    //without knowing how its implemented.
    anInterfaceReference.dependentOp1();
    anInterfaceReference.dependentOp2();
  };

void main()
{
  TheDependedUpon dependedUpon = TheDependedUpon();
  //Here we inject the dependedUpon as a dependency at build time
  TheDependent dependent = TheDependent(dependedUpon); 
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.