定义
桥接模式属于结构型模式中的一种,也称之为桥梁模式,书中的定义:将抽象部分与它的实现部分分离,使它们都可以独立的变化,官话有点难理解。
个人理解,桥接模式是相对于继承的,一般通过继承,可以对我们的代码进行扩展,但是随着继承体系逐渐庞大,会产生比较多的子类,难以管理,而且继承将所有的类都绑定在一起,存在一定的耦合性,如果父类发生变化,很有可能会影响到子类,对后期的扩展不友好。
于是,我们可以在设计上对业务进行更细致的抽象,以汽车为例,有各种类型的汽车,各种各样的品牌,同时汽车也有各种的颜色等等,如果以汽车为抽象类,就会出现A品牌的白色卡车、B品牌的银色轿车、C品牌的黑色跑车等等具体类,这会出现非常庞大的继承体系。为了解决这个问题,就可以将根据各种特点单独进行抽象,汽车类型,品牌,颜色等,使它们能够保持自己的独立性,可以单独发展。然后在抽象层面将他们通过聚合,复用的方式组合在一起,这个过程就叫做桥接。
再回头看定义:“将抽象部分与它的实现部分分离”,即在抽象层面将他们之间的关系聚合在一起,而具体的实现则是与他们保持分离的状态(抽象的方式描述关系,关系之间的顶点代入具体实现)。
继承方式下抽象和实现是不分离的,从结构上看,继承是一个悠长的瘦子,是一个一维的扩展方式,而通过桥接的方式,将扩展方式变成了二维,通过更细致的抽象+聚合的方式将原本只能在一个维度扩展变成了从两个维度上扩展,变成了一个小胖子。形象点就是油条变成了包子,结构更稳定。
如果理解了上边的概念,接下来的东西简单看一下应该很容易理解
其中的一些角色信息
- 抽象化角色(Abstraction):定义抽象类,并包含一个对实现化对象的引用
- 扩展抽象化角色(Refined Abstraction):是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
- 实现化角色(Implementor):定义实现化角色的接口,供扩展抽象化角色使用
- 具体实现化(Concrete Implementor):实现化接口具体实现
UML:
图片来源:知乎
代码表示
public class BridgeTest {
public static void main(String[] args) {
Implementor imple = new ConcreteImplementorA();
Abstraction abs = new RefinedAbstraction(imple);
abs.Operation();
}
}
//实现化角色
interface Implementor {
public void OperationImpl();
}
//具体实现化角色
class ConcreteImplementorA implements Implementor {
public void OperationImpl() {
System.out.println("具体实现化(Concrete Implementor)角色被访问");
}
}
//抽象化角色
abstract class Abstraction {
protected Implementor imple;
protected Abstraction(Implementor imple) {
this.imple = imple;
}
public abstract void Operation();
}
//扩展抽象化角色
class RefinedAbstraction extends Abstraction {
protected RefinedAbstraction(Implementor imple) {
super(imple);
}
public void Operation() {
System.out.println("扩展抽象化(Refined Abstraction)角色被访问");
imple.OperationImpl();
}
}
代码片段来源:知乎
偷个懒,,,,,,,
2.示例
接下来以汽车为实例,对桥接模式进行一个简单的实现
实现化角色和具体实现化角色,以颜色为例
/**
* @description: 实现化角色 =>color
* @create by twotiger2tigersofast
* @datetime 2023/3/28 23:13
* @version: 1.0
*/
public interface Color {
String getColor();
}
/**
* @description: 具体实现化角色 =>white
* @version: 1.0
*/
public class White implements Color{
@Override
public String getColor() {
return "Color: White";
}
}
/**
* @description: 具体实现化角色 =>black
* @version: 1.0
*/
public class Black implements Color{
@Override
public String getColor() {
return "Color: Black";
}
}
/**
* @description: 具体实现化角色 =>red
* @version: 1.0
*/
public class Red implements Color{
@Override
public String getColor() {
return "Color: Red";
}
}
抽象化角色,内部持有实现化的引用,这个就是桥接,实际上就是抽象层的组合
/**
* @description: 抽象化角色
* @version: 1.0
*/
public abstract class Vehicle {
protected Color color;
public Vehicle(Color color){
this.color = color;
}
public abstract void getVehicle();
}
扩展抽象化角色,对抽象化实现进行具体的实现
/**
* @description: 扩展抽象化角色 =>sport car
* @create by twotiger2tigersofast
* @datetime 2023/3/28 23:20
* @version: 1.0
*/
public class SportCar extends Vehicle{
public SportCar(Color color) {
super(color);
}
@Override
public void getVehicle() {
System.out.println(color.getColor() + ">>>>>>>Sport Car");
}
}
/**
* @description: 扩展抽象化角色 =>suv
* @version: 1.0
*/
public class Suv extends Vehicle{
public Suv(Color color) {
super(color);
}
@Override
public void getVehicle() {
System.out.println(color.getColor() + ">>>>>>>Suv");
}
}
/**
* @description: 扩展抽象化 =>卡车
* @version: 1.0
*/
public class Truck extends Vehicle{
public Truck(Color color) {
super(color);
}
@Override
public void getVehicle() {
System.out.println(color.getColor() + ">>>>>>>Truck");
}
}
test
/**
* @description: test
* @version: 1.0
*/
public class Test {
public static void main(String[] args) {
//创建颜色
Color white = new White();
Color black = new Black();
Color red = new Red();
//创建各类汽车
Vehicle sportCar = new SportCar(white);
Vehicle suv = new Suv(black);
Vehicle truck = new Truck(red);
//...
//...
//run
sportCar.getVehicle();
suv.getVehicle();
truck.getVehicle();
//...
//...
}
}
input:
Color: White>>>>>>>Sport Car
Color: Black>>>>>>>Suv
Color: Red>>>>>>>Truck
3.总结
桥接模式弱化了静态的继承关系,在抽象层面建立了一组关联关系,使得具体对象在关联关系的聚合框架下更为灵活的组织代码。增加了扩展的方向,一个类的变化从单纬度变为两个维度,也可以说从垂直扩展变成了水平+垂直扩展,使得内部结构更为紧凑稳定,外层实现则更为灵活,实现抽象和具体实现分离,遵循开闭原则。当然,桥接模式需要在前期设计上下足够的功夫,能够更为合理的对业务细节进行抽象是关键,如果设计不合理,可能会增加更多的复杂性。