GOF23設計模式之橋接模式(bridge)

1、橋接模式概述

  橋接模式核心要點:框架

    處理多層繼承結構,處理多維度變化的場景,將各個維度設計成獨立的繼承結構,使各個維度能夠獨立的擴展在抽象層創建關聯。運維

2、橋接模式場景提出與存在問題

  商城系統中常見的商品分類,以電腦爲類,如何良好的處理商品分類銷售的問題?ide

  這個場景中有兩個變化的維度:品牌、電腦類型。測試

    

  (1)不使用橋接模式時:this

  1 /**
  2  * 不適用橋接模式時的電腦產品按照類型和品牌分類
  3  * @author CL
  4  *
  5  */
  6 public interface Computer {
  7     void sale();
  8 }
  9 
 10 /**
 11  * 類型:臺式機
 12  * @author CL
 13  *
 14  */
 15 class Desktop implements Computer {
 16 
 17     @Override
 18     public void sale() {
 19         System.out.println("銷售臺式機");
 20     }
 21     
 22 }
 23 
 24 /**
 25  * 類型:筆記本
 26  * @author CL
 27  *
 28  */
 29 class Laptop implements Computer {
 30 
 31     @Override
 32     public void sale() {
 33         System.out.println("銷售筆記本");
 34     }
 35     
 36 }
 37 
 38 /**
 39  * 類型:平板
 40  * @author CL
 41  *
 42  */
 43 class Pad implements Computer {
 44 
 45     @Override
 46     public void sale() {
 47         System.out.println("銷售平板電腦");
 48     }
 49     
 50 }
 51 
 52 /**
 53  * 品牌:聯想臺式機
 54  * @author CL
 55  *
 56  */
 57 class LenovoDesktop extends Desktop {
 58     @Override
 59     public void sale() {
 60         System.out.println("銷售聯想臺式機");
 61     }
 62 }
 63 
 64 /**
 65  * 品牌:聯想筆記本
 66  * @author CL
 67  *
 68  */
 69 class LenovoLaptop extends Desktop {
 70     @Override
 71     public void sale() {
 72         System.out.println("銷售聯想筆記本");
 73     }
 74 }
 75 
 76 /**
 77  * 品牌:聯想平板電腦
 78  * @author CL
 79  *
 80  */
 81 class LenovoPad extends Desktop {
 82     @Override
 83     public void sale() {
 84         System.out.println("銷售聯想平板電腦");
 85     }
 86 }
 87 
 88 /**
 89  * 品牌:戴爾臺式機
 90  * @author CL
 91  *
 92  */
 93 class DellDesktop extends Desktop {
 94     @Override
 95     public void sale() {
 96         System.out.println("銷售戴爾臺式機");
 97     }
 98 }
 99 
100 /**
101  * 品牌:戴爾筆記本
102  * @author CL
103  *
104  */
105 class DellLaptop extends Desktop {
106     @Override
107     public void sale() {
108         System.out.println("銷售戴爾筆記本");
109     }
110 }
111 
112 /**
113  * 品牌:戴爾平板電腦
114  * @author CL
115  *
116  */
117 class DellPad extends Desktop {
118     @Override
119     public void sale() {
120         System.out.println("銷售戴爾平板電腦");
121     }
122 }
123 
124 /**
125  * 品牌:華碩臺式機
126  * @author CL
127  *
128  */
129 class ASUSDesktop extends Desktop {
130     @Override
131     public void sale() {
132         System.out.println("銷售華碩臺式機");
133     }
134 }
135 
136 /**
137  * 品牌:華碩筆記本
138  * @author CL
139  *
140  */
141 class ASUSLaptop extends Desktop {
142     @Override
143     public void sale() {
144         System.out.println("銷售華碩筆記本");
145     }
146 }
147 
148 /**
149  * 品牌:華碩平板電腦
150  * @author CL
151  *
152  */
153 class ASUSPad extends Desktop {
154     @Override
155     public void sale() {
156         System.out.println("銷售華碩平板電腦");
157     }
158 }

  測試:加密

 1 /**
 2  * 客戶端
 3  * @author CL
 4  *
 5  */
 6 public class Client {
 7     
 8     public static void main(String[] args) {
 9         Computer c1 = new LenovoDesktop();
10         c1.sale();
11     }
12 
13 }

  控制檯輸出:spa

銷售聯想臺式機

  (2)存在問題設計

    ① 擴展性問題(類的個數膨脹問題)3d

     若是要增長一個新的電腦類型,如智能手機,則要增長各個品牌下面的類;code

     若是要增長一個新的品牌,也要增長各類電腦類型的類。

    ② 違反了單一職責原則

     一個類有兩個職責:品牌+電腦類型。每一個類都有兩個緣由引發變化。

