桥梁模式
定义:
将抽象部分与实现部分分离,使它们都可以独立的变化。重点需要理解如何将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。
类图:
举例:(智能手机使用安装包的例子)
—未优化的例子—
/**
* 智能手机抽象类
*/
public abstract class SmartPhone {
public abstract void installApk();
public abstract void openApk();
public void useApk() {
installApk();
openApk();
}
}
/**
* 专门使用微信手机
*/
public class WechatPhone extends SmartPhone {
@Override
public void installApk() {
System.out.println("安装微信");
}
@Override
public void openApk() {
System.out.println("打开微信");
}
@Override
public void useApk() {
super.useApk();
System.out.println("开始使用微信");
}
}
/**
* 专门使用QQ手机
*/
public class QQPhone extends SmartPhone {
@Override
public void installApk() {
System.out.println("安装QQ");
}
@Override
public void openApk() {
System.out.println("打开QQ");
}
@Override
public void useApk() {
super.useApk();
System.out.println("使用QQ");
}
}
//TODO 之后每安装一种apk都要使用不同的手机......
引出问题:我们会发现,每安装一种APK都是用一个手机,这是不合理的,应该一种手机可以安装不同的APK
细心点,会发现 “apk” 和 “手机” 是两个不同的维度。而且抽象和实现写在了一起(即SmartPhone类里面的两个抽象方法和一个具体实现方法),这是十分不合理的。
—优化之后—
/**
* 抽象APK
*/
public abstract class APK {
public abstract void beInstalled();
public abstract void beOpened();
}
public class WeChat extends APK {
@Override
public void beInstalled() {
System.out.println("微信被安装");
}
@Override
public void beOpened() {
System.out.println("微信被打开");
}
}
public class QQ extends APK {
@Override
public void beInstalled() {
System.out.println("QQ被安装");
}
@Override
public void beOpened() {
System.out.println("QQ被打开");
}
}
/**
* 抽象智能手机
*/
public abstract class SmartPhone {
private APK apk;
public SmartPhone(APK apk) {
this.apk = apk;
}
public void useApk() {
apk.beInstalled();
apk.beOpened();
}
}
public class HuaWei extends SmartPhone {
public HuaWei(APK apk) {
super(apk);
}
}
public class User {
public void useApk() {
WeChat weChat = new WeChat();
HuaWei huaWei = new HuaWei(weChat);
huaWei.useApk();
QQ qq = new QQ();
huaWei = new HuaWei(qq);
huaWei.useApk();
}
}
修改之后,可知道手机和APK两个维度已经拆开了。还有抽象与实现也拆开了。下面看看优化之后的好处。
比如说像增加多一个APK,如钉钉
/**
* 抽象APK
*/
public abstract class APK {
public abstract void beInstalled();
public abstract void beOpened();
}
public class WeChat extends APK {
@Override
public void beInstalled() {
System.out.println("微信被安装");
}
@Override
public void beOpened() {
System.out.println("微信被打开");
}
}
public class QQ extends APK {
@Override
public void beInstalled() {
System.out.println("QQ被安装");
}
@Override
public void beOpened() {
System.out.println("QQ被打开");
}
}
> public class DingDing extends APK {
>
> @Override
> public void beInstalled() {
> System.out.println("钉钉被安装");
> }
>
> @Override
> public void beOpened() {
> System.out.println("钉钉被打开");
> }
>
> }
/**
* 抽象智能手机
*/
public abstract class SmartPhone {
private APK apk;
public SmartPhone(APK apk) {
this.apk = apk;
}
public void useApk() {
apk.beInstalled();
apk.beOpened();
}
}
public class HuaWei extends SmartPhone {
public HuaWei(APK apk) {
super(apk);
}
}
public class User {
public void useApk() {
WeChat weChat = new WeChat();
HuaWei huaWei = new HuaWei(weChat);
huaWei.useApk();
QQ qq = new QQ();
huaWei = new HuaWei(qq);
huaWei.useApk();
> DingDing dingDing = new DingDing();
> huaWei = new HuaWei(dingDing);
> huaWei.useApk();
}
}
会发现,修改的部分,只是代码里面右箭头增加的部分。
手机可能不单只是使用华为的,可能还用小米,所以,代码可以这样优化。
/**
* 抽象APK
*/
public abstract class APK {
public abstract void beInstalled();
public abstract void beOpened();
}
public class WeChat extends APK {
@Override
public void beInstalled() {
System.out.println("微信被安装");
}
@Override
public void beOpened() {
System.out.println("微信被打开");
}
}
public class QQ extends APK {
@Override
public void beInstalled() {
System.out.println("QQ被安装");
}
@Override
public void beOpened() {
System.out.println("QQ被打开");
}
}
/**
* 抽象智能手机
*/
public abstract class SmartPhone {
private APK apk;
public SmartPhone(APK apk) {
this.apk = apk;
}
public void useApk() {
apk.beInstalled();
apk.beOpened();
}
}
public class HuaWei extends SmartPhone {
public HuaWei(APK apk) {
super(apk);
}
}
> public class XiaoMi extends SmartPhone {
>
> public XiaoMi(APK apk) {
> super(apk);
> }
> }
public class User {
public void useApk() {
WeChat weChat = new WeChat();
HuaWei huaWei = new HuaWei(weChat);
huaWei.useApk();
QQ qq = new QQ();
huaWei = new HuaWei(qq);
huaWei.useApk();
> System.out.println("使用小米手机");
> XiaoMi xiaoMi = new XiaoMi(weChat);
> xiaoMi.useApk();
> xiaoMi = new XiaoMi(qq);
> xiaoMi.useApk();
}
}
看,只是增加了代码右键头部分的代码,十分方便。
最后总结:
总结就是第一句的定义呗。其实桥梁模式的优点就是类间解耦,两个角色都可以自己的扩展下去,不会相互影响,这个符合 OCP 原则。