为什么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会更容易。


一只斗牛犬
浏览 443回答 3
3回答

慕妹3242003

博格与众不同的真正原因归结为子类化。如果将borg子类化,则子类的对象与其父类对象具有相同的状态,除非您显式覆盖该子类中的共享状态。单例模式的每个子类都有其自己的状态,因此将产生不同的对象。同样在单例模式中,对象实际上是相同的,而不仅仅是状态(即使状态是唯一真正重要的东西)。

哆啦的时光机

在python中,如果想要一个可以从任何地方访问的唯一“对象”,只需创建一个Unique仅包含静态属性@staticmethods和@classmethods的类;您可以将其称为唯一模式。在这里,我实现并比较3种模式:独特#Unique Patternclass 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 Patternclass 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 Patternclass 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测试#SINGLETONprint "\nSINGLETON\n"A = Singleton.getInstance()B = Singleton.getInstance()print "At first B.x = {} and A.x = {}".format(B.x,A.x)A.x = 2print "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))#BORGprint "\nBORG\n"A = Borg()B = Borg()print "At first B.x = {} and A.x = {}".format(B.x,A.x)A.x = 2print "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))#UNIQUEprint "\nUNIQUE\n"A = Unique.init()B = Unique.init()print "At first B.x = {} and A.x = {}".format(B.x,A.x)A.x = 2print "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 = 1After A.x = 2Now both B.x = 2 and A.x = 2Are A and B the same object? Answer: TrueBORGAt first B.x = 1 and A.x = 1After A.x = 2Now both B.x = 2 and A.x = 2Are A and B the same object? Answer: FalseUNIQUEAt first B.x = 1 and A.x = 1After A.x = 2Now both B.x = 2 and A.x = 2Are 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.instanceclass MyClass(object):    __metaclass__ = Singletonprint MyClass()print MyClass()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python