橋接模式核心要點:框架
處理多層繼承結構,處理多維度變化的場景,將各個維度設計成獨立的繼承結構,使各個維度能夠獨立的擴展在抽象層創建關聯。運維
商城系統中常見的商品分類,以電腦爲類,如何良好的處理商品分類銷售的問題?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
若是要增長一個新的品牌,也要增長各類電腦類型的類。
② 違反了單一職責原則
一個類有兩個職責:品牌+電腦類型。每一個類都有兩個緣由引發變化。
(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 }
控制檯輸出:
銷售聯想電腦
銷售筆記本
銷售戴爾電腦
銷售臺式機
銷售宏碁電腦
銷售平板電腦
(1)橋接模式能夠取代多層繼承的方案。
多層繼承違背了單一職責原則,複用性較差,類的個數也很是多。橋接模式能夠極大的減小子類的個數,從而下降管理和維護的成本。
(2)橋接模式極大的提升了系統的可擴展性。
在兩個變化的維度中任意擴展一個維度。都不須要修改原有的代碼,符合開閉原則。
(1)JDBC驅動程序;
(2)AWT中的Peer框架;
(3)人力資源系統中的獎金計算模塊:
獎金分類:我的獎金、團隊獎金、激勵獎金
部門分類:開發部門、運維部門、人事部門
(4)OA系統中的消息處理:
業務類型:普通消息、加密消息、緊急消息
發送方式:系統內部、手機短信、郵件、飛秋
(5)…………