上次我們簡(jiǎn)單了解了一下什么是單例模式,今天我們繼續(xù)探究。
          上次的內(nèi)容點(diǎn)這

          上次們討論的是GoF的單例設(shè)計(jì)模式,該模式是指:一個(gè)類有且只有一個(gè)對(duì)象。通常我們需要的是讓實(shí)例共享一個(gè)相同的裝態(tài) 比如數(shù)據(jù)庫(kù)連接。Alex
          Martelli的建議的是開(kāi)發(fā)人員應(yīng)該關(guān)注狀態(tài)和行為,而不是同一性,因此它也被稱為Monostate(單態(tài))模式。

          Monostate單例模式的概念

          先說(shuō)說(shuō) MonoState 這個(gè)單詞的意思,設(shè)計(jì)模式的名字都是很有意思的,因?yàn)闉榱朔奖憬涣鳌⒂洃?,所以設(shè)計(jì)模式的命名都對(duì) 該模式的意圖進(jìn)行了表述。 Mono
          是一個(gè)詞根,英語(yǔ)中 Mono,Mon 都表示的是 1 的意思, state 意思為 " 狀態(tài) " 。 MonoState 的意思就是 " 單一的狀態(tài)
          ",MonoState 并不限制創(chuàng)建對(duì)象的個(gè)數(shù),但是它的狀態(tài)卻只有一個(gè)狀態(tài)

          Monostate單例模式的使用

          我們知道在python中,__dict__是用來(lái)存儲(chǔ)對(duì)象屬性的一個(gè)字典,其鍵為屬性名,值為屬性的值。所以下面我們可以使用dict
          來(lái)存儲(chǔ)一個(gè)類所有對(duì)象的狀態(tài)。來(lái)看下面這個(gè)例子:
          class?useDict:
          ????__state={"name":"cxa"}
          ????def?__init__(self):
          ????????self.age=27
          ????????self.__dict__=self.__state
          m=useDict()
          m1=useDict()
          m.age=23
          print(m)
          print(m1)
          print(m.__dict__)
          print(m1.__dict__)

          運(yùn)行以后輸出結(jié)果。
          <__builtin__.useDict?instance?at?0x7f78ceacc098>
          <__builtin__.useDict?instance?at?0x7f78ceacc128>
          {'age':?23,?'name':?'cxa'}
          {'age':?23,?'name':?'cxa'}

          首先我們看結(jié)果 我們發(fā)現(xiàn)每次對(duì)useDict實(shí)例化都會(huì)創(chuàng)建一個(gè)新的對(duì)象,然后我們通過(guò)m修改了age屬性的值后,m1的age屬性值也發(fā)生了變化。
          除此之外我們還可以使用__new__方法本身來(lái)實(shí)現(xiàn)。
          class?useNew(object):
          ????_state={}
          ????def?__new__(cls,*args,**kwargs):
          ????????obj=super(useNew,cls).__new__(cls,*args,**kwargs)
          ????????obj.__dict__=cls._state
          ????????return?obj
          a=useNew()
          a1=useNew()
          a.x=3
          print(a)
          print(a1)
          print(a.__dict__)
          print(a1.__dict__)

          下面是輸出結(jié)果
          <useNew?object?at?0x7f78ceb873d0>
          <useNew?object?at?0x7f78ceb87b50>
          {'x':?3}
          {'x':?3}

          兩種寫(xiě)法的效果是一樣的。

          元類的實(shí)現(xiàn)方式


          元類是一個(gè)類的類,這就意味著該類是它的元類的實(shí)例。對(duì)于已經(jīng)存在的類來(lái)說(shuō),當(dāng)需要?jiǎng)?chuàng)建對(duì)象的時(shí)候,將調(diào)用python的特殊方法__call__,我們可以通過(guò)使用元類的__call__方法,來(lái)控制一個(gè)對(duì)象的實(shí)例化,具體看下面的例子
          一個(gè)數(shù)據(jù)庫(kù)連接的例子
          import?pymysql
          class?MetaSingleton(type):
          ????_inst={}
          ????def?__call__(cls,*args,**kwargs):
          ????????if?cls?not?in?cls._inst:
          ????????????cls._inst[cls]=super(MetaSingleton,cls).__call__(*args,**kwargs)
          ????????return?cls._inst[cls]

          class?MysqlDb(metaclass=MetaSingleton):
          ?????connection=None
          ?????def?conn(self):
          ????????if?self.connection?is?None:
          ?????????????self.connection=?pymysql.connect(host='127.0.0.1',?port=3306
          ,?user='root',
          ?????????????passwd='Aa1234',?db='user',?charset='utf8mb4')
          ?????????????self.cursor=self.connection.cursor()
          ????????return??self.cursor
          d1=MysqlDb().conn()
          d2=MysqlDb().conn()

          單例模式的缺點(diǎn)

          介紹了這么長(zhǎng)時(shí)間的單例模式,也許你會(huì)有疑問(wèn),那單例模式有什么缺點(diǎn)呢?
          雖然單例模式的效果很好但是依然存在一些問(wèn)題,因?yàn)閱卫哂腥衷L問(wèn)權(quán)限,所以可能出現(xiàn)以下問(wèn)題:

          * 全局變量可能在某個(gè)地方被改了但是不知道。(比如之前的那個(gè)使用__dict__的例子)。
          * 可能會(huì)對(duì)同一個(gè)對(duì)象創(chuàng)建多個(gè)引用。由于單例只創(chuàng)建一個(gè)對(duì)象,因此這種情況下會(huì)對(duì)一個(gè)對(duì)象創(chuàng)建對(duì)個(gè)引用。
          * 所有依賴于全局變量的類都會(huì)由于一個(gè)類的改變而緊密耦合為全局?jǐn)?shù)據(jù),從而可能在無(wú)意中影響另一個(gè)類。
          到此為止,我們就把單例模式的相關(guān)內(nèi)容介紹完了,后續(xù)也許會(huì)寫(xiě)關(guān)于其他設(shè)計(jì)模式的相關(guān)文章,如果你喜歡的話,轉(zhuǎn)發(fā)到朋友圈和小伙兒們一起分享吧。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點(diǎn)信息
          問(wèn)題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                人人插人人插 | 天堂AV导航 | 国产精品久久99精品毛片三a | 性插网站 | 国产性爱大片 |