设计模式GOF23--桥接模式

场景

  • 商城系统中常见的商品分类,以电脑为类,如何良好的处理商品分类销售的问题?
    如图所示,我们的电脑有很多的品牌,如联想,戴尔等。同时,我们的电脑有很多的品类,如台式机,笔记本,平板电脑等。那么,我们组合展示电脑的时候,我们一般会使用多层继承结构实现图中关系:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.kid.bridge;

public interface Computer {
void sale();
}

class Desktop implements Computer{

@Override
public void sale() {
System.out.println("销售台式机");
}
}

class Laptop implements Computer{

@Override
public void sale() {
System.out.println("销售笔记本");
}
}

class LenovoDesktop extends Desktop{
@Override
public void sale() {
System.out.println("销售联想台式机");
}
}

class LenovoLaptop extends Laptop{
@Override
public void sale() {
System.out.println("销售联想笔记本");
}
}


class DellDesktop extends Desktop{
@Override
public void sale() {
System.out.println("销售戴尔台式机");
}
}

class DellLaptop extends Laptop{
@Override
public void sale() {
System.out.println("销售戴尔笔记本");
}
}

一件商品的展示,我们需要耗费很大的时间。就有如下问题发生:

  • 扩展性问题:
    • 如果要增加一个新的电脑类型,平板电脑,则要怎加各个品牌下面的类。
    • 如果要增加一个新的品牌,也要增加各种电脑类型的类。
  • 违反单一职责原则:
    • 一个类:联想笔记本,有两个引起这个类变化的原因

场景分析

  • 这个场景中有两个变化的维度:电脑类型、电脑品牌。那么,我们可以建立两个不同的维度,通过某些连接,使其两两不同组合。– > 桥接模式

桥接模式的核心要点

  • 处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。

代码解析

我们先建造电脑品牌维度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 电脑品牌维度
*/
public interface Brand {
void sale();
}

class Lenovo implements Brand{

@Override
public void sale() {
System.out.println("销售联想电脑");
}
}


class Dell implements Brand{

@Override
public void sale() {
System.out.println("销售戴尔电脑");
}
}

再建造电脑类型维度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* 电脑类型维度
*/
public class Computer2 {

protected Brand brand;

public Computer2(Brand brand) {
this.brand = brand;
}

public void sale(){
brand.sale();
}
}

class Desktop2 extends Computer2{

public Desktop2(Brand brand) {
super(brand);
}

@Override
public void sale() {
super.sale();
System.out.println("销售台式机");
}
}

class Laptop2 extends Computer2{

public Laptop2(Brand brand) {
super(brand);
}

@Override
public void sale() {
super.sale();
System.out.println("销售笔记本");
}
}

调用:

1
2
3
4
5
6
7
8
9
10
/**
* 桥接模式
*/
public class Client {
public static void main(String[] args) {
//销售联想笔记本电脑
Computer2 c = new Laptop2(new Lenovo());
c.sale();
}
}

这样,我们就很轻松的实现业务需求。即使增加新的品类或者品牌。也只需要增加部分代码就可以,而无需改动太多。

桥接模式实际开发中应用场景

  • JDBC驱动程序
  • AWT中的Peer架构
注:该博文为学习总结,视频来源为高淇java300集