开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
一、介绍
1.1 桥接模式(Builder)
桥接,顾名思义,就是用来连接两个部分,为被分离了的抽象部分和实现部分搭桥。 **官方一点的说明:**桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interfce)模式。
1.2 桥接模式的结构
桥梁模式所涉及的角色有:
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
- 修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
1.3 类图(维基百科)
来自:维基百科
1.4 使用场景
- 如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
- 一个类存在两个独立变化的维度,而这两个维度都需要进行扩展。
二、举例
2.1 问题引入
电脑特点分为可触屏和不可触屏,同时电脑又有那么多品牌。如果新增一个品牌或者新增一个特点,如何能让我们的代码写的更好,看起来更优雅那,这个时候就需要考虑桥接模式了
2.2 品牌 Brade
public interface Brade {
//开机
void open();
//打电话;
void internet();
//关机;
void close();
}
2.3 品牌实现类
package com.test.designpattern.bridge;
public class Mac implements Brade{
@Override
public void open() {
System.out.println("Mac开机");
}
@Override
public void internet() {
System.out.println("Mac上网");
}
@Override
public void close() {
System.out.println("Mac关机");
}
}
package com.test.designpattern.bridge;
public class Lenovo implements Brade{
@Override
public void open() {
System.out.println("Lenovo开机");
}
@Override
public void internet() {
System.out.println("Lenovo上网");
}
@Override
public void close() {
System.out.println("Lenovo关机");
}
}
2.4 抽象电脑 AbsComputer
package com.test.designpattern.bridge;
public abstract class AbsComputer {
//聚合品牌;
private Brade brade;
public AbsComputer(Brade brade) {
super();
this.brade = brade;
}
//调用品牌的方法;
protected void open(){
this.brade.open();
}
protected void internet(){
this.brade.internet();
}
protected void close(){
this.brade.close();
}
}
2.5 可触摸电脑和不可触摸电脑
package com.test.designpattern.bridge;
/**
* 可触摸电脑
*/
public class TouchableComputer extends AbsComputer{
public TouchableComputer(Brade brade) {
super(brade);
}
public void open(){
System.out.println("可触摸电脑");
super.open();
}
public void internet(){
System.out.println("可触摸电脑");
super.internet();
}
public void close(){
System.out.println("可触摸电脑");
super.close();
}
}
package com.test.designpattern.bridge;
/**
* 不可触摸电脑
*/
public class UntouchableComputer extends AbsComputer{
public UntouchableComputer(Brade brade) {
super(brade);
}
public void open(){
System.out.println("不可触摸电脑");
super.open();
}
public void internet(){
System.out.println("不可触摸电脑");
super.internet();
}
public void close(){
System.out.println("不可触摸电脑");
super.close();
}
}
2.6 客户端
package com.test.designpattern.bridge;
public class Client {
public static void main(String[] args) {
//选择可触摸mac操作
AbsComputer mac=new TouchableComputer(new Mac());
mac.open();
mac.internet();
mac.close();
System.out.println("<------------------------------->");
//使用可触摸Lenovo操作;
AbsComputer lenovo = new TouchableComputer(new Lenovo());
lenovo.open();
lenovo.internet();
lenovo.close();
System.out.println("<------------------------------->");
//选择不可触摸mac操作
AbsComputer macUntouchable = new UntouchableComputer(new Mac());
macUntouchable.open();
macUntouchable.internet();
macUntouchable.close();
System.out.println("<------------------------------->");
}
}
2.7 结果
可触摸电脑 Mac开机 可触摸电脑 Mac上网 可触摸电脑 Mac关机
<------------------------------->
可触摸电脑 Lenovo开机 可触摸电脑 Lenovo上网 可触摸电脑 Lenovo关机
<------------------------------->
不可触摸电脑 Mac开机 不可触摸电脑 Mac上网 不可触摸电脑 Mac关机
<------------------------------->
2.8 优缺点:
优点:
- 桥接模式避免了多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
- 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。
缺点:
- 桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。
三、参考
zh.m.wikipedia.org/wiki/%E6%A9… zhuanlan.zhihu.com/p/58903776 blog.csdn.net/MrTumnus/ar… www.bilibili.com/video/BV1G4…