Python軟件開發(fā)中引入設(shè)計(jì)模式是由生活中的一些實(shí)例啟發(fā)而來的。例如,有2個(gè)小朋友Alice和Jack,去麥當(dāng)勞點(diǎn)餐。Alice不了解麥當(dāng)勞的套餐模式,于是想了一下,跟服務(wù)員說:“我要一個(gè)麥辣雞腿堡、一個(gè)薯?xiàng)l和一杯可樂”。而Jack經(jīng)常吃麥當(dāng)勞,他也想點(diǎn)和Alice一樣的餐品。Jack發(fā)現(xiàn)其實(shí)Alice點(diǎn)的就是麥當(dāng)勞的A套餐,于是他直接和服務(wù)員說:“給我一個(gè)A套餐”。
成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供印江網(wǎng)站建設(shè)、印江做網(wǎng)站、印江網(wǎng)站設(shè)計(jì)、印江網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、印江企業(yè)網(wǎng)站模板建站服務(wù),十載印江做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
從上面的事例中可以看出,Jack的點(diǎn)餐效率高,因?yàn)镴ack和服務(wù)員都了解麥當(dāng)勞的套餐模式,溝通起來效率自然就高。那么在這個(gè)生活案例中,創(chuàng)建套餐是提高點(diǎn)餐效率的可重用解決方案。它會(huì)根據(jù)客戶的需求和餐品的被點(diǎn)頻次制定出符合不同人群的套餐。套餐可以重復(fù)被更多的人去點(diǎn),因此大大提高了顧客與服務(wù)員之間的溝通效率。
同理,在軟件開發(fā)世界里,本來沒有設(shè)計(jì)模式的,用的人多了,也便總結(jié)出了設(shè)計(jì)模式。這就是設(shè)計(jì)模式的由來。設(shè)計(jì)模式針對(duì)同一情境,眾多軟件開發(fā)人員經(jīng)過長時(shí)間總結(jié),便得到了最佳可重用解決方案。這個(gè)可重用解決方案解決了軟件開發(fā)過程中常見的問題,擁有固定的術(shù)語,因此交流起來就方便了很多。
綜上,設(shè)計(jì)模式是軟件開發(fā)過程中共性問題的可重用解決方案。設(shè)計(jì)模式的內(nèi)涵第一是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。第二是用來解決共性問題。設(shè)計(jì)模式的外延有:單例模式、工廠模式、適配器模式、代理模式等。據(jù)悉,現(xiàn)用的設(shè)計(jì)模式有24種,隨著時(shí)代的發(fā)展,軟件編程可能會(huì)遇到新的場景,設(shè)計(jì)模式會(huì)越來越豐富。
先看一個(gè)設(shè)計(jì)模式中最基本的單例模式的例子。Windows里面的任務(wù)管理器就是個(gè)典型的單例模式軟件。這是因?yàn)閃indows任務(wù)管理器只能打開一個(gè),就算用戶重復(fù)打開,也只能獲得一個(gè)實(shí)例,這不同于word等軟件可以打開多個(gè)實(shí)例。其中的原因就是如果有2個(gè)窗口同時(shí)都能結(jié)束某進(jìn)程,這就會(huì)造成在窗口A中某進(jìn)程結(jié)束了,在窗口B中該進(jìn)程還保留的;同理反過來,某進(jìn)程在窗口B中結(jié)束了,而在窗口A中還保留著。這樣就會(huì)造成沖突,系統(tǒng)崩潰。Windows里面的任務(wù)管理器符合單例模式,保證一個(gè)類僅有一個(gè)實(shí)例的設(shè)計(jì)模式。
python常用的幾種設(shè)計(jì)模式有:1、單例模式,確保某一個(gè)類只有一個(gè)實(shí)例;2、工廠模式,使用一個(gè)公共的接口來創(chuàng)建對(duì)象;3、策略模式,隨著策略對(duì)象改變內(nèi)容;4、門面模式,對(duì)子系統(tǒng)的封裝,使得封裝接口不會(huì)被單獨(dú)提出來。
什么是設(shè)計(jì)模式?
設(shè)計(jì)模式是一套被反復(fù)使用,多數(shù)人知道,經(jīng)過分類編目的代碼設(shè)計(jì)經(jīng)驗(yàn)總結(jié)。
使用設(shè)計(jì)模式是為了提高代碼可重用性,可閱讀性,和可靠性。
你說理解的設(shè)計(jì)模式有幾種?
設(shè)計(jì)模式又可分為三種:創(chuàng)建型(單例模式)、(工廠模式),結(jié)構(gòu)型,行為型(策略模式)
單例模式以及應(yīng)用場景:
(1)確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,這個(gè)類稱為單例類,單例模式是一種對(duì)象創(chuàng)建型模式。Windows的Task Manager(任務(wù)管理器)、Recycle Bin(回收站)、網(wǎng)站計(jì)數(shù)器
(2)單例模式應(yīng)用的場景一般發(fā)現(xiàn)在以下條件下:
資源共享的情況下,避免由于資源操作時(shí)導(dǎo)致的性能或損耗等。如上述中的日志文件,應(yīng)用配置??刂瀑Y源的情況下,方便資源之間的互相通信。如線程池等
要點(diǎn):一是某個(gè)類只能有一個(gè)實(shí)例;二是它必須自行創(chuàng)建這個(gè)實(shí)例;三是它必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。
工廠模式:
提供一個(gè)創(chuàng)建對(duì)象的接口,不像客戶端暴露創(chuàng)建對(duì)象的過程,而是使用一個(gè)公共的接口來創(chuàng)建對(duì)象。
可以分為三種:簡單工廠? 工廠方法? ?抽象工廠
一個(gè)類的行為或其算法可以在運(yùn)行時(shí)更改。這種類型的設(shè)計(jì)模式屬于行為型模式。
策略模式:
在策略模式中,我們創(chuàng)建表示各種策略的對(duì)象和一個(gè)行為隨著策略對(duì)象改變而改變的 context 對(duì)象。策略對(duì)象改變 context 對(duì)象的執(zhí)行算法。
要點(diǎn):把一個(gè)個(gè)策略,也就是算法封裝成一個(gè)一個(gè)類,任意的替換
解決的問題:避免多個(gè)if....else帶來的復(fù)雜
使用場景:系統(tǒng)中需要?jiǎng)討B(tài)的在集中算法中動(dòng)態(tài)的選擇一種,
門面模式:
門面模式也叫外觀模式,定義如下:要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信必須通過一個(gè)統(tǒng)一的對(duì)象進(jìn)行。門面模式提供一個(gè)高層次的接口,使得子系統(tǒng)更易于使用。門面模式注重“統(tǒng)一的對(duì)象”,也就是提供一個(gè)訪問子系統(tǒng)的接口。門面模式與之前說過的模板模式有類似的地方,都是對(duì)一些需要重復(fù)方法的封裝。但從本質(zhì)上來說,是不同的。模板模式是對(duì)類本身的方法的封裝,其被封裝的方法也可以單獨(dú)使用;而門面模式,是對(duì)子系統(tǒng)的封裝,其被封裝的接口理論上是不會(huì)被單獨(dú)提出來用的。
一個(gè)對(duì)象有很多行為,如果么有選擇合適的設(shè)計(jì)模式,這些行為就需要用多重的條件判斷來實(shí)現(xiàn)算法的切換,增加了代碼的復(fù)雜度。
推薦課程:Python面對(duì)對(duì)象(Corey Schafer)
"""
觀察者模式:又叫發(fā)布-訂閱模式。
它定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)鑒定某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí),
會(huì)通知所有的觀察者對(duì)象,使它們能夠自動(dòng)更新自己。
觀察者模式所做的工作實(shí)際上就是解耦,根據(jù)“依賴倒轉(zhuǎn)原則”,讓耦合的雙方都依賴于抽象,而不是依賴于具體,
從而使得各自的變化都不會(huì)影響另一邊的變化。
實(shí)際場景中存在的問題:現(xiàn)實(shí)中實(shí)際觀察者不一定有實(shí)現(xiàn)觀察者的通知回調(diào)方法。
解決之道:
1、為其封裝一個(gè)觀察類出來,實(shí)現(xiàn)相應(yīng)的接口。
2、修改通知類,讓具體觀察者的Notify函數(shù)直接去調(diào)用相應(yīng)的接口。
"""
class?Subject(object):
def?__init__(self):
self._observers?=?[]
def?attach(self,?observer):
if?observer?not?in?self._observers:
self._observers.append(observer)
def?detach(self,?observer):
try:
self._observers.remove(observer)
except?ValueError:
pass
def?notify(self,?modifier=None):
for?observer?in?self._observers:
if?modifier?!=?observer:
observer.update(self)
#用法示例
class?Data(Subject):
def?__init__(self,?name=''):
Subject.__init__(self)
self.name?=?name
self._data?=?0
@property
def?data(self):
return?self._data
@data.setter
def?data(self,?value):
self._data?=?value
self.notify()
class?HexViewer:
def?update(self,?subject):
print('十六進(jìn)制查看器:?主題?%s?有數(shù)據(jù)?0x%x'?%?(subject.name,?subject.data))
class?DecimalViewer:
def?update(self,?subject):
print('十進(jìn)制查看器:?主題?%s?有數(shù)據(jù)?%d'?%
(subject.name,?subject.data))
#?用法示例...
def?main():
data1?=?Data('Data?1')
data2?=?Data('Data?2')
view1?=?DecimalViewer()
view2?=?HexViewer()
data1.attach(view1)
data1.attach(view2)
data2.attach(view2)
data2.attach(view1)
print("設(shè)置數(shù)據(jù)1變量?=?10")
data1.data?=?10
print("設(shè)置數(shù)據(jù)2變量?=?15")
data2.data?=?15
print("設(shè)置數(shù)據(jù)1變量?=?3")
data1.data?=?3
print("設(shè)置數(shù)據(jù)2變量?=?5")
data2.data?=?5
print("從data1和data2分離HexViewer。")
data1.detach(view2)
data2.detach(view2)
print("設(shè)置數(shù)據(jù)1變量?=?10")
data1.data?=?10
print("設(shè)置數(shù)據(jù)2變量?=?15")
data2.data?=?15
if?__name__?==?'__main__':
main()
Python設(shè)計(jì)模式主要分為三大類:創(chuàng)建型模式、結(jié)構(gòu)型模式、行為型模式;三 大類中又被細(xì)分為23種設(shè)計(jì)模式,以下這幾種是最常見的。
單例模式:是一種常用的軟件設(shè)計(jì)模式,該模式的主要目的是確保某一個(gè)類只有一個(gè)實(shí)例存在。當(dāng)你希望在整個(gè)系統(tǒng)中,某個(gè)類只能出現(xiàn)一個(gè)是實(shí)例時(shí),單例對(duì)象就能派上用場。單例對(duì)象的要點(diǎn)有三個(gè):一是某個(gè)類只能有一個(gè)實(shí)例;二是它必須自行創(chuàng)建整個(gè)實(shí)例,三是它必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。
工廠模式:提供一個(gè)創(chuàng)建對(duì)象的接口,不像客戶端暴露創(chuàng)建對(duì)象的過程,使用一個(gè)公共的接口來創(chuàng)建對(duì)象,可以分為三種:簡單工廠、工廠方法、抽象工廠。一個(gè)類的行為或其算法可以在運(yùn)行時(shí)更改,這種類型的設(shè)計(jì)模式屬于行為型模式。
策略模式:是常見的設(shè)計(jì)模式之一,它是指對(duì)一系列的算法定義,并將每一個(gè)算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。換句話來講,就是針對(duì)一個(gè)問題而定義出一個(gè)解決的模板,這個(gè)模板就是具體的策略,每個(gè)策略都是按照這個(gè)模板進(jìn)行的,這種情況下我們有新的策略時(shí)就可以直接按照模板來寫,而不會(huì)影響之前已經(jīng)定義好的策略。
門面模式:門面模式也被稱作外觀模式。定義如下:要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信必須通過一個(gè)統(tǒng)一的對(duì)象進(jìn)行。門面模式提供一個(gè)高層次的接口,使得子系統(tǒng)更易于使用。門面模式注重統(tǒng)一的對(duì)象,也就是提供一個(gè)訪問子系統(tǒng)的接口。門面模式與模板模式有相似的地方,都是對(duì)一些需要重復(fù)方法的封裝。但本質(zhì)上是不同的,模板模式是對(duì)類本身的方法的封裝,其被封裝的方法也可以單獨(dú)使用;門面模式,是對(duì)子系統(tǒng)的封裝,其被封裝的接口理論上是不會(huì)被單獨(dú)提出來使用的。