桥接模式就是将抽象部分和实际部分用一个桥接过渡起来,即将继承关系变为关联关系,从而使得两部分可以扩展而互不影响。
案例举例说明
电脑有文件解析功能,有不用的操作系统,有很多不同类型的文件,假设使用传统的继承模式就是这样的
Computer 电脑作为一个类
Computer有 Mac,Linux,Windows 等等具体的实现类。
假设有一个视频文件解析 VideoFile ,当 三个操作系统都有这种视频解析功能时,那么就是有三个操作系统视频解析类
MacVideoFile、LinuxVideoFile 和 WindowsVideoFile
假设又出现了音频解析器 MusicFile,并且三个操作系统也都有这个功能,那么就又有三个操作系统音频解析类
MacMusicFile、LinuxMusicFile 和 WindowsMusicFile
那么如果有出现了三个操作系统并且有 VideoFile 和 MusicFile 解析功能时,又该怎么办呢?难道又创建各种类?
这样就可以看出来了,传统的继承模式很容易出现 类爆炸 的情况,所以这样是不可取的。
使用桥接模式实现上面的文件解析案例:
1、定义一个操作系统类:OperateSystem【桥接连接器】,我们将 文件解析器【FileParser,抽象接口】作为 OperateSystem 的成员(聚合关系)
2、咱们将在创建操作系统时,将 FileParser 作为参数传递给 OperateSystem 的构造器,这样子就可以很轻松的创建出有各个功能的操作系统了。
3、 FileParser 只是一个抽象类或者接口,在给 OperateSystem 传递参数是应该是 FileParser 的子类或者实现类
4、有很多种不同的操作系统,直接继承自 OperateSystem 即可。
代码实现如下:
1、定义抽象接口【FileParser,文件解析器】,其中包含文件解析的抽象方法。
/**
* 文件解析器
**/
public interface FileParser {
/**
* 文件解析方法
**/
void parse();
}
2、说明具体的文件解析器,用于解析不同类型的文件【视频文件解析器和音频文件解析器】
public class VideoFileParser implements FileParser {
@Override
public void parse() {
System.out.println("解析视频文件");
}
}
public class MusicFileParser implements FileParser {
@Override
public void parse() {
System.out.println("解析音频文件");
}
}
3、定义桥接连接器【OperateSystem】,需要声明文件解析方法 parseFile() 。
public abstract class OperateSystem {
private String name;
/**
* 若要实现一个操作系统可以同时执行多个文件解析器,实例直接使用 List<FileParser> 就行了,
* 然后再具体的子类 的 parseFile() 方法里面一次便利所有父类的 fileParser 就可以了
**/
private List<FileParser> fileParsers = new ArrayList<>();
public abstract void parseFile();
public OperateSystem() {
//每次可以传递多个文件解析器
public OperateSystem(FileParser ...parsers ) {
if (parsers.length != 0) {
this.fileParsers.addAll(Arrays.asList(parsers));
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<FileParser> getFileParsers() {
return fileParsers;
}
public void setFileParsers(List<FileParser> fileParsers) {
this.fileParsers = fileParsers;
}
}
4、声明具体的操作系统,需要继承桥接连接器。如Windows 或者 Mac。
public class Windows extends OperateSystem {
@Override
public void parseFile() {
System.out.println(super.getName() + "要解析文件了");
if (!super.getFileParsers().isEmpty()) {
for (FileParser parser : super.getFileParsers()) {
parser.parse();
}
}
public Windows(FileParser ...fileParser) {
super(fileParser);
super.setName("Windows");
}
}
// Mac 操作系统
public class Mac extends OperateSystem {
@Override
public void parseFile() {
System.out.println(super.getName() + "要解析文件了");
if (!super.getFileParsers().isEmpty()) {
for (FileParser parser : super.getFileParsers()) {
parser.parse();
}
}
public Mac(FileParser ...fileParser) {
super(fileParser);
super.setName("Mac");
}
}
5、测试,声明具体的操作系统,声明时传入相应的文件解析器,就可以实现解析功能了。
public static void main(String[] args) {
Windows windows = new Windows(new VideoFileParser(),new MusicFileParser());
windows.parseFile();
}
//打印输出
Windows要解析文件了
解析视频文件
解析音频文件
桥接模式的组成说明:
在实现桥接模式时,有两个重要的概念:抽象部分【FileParser】和实现部分【VideoFileParser 和 MusicFileParser】。
抽象部分定义了系统中所需功能的通用接口,而实现部分则负责提供这些接口的具体实现。这两个部分之间通过桥接连接器进行交互。
在桥接模式中,系统必须包含一个抽象类或接口,它定义了所有实施具体功能所需的方法。
这个抽象基类与实现它的所有子类之间都应该存在一个桥接连接器【FileParser 作为 OperateSystem 的成员变量,聚合到 OperateSystem 里面】。
这个桥接连接器就是一个抽象类或接口,它声明了所有该特性所需的方法【OperateSystem#parseFile()】,但并不提供任何默认实现。
文章介绍了桥接模式的概念,通过电脑操作系统和文件解析功能的例子展示了传统继承模式可能导致的类爆炸问题。桥接模式通过将抽象部分(如文件解析器)和实现部分(如操作系统)解耦,解决了这个问题。具体实现中,定义了文件解析器接口和操作系统抽象类,操作系统持有文件解析器的列表,可以根据需要组合不同的解析器和操作系统。测试代码显示了如何创建和使用这些组件来解析不同类型的文件。
416

被折叠的 条评论
为什么被折叠?



