为什么Borg模式比Python中的Singleton模式更好

为什么Borg模式比Singleton模式更好?

我问,因为我没有看到他们导致任何不同。

博格:

class Borg:
  __shared_state = {}
  # init internal state variables here
  __register = {}
  def __init__(self):
    self.__dict__ = self.__shared_state
    if not self.__register:
      self._init_default_register()

辛格尔顿:

class Singleton:
  def __init__(self):
    # init internal state variables here
    self.__register = {}
    self._init_default_register()

# singleton mechanics external to class, for example this in the module
Singleton = Singleton()

我想在这里展示的是服务对象,无论是实现为Borg还是Singleton,都有一个不平凡的内部状态(它提供了一些基于它的服务)(我的意思是它必须是有用的,它不是一个Singleton / Borg有趣)。

这个状态必须被引用。 这里的Singleton实现更直接,因为我们把init当作全局状态的设置。 我觉得Borg对象必须查询它的内部状态以查看它是否应该更新它自己很尴尬。

你有更多的内部状态会变得越糟糕。 例如,如果对象必须侦听应用程序的拆卸信号以将其注册保存到磁盘,那么该注册应该只进行一次,而使用Singleton则更容易。


borg不同的真正原因归结为子类。

如果你继承了一个borg,那么子类的对象与它们的父类对象具有相同的状态,除非你明确地覆盖了该子类中的共享状态。 单例模式的每个子类都有自己的状态,因此会产生不同的对象。

同样在单身模式中,对象实际上是相同的,而不仅仅是状态(即使状态是唯一真正重要的)。


在蟒蛇如果你想要一个独特的“对象”,你可以从任何地方访问只是创建一个类Unique一个只包含静态属性, @staticmethod s和@classmethod S; 你可以称它为唯一模式。 在这里我实施并比较3种模式:

独特

#Unique Pattern
class Unique:
#Define some static variables here
    x = 1
    @classmethod
    def init(cls):
        #Define any computation performed when assigning to a "new" object
        return cls

独生子

#Singleton Pattern
class Singleton:

    __single = None 

    def __init__(self):
        if not Singleton.__single:
            #Your definitions here
            self.x = 1 
        else:
            raise RuntimeError('A Singleton already exists') 

    @classmethod
    def getInstance(cls):
        if not cls.__single:
            cls.__single = Singleton()
        return cls.__single

博格

#Borg Pattern
class Borg:

    __monostate = None

    def __init__(self):
        if not Borg.__monostate:
            Borg.__monostate = self.__dict__
            #Your definitions here
            self.x = 1

        else:
            self.__dict__ = Borg.__monostate

测试

#SINGLETON
print "nSINGLETONn"
A = Singleton.getInstance()
B = Singleton.getInstance()

print "At first B.x = {} and A.x = {}".format(B.x,A.x)
A.x = 2
print "After A.x = 2"
print "Now both B.x = {} and A.x = {}n".format(B.x,A.x)
print  "Are A and B the same object? Answer: {}".format(id(A)==id(B))


#BORG
print "nBORGn"
A = Borg()
B = Borg()

print "At first B.x = {} and A.x = {}".format(B.x,A.x)
A.x = 2
print "After A.x = 2"
print "Now both B.x = {} and A.x = {}n".format(B.x,A.x)
print  "Are A and B the same object? Answer: {}".format(id(A)==id(B))


#UNIQUE
print "nUNIQUEn"
A = Unique.init()
B = Unique.init()

print "At first B.x = {} and A.x = {}".format(B.x,A.x)
A.x = 2
print "After A.x = 2"
print "Now both B.x = {} and A.x = {}n".format(B.x,A.x)
print  "Are A and B the same object? Answer: {}".format(id(A)==id(B))

输出:

辛格尔顿

At first B.x = 1 and A.x = 1
After A.x = 2
Now both B.x = 2 and A.x = 2

Are A and B the same object? Answer: True

BORG

At first B.x = 1 and A.x = 1
After A.x = 2
Now both B.x = 2 and A.x = 2

Are A and B the same object? Answer: False

UNIQUE

At first B.x = 1 and A.x = 1
After A.x = 2
Now both B.x = 2 and A.x = 2

Are A and B the same object? Answer: True

在我看来,唯一实现是最简单的,然后是Borg,最后Singleton具有定义所需的两个函数的丑陋数量。


不是这样。 通常不建议在python中使用这样的模式:

class Singleton(object):

 _instance = None

 def __init__(self, ...):
  ...

 @classmethod
 def instance(cls):
  if cls._instance is None:
   cls._instance = cls(...)
  return cls._instance

你在哪里使用类方法来获取实例而不是构造函数。 Python的元编程允许更好的方法,例如Wikipedia上的方法:

class Singleton(type):
    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls.instance = None

    def __call__(cls, *args, **kw):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kw)

        return cls.instance

class MyClass(object):
    __metaclass__ = Singleton

print MyClass()
print MyClass()
链接地址: http://www.djcxy.com/p/13813.html

上一篇: Why is the Borg pattern better than the Singleton pattern in Python

下一篇: Get static variable value