木灵鱼儿

木灵鱼儿

阅读:153

最后更新:2022/06/06/ 0:03:51

结构型模式:桥接模式

简介

桥接模式是指:将抽象与实现分离,使它们可以独立变化。它使用组合关系来代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

简单点来说,桥接模式用就是用于连接两个独立变化维度的一种方式(组合),而为什么要连接,我们需要先了解到类继承带来的复杂性。

先看一张图:

我们可以看到,从最顶层的电脑类延伸了三个子类,子类又延伸出不同的品牌类,如果我们又新增了一个新的电脑子类,比如二合一电脑,又不得不重复实现一下对应的品牌子类;

如果是新增新的品牌,也是同理,也得产生很多新的子类。

这就导致类的不断产生,从而有了类爆炸这一说。

而桥接模式,就是用于解决这个问题的,我们将他们进行抽象,你会发现有两个会变动的东西,一个是不同的电脑分类,一个是不同的品牌,他们就等于是两个可变的维度。

那如何进行桥接呢?

我们可以参考现实中的一种处理方式:贴牌;厂商生产出对应的产品,但是他是没有品牌的,品牌方可以联系工厂,进行贴牌,贴上我自己的logo,它就是我的产品了。

而桥接,在代码的定义里,也是类似的,我们会抽象出一个电脑的类,这个类会提供接口,将品牌聚合到自身,聚合的接口依赖于品牌的接口(抽象),将品牌进行解耦了,具体的品牌由它的子类去实现。加上自身为一个抽象,具体的实现交给了子类,此时电脑分类与品牌是没有继承关系了,从而减少了类的产生。

代码实现

//品牌接口
interface Brand {
  info(): string; //用于输出品牌信息
}

//具体的品牌子类实现
//戴尔
class Dell implements Brand {
  info() {
    return "dell";
  }
}

//三星
class Samsung implements Brand {
  info() {
    return "samsung";
  }
}

//电脑的抽象,用于桥接品牌与具体的电脑实现
abstract class Computer {
  brand: Brand;

  constructor(brand: Brand) {
    this.brand = brand;
  }

  //抽象方法,用于输出电脑的品牌信息
  abstract info(): string;
}

//具体的电脑子类实现
//台式电脑
class Desktop extends Computer {
  constructor(brand: Brand) {
    super(brand);
  }

  info() {
    return `${this.brand.info()} 台式电脑`;
  }
}

//笔记本电脑
class Laptop extends Computer {
  constructor(brand: Brand) {
    super(brand);
  }

  info() {
    return `${this.brand.info()} 笔记本电脑`;
  }
}

//平板电脑
class Tablet extends Computer {
  constructor(brand: Brand) {
    super(brand);
  }

  info() {
    return `${this.brand.info()} 平板电脑`;
  }
}

我们简单实现了两个品牌和三个电脑类,一个电脑的抽象,抽象里面会要求聚合一个品牌,依赖的是一个接口。

此时我们想创建不同的品牌不同的电脑,进行组合就可以了。

//三星的平板电脑
const samsungTablet = new Tablet(new Samsung());
console.log(samsungTablet.info());

//戴尔的笔记本
const dellLaptop = new Laptop(new Dell());
console.log(dellLaptop.info());

上述代码都只是为了方便让我们理解什么是桥接模式,代码上怎么去实现桥接,但是实际情况下,代码可能会比上述的要复杂很多,所以,要理解逻辑思维,而不是照搬一样的代码。

扩展思维

就以前端的一个弹窗来拓展下思维吧,就不进行具体实现了。

弹窗是有很多种动画的,有渐变啊,有闪烁啊,有自上而下啊,多种多样,弹窗自身又有很多种分类:message、dialog、 MessageBox、 Notification 等等。

那么动画和弹窗可以看做是两种独立变化维度,我们可以将他们组合起来使用,而不是继承的方式去实现。减少类的产生,编写代码和使用都会因为桥接模式减少很多心智负担。

动画

抽象出一个接口,接口里面有:show方法,不同的生命周期钩子,hide方法

然后不同的动画根据接口进行具体的实现。

弹窗

抽象出一个类,类提供一个接口用于聚合动画,并依赖动画的抽象接口。自身定义了:show、hide方法用于弹窗的调用关闭。

然后具体的子类则去实现这个抽象类。

使用

使用的时候将他们组合到一起就可以了,以后我这个A弹窗想换一个动画,是不是更换一个具体的动画子类就可以了,这就是组合使用的好处。

版权申明

本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。

关于作者

站点职位 博主
获得点赞 0
文章被阅读 153

相关文章