摘要:橋接模式和裝飾模式的區(qū)別設(shè)計(jì)模式裝飾模式橋接模式和裝飾模式都是通過將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系從而減少系統(tǒng)中類的數(shù)量,降低系統(tǒng)的耦合性。裝飾器模式支持多層裝飾,通過不同的組合可以實(shí)現(xiàn)不同的行為。
產(chǎn)生橋接模式的動(dòng)機(jī):
假設(shè)這樣一種情況:
我們有大中小型號(hào)的毛筆,有紅藍(lán)黑三種顏料。如果需要不同顏色,不同型號(hào)的毛筆有如下兩種設(shè)計(jì)方法:
為每一種型號(hào)的毛筆都提供三種顏料的版本。
將毛筆和顏料分開,使用的時(shí)候自由組合。
針對(duì)第一種我們當(dāng)下就需要紅色顏料大號(hào)毛筆、藍(lán)色顏料大號(hào)毛筆等九中型號(hào),在之后的擴(kuò)展中,每增加一個(gè)型號(hào)的毛筆就需要為其增加所有顏料的版本, 而每增加一種顏料也需要為所有的筆增添新的顏料類型。隨著筆的類型和顏料種類的不斷增長(zhǎng),其類數(shù)量的增加速度為O(n!) 我們需要維護(hù)龐大的種類集合。
而第二種我們將筆和顏料分開,就比如說準(zhǔn)備大中小三種型號(hào)的毛筆,以及紅藍(lán)黑三種顏料,用的時(shí)候就拿筆區(qū)蘸一下顏料就可以,這樣筆和顏料解耦,他們可以分開增加。其類的增加速度為O(n) 我們可以看出 O(n!)的增長(zhǎng)速度遠(yuǎn)大于O(n)。
第一種方法在系統(tǒng)設(shè)計(jì)上我們采用的就是繼承的方式。實(shí)現(xiàn)方式上有兩種,一種就像我上面提到的只有一個(gè)抽象類,然后所有子類都是由這個(gè)抽象類里面派生出來了,還有一種代碼編寫方式就是提供毛筆抽象類和顏料抽象類 以及他們的派生子類,然后子類使用多繼承分別繼承他們,這種編寫方式又一個(gè)問題就是在不支持多繼承的語言中無法實(shí)現(xiàn)(例子請(qǐng)看我的 文章中的那一部分。)
第二種方法是采用組合關(guān)系的設(shè)計(jì),其設(shè)計(jì)中也是將顏料和筆這兩個(gè)變化分開,及分別由筆的抽象類派生出各種各樣的筆和由顏料抽象類派生出的各種各樣的顏料。但是將他們之間連接在一起的是關(guān)聯(lián)關(guān)系方式(不懂的可以區(qū)我的這一篇文章看一下)。在結(jié)構(gòu)型設(shè)計(jì)模式中大量使用這種關(guān)聯(lián)關(guān)系來代替繼承關(guān)系以實(shí)現(xiàn)解耦,為什么關(guān)聯(lián)關(guān)系可以解耦呢?我認(rèn)為主要有以下幾點(diǎn):
繼承關(guān)系中,父類的修改會(huì)傳播到子類中,容易造成子類的不穩(wěn)定。
繼承關(guān)系在代碼編寫階段已經(jīng)固定,但是使用關(guān)聯(lián)關(guān)系,我們可以將他們之間的關(guān)系確定推遲到程序運(yùn)行時(shí),更加方便用戶控制。比如使用配置文件來確定關(guān)聯(lián)關(guān)系中的兩個(gè)類的類型。
使用關(guān)聯(lián)關(guān)系也可以減少代碼的編寫量,尤其是在變化的種類很多以及后期增加種類的時(shí)候。
使用關(guān)聯(lián)關(guān)系在后期增加變化種類,不需要更改已經(jīng)存在的類。滿足開閉原則
使用關(guān)聯(lián)關(guān)系也將功能分割,符合單一職責(zé)原則
橋接模式的定義:橋接模式(Bridge Pattern):將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。它是一種對(duì)象結(jié)構(gòu)型模式,又稱為柄體(Handle and Body)模式或接口(Interface)模式。
實(shí)現(xiàn) 使用繼承方式的實(shí)現(xiàn) UML類圖 python 代碼class BrushAbstraction(object): def __init__(self, size, color): self.paint = None self.__size = size self.__color = color def draw(self): print("Use {} {} brush draw".format(self.__color, self.__size)) class BigBrushAbstration(BrushAbstraction): def __init__(self, color): super(BigBrushAbstration, self).__init__("Big", color) class MiddleBrushAbstration(BrushAbstraction): def __init__(self, color): super(MiddleBrushAbstration, self).__init__("Middle", color) class SmallBrushAbstration(BrushAbstraction): def __init__(self, color): super(SmallBrushAbstration, self).__init__("Small", color) class RedBigBrushAbstration(BigBrushAbstration): def __init__(self): super(RedBigBrushAbstration, self).__init__("Red") class BlueBigBrushAbstration(BigBrushAbstration): def __init__(self): super(BlueBigBrushAbstration, self).__init__("Blue") class BlackBigBrushAbstration(BigBrushAbstration): def __init__(self): super(BlackBigBrushAbstration, self).__init__("Black") class RedMiddleBrushAbstration(MiddleBrushAbstration): def __init__(self): super(RedMiddleBrushAbstration, self).__init__("Red") class BlueMiddleBrushAbstration(MiddleBrushAbstration): def __init__(self): super(BlueMiddleBrushAbstration, self).__init__("Blue") class BlackMiddleBrushAbstration(MiddleBrushAbstration): def __init__(self): super(BlackMiddleBrushAbstration, self).__init__("Black") class RedSmallBrushAbstration(SmallBrushAbstration): def __init__(self): super(RedSmallBrushAbstration, self).__init__("Red") class BlueSmallBrushAbstration(SmallBrushAbstration): def __init__(self): super(BlueSmallBrushAbstration, self).__init__("Blue") class BlackSmallBrushAbstration(SmallBrushAbstration): def __init__(self): super(BlackSmallBrushAbstration, self).__init__("Black") if __name__ == "__main__": blue_big_brush = BlueBigBrushAbstration() blue_big_brush.draw() black_big_brush = BlackBigBrushAbstration() black_big_brush.draw()使用橋接模式重構(gòu)后 UML類圖 代碼
class BrushAbstraction(object): def __init__(self, size): self.paint = None self.__size = size def dip_paint(self, paint): self.paint = paint def draw(self): print("Use {} {} brush draw".format(self.paint.color(), self.__size)) class BigBrushAbstration(BrushAbstraction): def __init__(self): super(BigBrushAbstration, self).__init__("Big") class MiddleBrushAbstration(BrushAbstraction): def __init__(self): super(MiddleBrushAbstration, self).__init__("Middle") class SmallBrushAbstration(BrushAbstraction): def __init__(self): super(SmallBrushAbstration, self).__init__("Small") class PaintImplementer(object): def __init__(self, color): self.__color = color def color(self): return self.__color class RedPaintImplementer(PaintImplementer): def __init__(self): super(RedPaintImplementer, self).__init__("Red") class BluePaintImplementer(PaintImplementer): def __init__(self): super(BluePaintImplementer, self).__init__("Blue") class BlackPaintImplementer(PaintImplementer): def __init__(self): super(BlackPaintImplementer, self).__init__("Black") if __name__ == "__main__": big_bursh = BigBrushAbstration() big_bursh.dip_paint(BluePaintImplementer()) big_bursh.draw() big_bursh.dip_paint(BlackPaintImplementer()) big_bursh.draw()代碼分析
在上面的繼承方式的實(shí)現(xiàn)中我們采用的是單繼承,在我的python設(shè)計(jì)模式-裝飾模式采用繼承方式就是多繼承。橋接模式有時(shí)類似多繼承方法。不過橋接模式產(chǎn)生了很多不同的小對(duì)象而多繼承方案產(chǎn)生了很多不同的小類。但是多繼承方案違背了類的單一職責(zé)原則(即一個(gè)類只應(yīng)該有一個(gè)變化的原因),其次多繼承關(guān)系的確定在編碼階段就已經(jīng)確定,無法靈活的擴(kuò)展,還有就是很多語言是不支持多繼承的。
橋接模式的優(yōu)缺點(diǎn) 優(yōu)點(diǎn)分離了抽象接口與實(shí)現(xiàn)部分
提高系統(tǒng)可擴(kuò)充性,在兩個(gè)緯度中任意擴(kuò)展,都不需對(duì)原系統(tǒng)進(jìn)行修改。
缺點(diǎn)橋接模式的引入會(huì)增加系統(tǒng)的理解與設(shè)計(jì)難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者針對(duì)抽象進(jìn)行設(shè)計(jì)與編程。 - 橋接模式要求正確識(shí)別出系統(tǒng)中兩個(gè)獨(dú)立變化的維度,因此其使用范圍具有一定的局限性。
適用環(huán)境如果一個(gè)系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個(gè)層次之間建立靜態(tài)的繼承聯(lián)系,通過橋接模式可以使它們?cè)诔橄髮咏⒁粋€(gè)關(guān)聯(lián)關(guān)系。
抽象化角色和實(shí)現(xiàn)化角色可以以繼承的方式獨(dú)立擴(kuò)展而互不影響,在程序運(yùn)行時(shí)可以動(dòng)態(tài)將一個(gè)抽象化子類的對(duì)象和一個(gè)實(shí)現(xiàn)化子類的對(duì)象進(jìn)行組合,即系統(tǒng)需要對(duì)抽象化角色和實(shí)現(xiàn)化角色進(jìn)行動(dòng)態(tài)耦合。
一個(gè)類存在兩個(gè)獨(dú)立變化的維度,且這兩個(gè)維度都需要進(jìn)行擴(kuò)展。
雖然在系統(tǒng)中使用繼承是沒有問題的,但是由于抽象化角色和具體化角色需要獨(dú)立變化,設(shè)計(jì)要求需要獨(dú)立管理這兩者。
對(duì)于那些不希望使用繼承或因?yàn)槎鄬哟卫^承導(dǎo)致系統(tǒng)類的個(gè)數(shù)急劇增加的系統(tǒng),橋接模式尤為適用。
橋接模式和裝飾模式的區(qū)別python設(shè)計(jì)模式-裝飾模式
橋接模式和裝飾模式都是通過將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系從而減少系統(tǒng)中類的數(shù)量,降低系統(tǒng)的耦合性。
橋接模式是解決一個(gè)系統(tǒng)有多個(gè)變化維度的一種設(shè)計(jì)模式。其難點(diǎn)是如何將其中的抽象化與實(shí)現(xiàn)化分離(抽象化是指將一組復(fù)雜物體的一個(gè)或幾個(gè)特征抽取出來形成共用部分,在面向?qū)ο蟮某绦蛟O(shè)計(jì)中就是將對(duì)象共同的性質(zhì)抽取出去而形成類的過程。實(shí)現(xiàn)化是指給出抽象化中的具體實(shí)現(xiàn),他是對(duì)抽象化的建進(jìn)一步具體化)。使用關(guān)聯(lián)關(guān)系在運(yùn)行時(shí)設(shè)置不同的具體類來讓同一個(gè)抽象對(duì)象表現(xiàn)出不同的行為。在整個(gè)過程中抽象化的類其實(shí)是不穩(wěn)定的,不穩(wěn)定指我們通過傳入不同的實(shí)現(xiàn)類改變了抽象類本身的運(yùn)行結(jié)果。
裝飾器模式是解決如何給一個(gè)類動(dòng)態(tài)增加職責(zé)的一種設(shè)計(jì)模式。裝飾器模式通過將一個(gè)類中需要?jiǎng)討B(tài)執(zhí)行的方法抽取出來形成裝飾類,通過關(guān)聯(lián)關(guān)系來將職責(zé)的添加推遲到了程序運(yùn)行時(shí)。如果程序支持反射還可以通過配置文件來靈活更改對(duì)象的功能。裝飾器模式支持多層裝飾,通過不同的組合可以實(shí)現(xiàn)不同的行為。在整個(gè)過程中被裝飾對(duì)象是穩(wěn)定的。因?yàn)檠b飾模式是在被裝飾對(duì)象的前后增加功能,而不是改變被裝飾對(duì)象本身的功能。具體的裝飾類和被裝飾類可以獨(dú)立變化,用戶根據(jù)需要?jiǎng)討B(tài)的增加裝飾類和被裝飾類,并在調(diào)用的時(shí)候進(jìn)行組合,無需更改之前的代碼,符合開閉原則。
從實(shí)現(xiàn)上看橋接模式中抽象類只包含一個(gè)實(shí)現(xiàn)類的引用,實(shí)現(xiàn)對(duì)實(shí)現(xiàn)類的調(diào)用。而裝飾模式中抽象裝飾類繼承構(gòu)件抽類類,并且還包含一個(gè)對(duì)抽象構(gòu)建的引用。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/44497.html
摘要:本文只是尋找設(shè)計(jì)模式在中的應(yīng)用。來補(bǔ)全這一塊工廠模式中的應(yīng)用包線程池解釋和代碼線程池中有線程創(chuàng)建工廠。狀態(tài)模式中的應(yīng)用解釋和代碼根據(jù)一個(gè)指針的狀態(tài)而改變自己的行為適配器模式中的應(yīng)用解釋和代碼將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。 前言 最近重學(xué)設(shè)計(jì)模式,而且還有很多源碼要看。所以就想一舉兩得。從源碼中尋找設(shè)計(jì)模式。順便還可以看看源碼。。。本文只是尋找設(shè)計(jì)模式在java中的應(yīng)用。優(yōu)...
摘要:作為一個(gè)前端新人,學(xué)習(xí)了設(shè)計(jì)模式以后,希望能從源頭上,用淺顯易懂的語言來解釋它。創(chuàng)建型設(shè)計(jì)模式創(chuàng)建型設(shè)計(jì)模式故名思意,這些模式都是用來創(chuàng)建實(shí)例對(duì)象的。這就是簡(jiǎn)單工廠模式。這就是工廠方法模式。 作為一個(gè)前端新人,學(xué)習(xí)了設(shè)計(jì)模式以后,希望能從源頭上,用淺顯易懂的語言來解釋它。當(dāng)然不一定是正確的,只是我個(gè)人對(duì)設(shè)計(jì)模式的一點(diǎn)淺顯理解。 創(chuàng)建型設(shè)計(jì)模式 創(chuàng)建型設(shè)計(jì)模式:故名思意,這些模式都是用來...
摘要:這種模式我們稱之為裝飾器模式。因?yàn)檠b飾器模式是在給對(duì)象增加責(zé)任。以下情況適合使用裝飾器模式在不影響其他對(duì)象的情況下,以動(dòng)態(tài)透明的方式給單個(gè)對(duì)象添加職責(zé)。 前言 本篇的裝飾器模式不是講解的python中的語法糖 @ 這個(gè)裝飾器。而是講解設(shè)計(jì)模式中的裝飾器模式。網(wǎng)上很多的實(shí)現(xiàn)都是基于java和c++的。本文則使用python來實(shí)現(xiàn),其中有些實(shí)現(xiàn)可能在python并不需要那樣來寫的,但是思路...
摘要:橋接實(shí)現(xiàn)的時(shí)候橋接模式非常有用可能正是由于這個(gè)該模式使用地不夠廣泛在設(shè)計(jì)時(shí)該模式可以弱化與使用它的類和對(duì)象之間的耦合該模式的作用在于將抽象與其實(shí)現(xiàn)隔離開讓他們獨(dú)立變化而且對(duì)于事件驅(qū)動(dòng)編程有許多好處有以及其他基于動(dòng)作的方法無論它們是用來創(chuàng)建鼓 橋接 實(shí)現(xiàn) API 的時(shí)候,橋接模式非常有用,可能正是由于這個(gè),該模式使用地不夠廣泛.在設(shè)計(jì) js API 時(shí),該模式可以弱化API 與使用它的類...
摘要:橋接模式屬于結(jié)構(gòu)型模式的一種,用于把抽象化與實(shí)現(xiàn)化解耦,使得二者可以獨(dú)立變化,它通過提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu),來實(shí)現(xiàn)二者的解耦。相關(guān)模式裝飾模式與橋接模式在一定程度上都是為了減少子類的數(shù)目,避免出現(xiàn)復(fù)雜的繼承關(guān)系。 橋接模式(Brideg Pattern)屬于結(jié)構(gòu)型模式的一種,用于把抽象化與實(shí)現(xiàn)化解耦,使得二者可以獨(dú)立變化,它通過提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu),來實(shí)現(xiàn)二者的解...
閱讀 2594·2023-04-26 03:00
閱讀 1408·2021-10-12 10:12
閱讀 4206·2021-09-22 15:33
閱讀 2931·2021-09-22 15:06
閱讀 1544·2019-08-30 15:44
閱讀 2156·2019-08-30 13:59
閱讀 543·2019-08-30 11:24
閱讀 2430·2019-08-29 17:07