桥接模式

桥梁模式是对象的结构模式。又称为柄体(Handle and Body)模式或接口(Interface)模式。桥梁模式的用意是“将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化”。

我们假设一个场景:我们需销售电脑,电脑有三种:台式电脑,笔记本电脑,平板电脑。每种电脑又有多个品牌:联想,戴尔等等。。

所以我们需要写如下代码:

 1 package top.bigking.bridge;
 2 
 3 import sun.security.krb5.internal.crypto.Des;
 4 
 5 /**
 6  * @Author ABKing
 7  * @Date 2020/2/15 下午11:03
 8  **/
 9 public interface Computer1 {
10     void sale();
11 }
12 class Desktop implements Computer1{
13     @Override
14     public void sale() {
15         System.out.println("销售台式电脑");
16     }
17 }
18 class Laptop implements Computer1{
19     @Override
20     public void sale() {
21         System.out.println("销售笔记本电脑");
22     }
23 }
24 class Pad implements Computer1{
25     @Override
26     public void sale() {
27         System.out.println("销售平板电脑");
28     }
29 }
30 class LenovoDesktop extends Desktop{
31     @Override
32     public void sale() {
33         System.out.println("销售联想台式电脑");
34     }
35 }
36 class LenovoLaptop extends Laptop{
37     @Override
38     public void sale() {
39         System.out.println("销售联想笔记本电脑");
40     }
41 }
42 class LenovoPad extends Pad{
43     @Override
44     public void sale() {
45         System.out.println("销售联想平板电脑");
46     }
47 }

这样就不可避免地带来一个问题,当需要扩展新的品牌,新的电脑类型时,维护会变得非常困难,需要增加相当多的类。

究其原因,是因为一个类同时被两个因素制约:种类 和 品牌。

为了消除这个耦合,我们引入了桥接模式,把一个因素变成类的属性。

 写一个Computer2类

 1 package top.bigking.bridge;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/15 下午11:26
 6  **/
 7 public abstract class Computer2 {
 8     protected Brand brand;
 9     public Computer2(Brand brand) {
10         this.brand = brand;
11     }
12     public void sale(){
13         brand.sale();
14     }
15 }
16 class Desktop2 extends Computer2 {
17     public Desktop2(Brand brand) {
18         super(brand);
19     }
20     @Override
21     public void sale() {
22         super.sale();
23         System.out.println("销售台式机电脑");
24     }
25 }
26 class Laptop2 extends Computer2{
27     public Laptop2(Brand brand) {
28         super(brand);
29     }
30     @Override
31     public void sale() {
32         super.sale();
33         System.out.println("销售笔记本电脑");
34     }
35 }

还需要一个制约品牌的因素

 1 package top.bigking.bridge;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/15 下午11:27
 6  **/
 7 public interface Brand {
 8     void sale();
 9 }
10 class Lenovo implements Brand{
11     @Override
12     public void sale() {
13         System.out.println("品牌为联想");
14     }
15 }
16 class Dell implements Brand{
17     @Override
18     public void sale() {
19         System.out.println("品牌为戴尔");
20     }
21 }

运行JUnit单元测试:

 1 package top.bigking.bridge;
 2 
 3 import org.junit.Test;
 4 
 5 /**
 6  * @Author ABKing
 7  * @Date 2020/2/15 下午11:38
 8  **/
 9 public class TestBridge {
10     @Test
11     public void testBridge(){
12         Brand brand = new Lenovo();
13         Computer2 c = new Desktop2(brand);
14         c.sale();
15     }
16 }

运行结果:

品牌为联想
销售台式机电脑

 

桥接模式总结:

  • 桥接模式可以取代多层继承的方案。多层集成违背了单一职责原则,复用性较差,类的个数也非常多。桥接模式可以极大地减少子类的个数,从而降低管理和维护的成本。
  • 桥接模式极大地提高了系统可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则。

 

桥接模式在开发应用中的场景:

JDBC驱动程序

AWT中的Peer结构

银行日志管理:

  格式分类:操作日志、交易日志、异常日志

  距离分类:本地记录日志、异地记录日志

人力资源系统中的奖金计算模块

  奖金分类:个人奖金、团体奖金、激励奖金

  部门分类:人事部门、销售部门、研发部门

OA系统中的消息处理

  业务类型:普通消息、加急消息、特急消息

  发送消息方式:系统内消息、手机短信、邮件

posted @ 2020-02-15 23:30  ABKing  阅读(142)  评论(0编辑  收藏  举报