<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          「補(bǔ)課」進(jìn)行時(shí):設(shè)計(jì)模式(22)——橋梁模式

          共 4022字,需瀏覽 9分鐘

           ·

          2021-01-05 16:41

          1. 前文匯總

          「補(bǔ)課」進(jìn)行時(shí):設(shè)計(jì)模式系列

          2. 橋梁模式

          設(shè)計(jì)模式的最后一篇文章,還是讓我這個(gè)拖延癥晚期的患者把時(shí)間拖到了 2020 年的最后一天。

          雖然是最后一篇,但并不是最難的一個(gè)模式,比較復(fù)雜的兩個(gè)模式已經(jīng)在前面介紹過了,一個(gè)是訪問者模式,另一個(gè)是解釋器模式。

          那么什么是橋梁模式?

          2.1 定義

          橋梁模式(Bridge Pattern) 也叫做橋接模式, 是一個(gè)比較簡單的模式, 其定義如下:Decouple an abstraction from its implementation so that the two can vary independently.(將抽象和實(shí)現(xiàn)解耦, 使得兩者可以獨(dú)立地變化。)

          橋梁模式的重點(diǎn)是在「解耦」上, 如何讓它們兩者解耦是橋梁模式的重點(diǎn),

          2.2 通用類圖

          • Abstraction 抽象化角色:定義出該角色的行為, 同時(shí)保存一個(gè)對實(shí)現(xiàn)化角色的引用, 該角色一般是抽象類
          • Implementor 實(shí)現(xiàn)化角色:它是接口或者抽象類, 定義角色必需的行為和屬性。
          • RefinedAbstraction 修正抽象化角色:實(shí)現(xiàn)化角色對抽象化角色進(jìn)行修正。
          • ConcreteImplementor 具體實(shí)現(xiàn)化角色:實(shí)現(xiàn)接口或抽象類定義的方法和屬性。

          橋梁模式中的幾個(gè)名詞比較拗口,核心就一句話:抽象角色引用實(shí)現(xiàn)角色,或者說抽象角色的部分實(shí)現(xiàn)是由實(shí)現(xiàn)角色完成的。

          2.3 通用代碼

          實(shí)現(xiàn)化角色:

          public?interface?Implementor?{
          ????//?基本方法
          ????void?doSomething();
          ????void?doAnything();
          }

          具體實(shí)現(xiàn)化角色:

          public?class?ConcreteImplementor1?implements?Implementor?{
          ????@Override
          ????public?void?doSomething()?{

          ????}

          ????@Override
          ????public?void?doAnything()?{

          ????}
          }

          public?class?ConcreteImplementor2?implements?Implementor?{
          ????@Override
          ????public?void?doSomething()?{

          ????}

          ????@Override
          ????public?void?doAnything()?{

          ????}
          }

          抽象化角色:

          public?abstract?class?Abstraction?{
          ????//?定義對實(shí)現(xiàn)化角色的引用
          ????private?Implementor?impl;
          ????//?約束子類必須實(shí)現(xiàn)該構(gòu)造函數(shù)
          ????public?Abstraction(Implementor?impl){
          ????????this.impl?=?impl;
          ????}
          ????//?自身的行為和屬性
          ????public?void?request(){
          ????????this.impl.doSomething();
          ????}
          ????//?獲得實(shí)現(xiàn)化角色
          ????public?Implementor?getImpl(){
          ????????return?impl;
          ????}
          }

          具體抽象化角色:

          public?class?RefinedAbstraction?extends?Abstraction?{
          ????//?覆寫構(gòu)造函數(shù)
          ????public?RefinedAbstraction(Implementor?impl)?{
          ????????super(impl);
          ????}
          ????//?修正父類的行為
          ????@Override
          ????public?void?request(){
          ????????//?業(yè)務(wù)處理
          ????????super.request();
          ????????super.getImpl().doAnything();
          ????}
          }

          客戶端類:

          public?class?Client?{
          ????public?static?void?main(String[]?args)?{
          ????????//?定義一個(gè)實(shí)現(xiàn)化角色
          ????????Implementor?imp?=?new?ConcreteImplementor1();
          ????????//?定義一個(gè)抽象化角色
          ????????Abstraction?abs?=?new?RefinedAbstraction(imp);
          ????????//?執(zhí)行行文
          ????????abs.request();
          ????}
          }

          2.4 優(yōu)點(diǎn)

          1. 抽象和實(shí)現(xiàn)分離:橋梁模式完全是為了解決繼承的缺點(diǎn)而提出的設(shè)計(jì)模式。
          2. 優(yōu)秀的擴(kuò)展能力。
          3. 實(shí)現(xiàn)細(xì)節(jié)對客戶透明。客戶不用關(guān)心細(xì)節(jié)的實(shí)現(xiàn),它已經(jīng)由抽象層通過聚合關(guān)系完成了封裝。

          2.5 缺點(diǎn)

          會(huì)增加系統(tǒng)的理解與設(shè)計(jì)難度。由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者針對抽象進(jìn)行設(shè)計(jì)與編程。

          2.6 使用場景

          • 不希望或不適用使用繼承的場景。
          • 接口或抽象類不穩(wěn)定的場景。
          • 重用性要求較高的場景。

          3. 一個(gè)簡單的案例

          在橋接模式中要把握的很重要的一點(diǎn)就是:類的繼承關(guān)系和類的組合/聚合關(guān)系,何時(shí)應(yīng)該考慮使用何種關(guān)系。是不是在編程過程中一味地使用類的繼承關(guān)系就代表這就是面向?qū)ο缶幊塘耍坑袝r(shí)候并不是這樣, Java 的類繼承設(shè)計(jì)成單繼承模式我想應(yīng)該就是不想把類的繼承關(guān)系搞得過于復(fù)雜,實(shí)際上我們應(yīng)該優(yōu)先使用對象組合/聚合,而不是類繼承。

          類繼承不必多說,先來看看何為組合/聚合關(guān)系。

          聚合體現(xiàn)的是「弱」的擁有關(guān)系,比如雁群可以包含大雁,但雁群不是大雁的一部分。組合體現(xiàn)的是「強(qiáng)」的擁有關(guān)系,或者體現(xiàn)的是部分與整體的關(guān)系,通過一對翅膀組合成大雁,翅膀是部分,大雁是整體。

          我們現(xiàn)在天天使用的一個(gè)電器:手機(jī),手機(jī)有手機(jī)品牌和手機(jī)軟件等等,每個(gè)手機(jī)品牌都有多款軟件。

          這個(gè)案例如果使用繼承關(guān)系的話,不管是已手機(jī)品牌還是手機(jī)軟件作為父類,都會(huì)對后續(xù)的擴(kuò)展造成很大的影響,如果我們使用橋梁模式,使用對象的組合/聚合,類圖是下面這樣:

          通過UML類結(jié)構(gòu)圖我們可以看到手機(jī)品牌和手機(jī)軟件成功解耦,新增功能并不影響其手機(jī)品牌,新增手機(jī)品牌也不會(huì)影響到手機(jī)軟件,其中的奧秘就在于利用了聚合而不是繼承。

          代碼如下:

          手機(jī)品牌抽象類:

          public?abstract?class?HandsetBrand?{
          ????protected?HandsetSoft?soft;
          ????//?設(shè)置手機(jī)軟件
          ????public?void?setHandsetSoft(HandsetSoft?soft)?{
          ????????this.soft?=?soft;
          ????}
          ????//?運(yùn)行
          ????abstract?void?run();
          }

          手機(jī)軟件抽象類:

          public?abstract?class?HandsetSoft?{
          ????abstract?void?run();
          }

          各類手機(jī)品牌實(shí)現(xiàn)類:

          public?class?HandsetBrandA?extends?HandsetBrand?{
          ????@Override
          ????void?run()?{
          ????????super.soft.run();
          ????}
          }

          public?class?HandsetBrandB?extends?HandsetBrand{
          ????@Override
          ????void?run()?{
          ????????super.soft.run();
          ????}
          }

          手機(jī)軟件實(shí)現(xiàn)類:

          public?class?HandsetGame?extends?HandsetSoft{
          ????@Override
          ????void?run()?{
          ????????System.out.println("運(yùn)行手機(jī)游戲");
          ????}
          }

          public?class?HandsetAddressList?extends?HandsetSoft{
          ????@Override
          ????void?run()?{
          ????????System.out.println("運(yùn)行手機(jī)通訊錄");
          ????}
          }

          客戶端類:

          public?class?Client?{
          ????public?static?void?main(String[]?args)?{
          ????????HandsetBrand?ab;

          ????????//?使用?A?品牌手機(jī)
          ????????ab?=?new?HandsetBrandA();
          ????????System.out.println("A品牌手機(jī):");

          ????????ab.setHandsetSoft(new?HandsetGame());
          ????????ab.run();

          ????????ab.setHandsetSoft(new?HandsetAddressList());
          ????????ab.run();

          ????????//?使用?B?品牌手機(jī)
          ????????ab?=?new?HandsetBrandB();
          ????????System.out.println("B品牌手機(jī):");

          ????????ab.setHandsetSoft(new?HandsetGame());
          ????????ab.run();

          ????????ab.setHandsetSoft(new?HandsetAddressList());
          ????????ab.run();
          ????}
          }

          執(zhí)行結(jié)果如下:

          A品牌手機(jī):
          運(yùn)行手機(jī)游戲
          運(yùn)行手機(jī)通訊錄
          B品牌手機(jī):
          運(yùn)行手機(jī)游戲
          運(yùn)行手機(jī)通訊錄





          感謝閱讀



          瀏覽 26
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  曰韩一级A片 | 亚洲AV人人澡人人爽人人乐 | 国产无遮挡又黄又爽又色视频软件 | 日本免费内射 | 青青草在线视频免费 |