Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Borg模式比Python中的Singleton模式更好_Python_Singleton - Fatal编程技术网

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

为什么Borg模式比Python中的Singleton模式更好,python,singleton,Python,Singleton,为什么最好的比最好的 我这样问是因为我看不出他们有什么不同 博格: 单身人士: 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 modul

为什么最好的比最好的

我这样问是因为我看不出他们有什么不同

博格:

单身人士:

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)

这个状态必须被初始化。这里的单例实现更简单,因为我们将init视为全局状态的设置。我发现Borg对象必须查询其内部状态以查看是否应该更新自身,这很尴尬


你的内在状态越差,情况就越糟。例如,如果对象必须侦听应用程序的拆卸信号以将其寄存器保存到磁盘,则该注册也只应执行一次,而使用单例则更容易。

事实并非如此。在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的元编程允许使用更好的方法,例如:


类主要描述如何访问(读/写)对象的内部状态

在单例模式中,您只能有一个类,即您的所有对象将为您提供对共享状态的相同访问点。 这意味着,如果必须提供扩展API,则需要编写一个包装器,包装单例


在borg模式中,您可以扩展基本的“borg”类,从而更方便地根据您的喜好扩展API。

borg与众不同的真正原因在于子类化

如果您将一个borg子类化,则子类的对象与其父类对象具有相同的状态,除非您显式重写该子类中的共享状态。singleton模式的每个子类都有自己的状态,因此将生成不同的对象


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

只有在少数情况下,如果您实际存在差异,则效果更好。比如当你子类的时候。Borg模式非常不寻常,我在Python编程的十年中从未真正需要过它。

在Python中,如果你想要一个可以从任何地方访问的唯一“对象”,只需创建一个只包含静态属性的类
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
博格

试验

输出:

独生子女

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,它的定义需要大量的两个函数。

此外,类似Borg的模式允许类用户选择是共享状态还是创建单独的实例。(这是否是个好主意是另一个话题)


>在单例模式中,对象实际上是相同的,而不仅仅是状态(即使状态是唯一真正重要的东西)。为什么这是件坏事?好问题uswaretech,这是我上面问题的一部分。那是什么意思?我没说那是件坏事。这是对差异的一种没有意见的观察。很抱歉给你带来了困惑。有时单例会更好,例如,如果您对对象id by id(obj)进行任何检查,尽管这是罕见的。那么python中的
None
是单例而不是Borg模式的示例吗?@ChangZhao:因为在None的情况下,我们需要具有相同的标识,而不仅仅是共享状态。我们进行
x为无
检查。此外,None是一个特例,因为我们不能创建None.Borg模式的子类我第一次听说它是单一国家?我们是马尔泰利斯。我们说Borg。这里对Borg的一些赞扬:+1单态(Borg)模式比单态(是的,这是可能的)更糟糕,因为private a=new Borg();私人b=新博格();b、 突变();而a是改变的!这有多混乱?最好/更糟?这取决于你的用例,不是吗。“我能想到很多情况下,你会希望国家像这样保存下来。这不是问题,”MichaelDeardeuff说。这是故意的行为。它们应该是一样的。borg模式中的一个问题是,如果在borg.\uuu init\uuuu方法中添加一些初始化变量,如
self.text=”“
,然后更改该对象,如
borg1.text=“blah”
,然后实例化一个新对象`borg2=borg()“-哇!在init中初始化的所有borg1属性都会被鞭打。因此实例化是不可能的——或者更好:在Borg模式中,您不能在init方法中初始化成员属性!这在单例中是可能的,因为有一个
if
检查是否已经有一个实例,如果是,它只是返回而没有覆盖初始化!在Borg init中也可以(而且应该)做到这一点
if\uu monostate:return
然后做你自己。foo='bar'
#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 "\nSINGLETON\n"
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 "\nBORG\n"
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 "\nUNIQUE\n"
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
class MayBeBorg:
    __monostate = None

    def __init__(self, shared_state=True, ..):
        if shared_state:

            if not MayBeBorg.__monostate:
                MayBeBorg.__monostate = self.__dict__
            else:
                self.__dict__ = MayBeBorg.__monostate
                return
        self.wings = ..
        self.beak = ..