理解设计模式(八)——桥接模式

桥接模式

理解设计模式(一)——简单工厂 理解设计模式(二)——工厂方法 理解设计模式(四)——建造者 理解设计模式(五)——原型模式 理解设计模式(六)——单例模式 理解设计模式(七)——适配器模式

提出问题

根据课本上的说法,有这样一种情况:一个对象存在两个变化的纬度。具体的🌰:实现一个图像显示,有jpg、gif、bmp、png四种格式,每种图片格式可以在windows、linux、Unix、Mac OS上显示。

如果分别对每种图片格式实现不同系统上的显示方式,则需要4*4=16个类。类的数目过于庞大。而且如果后期要添加更多的系统或者图片格式,则需要添加更多的类。

解决问题

类的数量为什么会过多?因为我们试图在一个类里面解决两种变化,这其实违背了设计模式的单一职责原则。一个类既要负责文件格式,又要负责系统类型。如果我们把职责拆分开,一个类专门负责图片格式,另一个类负责系统类型。那么就只需要4+4个类了。

要想一个类只需要负责一个变化的部分,就需要屏蔽另一个变化的部分。拿这里来说,负责解析图片格式的类就不需要关心系统类型。负责系统类型的类就不需要关心图片格式。

为了实现这样的效果,我们需要增加一些东西。

比如,为了让负责不同系统绘制的类不需要了解图片类型,那么我们就需要统一一个图片类型。比如,我们可以把所有的图片格式都转换为matrix,所有负责处理不同系统绘制图片的类都面向matrix编程即可,不需要了解其他的图片格式。

为了让解析不同图片格式的类屏蔽掉不同系统具体的绘制方法,可以设计一个操作系统绘制图片的接口。解析图片时,只要调用这个接口,不需要关心是什么操作系统。

代码示例如下:

class Matrix {
// ...
// 把所有图片格式都转换为该格式
}

class Windows {
DoPaint(Matrix m) {
// ...展示matrix
}
}

class Linux {
DoPaint(Matrix m) {
// ...展示matrix
}
}

class Unix {
DoPaint(Matrix m) {
// ...展示matrix
}
}

class MacOS {
DoPaint(Matrix m) {
// ...展示matrix
}
}

class Image {
constructor(OS) {
this.OS = OS;
}
}

class JPG extends Image {
ParseFile(fileName) {
// ...
Matrix m = new Matrix(parse(fileName));
this.OS.DoPaint(m);
}
}

class PNG extends Image {
ParseFile(fileName) {
// ...
Matrix m = new Matrix(parse(fileName));
this.OS.DoPaint(m);
}
}

class BMP extends Image {
ParseFile(fileName) {
// ...
Matrix m = new Matrix(parse(fileName));
this.OS.DoPaint(m);
}
}

class GIF extends Image {
ParseFile(fileName) {
// ...
Matrix m = new Matrix(parse(fileName));
this.OS.DoPaint(m);
}
}

let mac = new MacOS();
let img = new JPG(mac);
img.ParseFile("test.jpg");
Author: LeoB_O
Link: https://leob-o.github.io/2019/06/05/BridgePattern/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.