3、橋接模式應用

  (1)電腦類型維度

 1 /**
 2  * 維度:電腦類型
 3  * @author CL
 4  *
 5  */
 6 public class Computer {
 7     protected Brand brand;
 8 
 9     public Computer(Brand brand) {
10         this.brand = brand;
11     }
12 
13     public void sale() {
14         brand.sale();
15     }
16 }
17 
18 /**
19  * 臺式機
20  * @author CL
21  *
22  */
23 class Desktop extends Computer {
24 
25     public Desktop(Brand brand) {
26         super(brand);
27     }
28     
29     @Override
30     public void sale() {
31         super.sale();
32         System.out.println("銷售臺式機");
33     }
34 }
35 
36 /**
37  * 筆記本
38  * @author CL
39  *
40  */
41 class Laptop extends Computer {
42 
43     public Laptop(Brand brand) {
44         super(brand);
45     }
46     
47     @Override
48     public void sale() {
49         super.sale();
50         System.out.println("銷售筆記本");
51     }
52 }
53 
54 /**
55  * 平板電腦
56  * @author CL
57  *
58  */
59 class Pad extends Computer {
60 
61     public Pad(Brand brand) {
62         super(brand);
63     }
64     
65     @Override
66     public void sale() {
67         super.sale();
68         System.out.println("銷售平板電腦");
69     }
70 }

  (2)品牌維度

 1 /**
 2  * 一種維度:品牌
 3  * @author CL
 4  *
 5  */
 6 public interface Brand {
 7     void sale();
 8 }
 9 
10 /**
11  * 聯想電腦
12  * @author CL
13  *
14  */
15 class Lenovo implements Brand {
16 
17     @Override
18     public void sale() {
19         System.out.println("銷售聯想電腦");
20     }
21     
22 }
23 
24 /**
25  * 戴爾電腦
26  * @author CL
27  *
28  */
29 class Dell implements Brand {
30 
31     @Override
32     public void sale() {
33         System.out.println("銷售戴爾電腦");
34     }
35     
36 }
37 
38 /**
39  * 華碩電腦
40  * @author CL
41  *
42  */
43 class ASUS implements Brand {
44 
45     @Override
46     public void sale() {
47         System.out.println("銷售華碩電腦");
48     }
49     
50 }

  (3)測試

 1 /**
 2  * 客戶端
 3  * @author CL
 4  *
 5  */
 6 public class Client {
 7     
 8     public static void main(String[] args) {
 9         //銷售聯想筆記本電腦
10         Computer  c1 = new Laptop(new Lenovo());
11         c1.sale();
12         
13         //銷售戴爾臺式機
14         Computer c2 = new Desktop(new Dell());
15         c2.sale();
16     }
17 
18 }

  控制檯輸出:

銷售聯想電腦
銷售筆記本
銷售戴爾電腦
銷售臺式機

  (4)假如如今要在品牌維度上增長一種品牌:宏碁電腦,只須要在品牌維度中增長以下代碼:

 1 /**
 2  * 宏碁電腦
 3  * @author CL
 4  *
 5  */
 6 class Acer implements Brand {
 7 
 8     @Override
 9     public void sale() {
10         System.out.println("銷售宏碁電腦");
11     }
12     
13 }

  (5)測試

 1 /**
 2  * 客戶端
 3  * @author CL
 4  *
 5  */
 6 public class Client {
 7     
 8     public static void main(String[] args) {
 9         //銷售聯想筆記本電腦
10         Computer  c1 = new Laptop(new Lenovo());
11         c1.sale();
12         
13         //銷售戴爾臺式機
14         Computer c2 = new Desktop(new Dell());
15         c2.sale();
16         
17         //銷售宏碁的平板電腦
18         Computer c3 = new Pad(new Acer());
19         c3.sale();
20     }
21 
22 }

  控制檯輸出:

銷售聯想電腦
銷售筆記本
銷售戴爾電腦
銷售臺式機
銷售宏碁電腦
銷售平板電腦

4、橋接模式總結

  (1)橋接模式能夠取代多層繼承的方案。

      多層繼承違背了單一職責原則,複用性較差,類的個數也很是多。橋接模式能夠極大的減小子類的個數,從而下降管理和維護的成本。

  (2)橋接模式極大的提升了系統的可擴展性。

      在兩個變化的維度中任意擴展一個維度。都不須要修改原有的代碼,符合開閉原則。

5、橋接模式實際開發中的應用場景

  (1)JDBC驅動程序;

  (2)AWT中的Peer框架;

  (3)人力資源系統中的獎金計算模塊:

      獎金分類:我的獎金、團隊獎金、激勵獎金

      部門分類:開發部門、運維部門、人事部門

  (4)OA系統中的消息處理:

      業務類型:普通消息、加密消息、緊急消息

      發送方式:系統內部、手機短信、郵件、飛秋

  (5)…………

相關文章
相關標籤/搜索