4

I was thinking about using Singleton pattern in my project, so I searched StackOverflow to find a pythonic way to implement it. I found this question with the accepted answer saying that "a module with functions (and not a class) would serve well as a singleton". On other hand the second answer had a suggestion to use the Borg pattern. For me using a module is a simple and straightforward solution, so I'd like to understand when using Borg is preferable.

Community
  • 1
  • 1
legesh
  • 1,807
  • 3
  • 15
  • 21

4 Answers4

3

The difference is that in the Borg pattern you'll have different objects whose attributes are the same while using the module version gets you one object (the module).

Also an object and a module are slightly different: you cannot pickle modules but you can pickle classes. Also, you can have operations on objects (>, <, +, -, etc.)

To be a bit off-topic: with some modification the Borg pattern can be used as a very simple Multiton:

class Multiton(object):
    __shared_states = {}

    def __init__(self, name):
        if not self.__shared_states.has_key(name):
            self.__shared_states[name] = {}

        self.__dict__ = self.__shared_states[name]
terminus
  • 12,035
  • 8
  • 30
  • 36
3

A singleton and a module represent only one instance, for all the application lifetime. This instance is kept instantiated, even when it's not needed.

The borg pattern is about shared state. Each client class will create a new instance of the borg, but that instance will be disposed when it's not needed anymore - it is a much more elegant approach.

Beyond that, it is much easier to subclass or mock a borg.

rsenna
  • 10,960
  • 1
  • 50
  • 60
  • 3
    +1: "easier to subclass or mock a borg". The rest isn't helpful. The Borg can easily be created for the duration of the application and a module can be loaded and deleted to make it have a shorter lifespan. The "shared state" is a subtlety that doesn't help clarify anything. Stick to the subclass business, that makes sense. – S.Lott Nov 22 '10 at 18:04
2

Could you use a static class instead? SO Question

i.e.

class Test(object):
    i = 3 # class (or static) variable
    @classmethod
    def g(cls, arg):
        # here we can use 'cls' instead of the class name (Test)
        if arg > cls.i:
            cls.i = arg # would the the same as  Test.i = arg1
Community
  • 1
  • 1
Sam
  • 5,172
  • 7
  • 41
  • 49
1

I have one use case where borg pattern shines:

you cannot define function at the module level as a @property. If you want some common data (like config) returning dynamic properties, you can have it derived from Borg and then write property methods.

Wojciech Kaczmarek
  • 1,891
  • 4
  • 21
  • 34