描述
- 抽象和实现分离,使用组合代替继承关系维护对象之间的关系。
- 比如不同的视屏播放器,可以播放各种格式的视屏,视屏播放器的具体播放方式,不同格式的视屏解析方式,都不尽相同。
- 可以在不影响原有视屏格式的前提下,扩展新增播放器;也可以在不影响播放器的前提下,扩展新增不同格式的视屏。
- 其实就是把不同维度的角色,桥接起来。
角色
- 抽象化接口:比如不同的视屏解析规范
- 实现化类:具体的视屏,比如MP4,AVI
- 扩展抽象化类:播放器抽象对象,聚合抽象化接口,比如视屏播放器,
- 具体实现化类:具体的播放器,比如爱奇艺,B站,可以播放不同的视屏
实现
public class Test {
public static void main(String[] args) {
AbstractPalyer abstractPalyer = new BiliPalyer(new Mp4VideoServiceImpl());
abstractPalyer.play("哪吒闹海");
}
}
interface VideoService {
void decode();
}
class Mp4VideoServiceImpl implements VideoService {
@Override
public void decode() {
System.out.println("MP4编码");
}
}
class AviVideoServiceImpl implements VideoService {
@Override
public void decode() {
System.out.println("avi编码");
}
}
abstract class AbstractPalyer {
VideoService videoService;
AbstractPalyer(VideoService videoService) {
this.videoService = videoService;
}
abstract void play(String fileName);
}
class BiliPalyer extends AbstractPalyer {
BiliPalyer(VideoService videoService) {
super(videoService);
}
@Override
void play(String fileName) {
videoService.decode();
System.out.println("Mp4播放器播放:" + fileName);
}
}
class IqiyiPalyer extends AbstractPalyer {
IqiyiPalyer(VideoService videoService) {
super(videoService);
}
@Override
void play(String fileName) {
videoService.decode();
System.out.println("爱奇艺播放器播放:" + fileName);
}
}
优点
- 开闭原则,可扩展性,两个维度任意扩展一个,不影响原有系统。
使用场景
- 当一个类存在两个独立变化的维度,且两个维度都可能扩展时。
- 当使用继承可能会导致类爆炸时。
与装饰者模式的区别
- 装饰者模式的本质是对自己扩展。比如装饰者模式篇,主料(奶茶)和辅料(珍珠)都属于奶茶店,奶茶店都可提供,因此,主料继承奶茶店,辅料继承奶茶店,主料可以一直添加相同或不同的辅料(都是奶茶店子类),自己就是自己,可以实现自我无限套娃。
- 桥接模式,是聚合的关系,比如播放器抽象类,播放器拥有播放不同的视屏的能力,是拥有的关系,一对一的关系,虽然无法实现套娃,但是在不影响原有功能的前提下,可实现随时切换不同格式的视屏。