声明:
本节内容源自网络
【一句话介绍】
将抽象 与 实现 脱耦,使二者可以独立的变化。
桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。
桥梁模式目的就是把抽象化角色和实现化角色的强耦合解除掉。
【先混个脸熟】
这个系统包含两个等级结构:抽象等级结构 & 实现等级结构。
- 抽象化角色(Abstraction):抽象化给出的定义,并保存一个对实现化对象的引用。
- 修正抽象化角色(Refined Abstraction):扩展抽象化角色,改变和修正父类对抽象化的定义
- 实现化角色(Implementor):这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层操作。
- 具体实现化角色(Concreate Implementor):实现化角色接口的具体实现类。
抽象化角色就像一个水杯的手柄,实体类角色就像水杯的杯身,手柄控制杯身。
【讲个故事】
故事一、大飞机的故事
空中巴士(Airbus)、波音(Boeing)和麦道(McDonnell-Douglas)都是飞机制造商,它们都生产载客飞机(Passenger Plane) 和载货飞机(Cargo Plane),现在需要设计一个系统,描述这些飞机制造商以及它们所制造的飞机种类。
方案① --糟糕的示例
“开-闭 ”原则
这样的设计有一个很大的缺陷:在具体飞机与飞机制造商、飞机种类之间的耦合过强。一旦出现下面的情况,系统设计就不可避免第需要修改。
- 需要向系统引进新的飞机制造商
- 需要向系统引进新的飞机类型
组合/聚合复用原则(CARP)
要尽量使用合成/聚合,而不是继承关系来达到扩展系统功能的目的。
组合/聚合复用原则是达到"开-闭"原则要求的必要手段。
这个设计里过多的使用了继承关系,改变这一局面的办法就是放弃继承关系,通过动态的委派改进系统的设计。
方案② --改良
代码:
抽象角色类Airplane
修正抽象化角色载客飞机
public class PassengerPlane extends Airplane {
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("This is Passenger Plane fly.");
}
}
修正抽象化角色货运飞机
public class CargoPlane extends Airplane {
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("This is CargoPlane fly.");
}
}
实现化角色(Implementor)-实现化角色的接口--飞机厂商
public abstract class AirplaneMaker {
abstract public void produce();
}
具体实现化角色-空客 波音
public class Airbus extends AirplaneMaker {
@Override
public void produce(){
System.out.println("Airbus>>>>>>>>");
}
}
【小结】
现在如果需要增加新的飞机制造商或者新的飞机种类,只需要向系统引进一个新的修正抽象化角色,或者一个新的具体实现化角色就可以了。
或者说,系统的功能可以在不修改已有代码的情况下得到扩展。
桥梁模式-设计语言:
使用两个独立的等级结构封装两个独立的变化因素,并在它们之间使用聚合关系,以达到功能复合的目的。
故事二 新老司机开车的故事
对象:
主要有两个类层次结构
一类是司机类,有老司机、新手
二类是汽车类,有奔驰、奥迪、宝马
【代码】
①抽象化角色-司机类
/**
* @author
* @version V1.0
* @Date 2017年11月30日 下午1:52:27
* @Email
* @Description: 桥接模式 -司机抽象类
*/
public abstract class Driver {
private Car car;
public abstract void drive();
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
}
*此处没有把car写到构造函数参数中,主要考虑是降耦;
②实现化角色-抽象类-汽车类
/**
* @author
* @version V1.0
* @Date 2017年11月30日 下午1:54:11
* @Email
* @Description: 桥接模式-汽车抽象类
*/
public abstract class Car {
public abstract String run();
}
③抽象修正化角色
新司机
/**
* @author
* @version V1.0
* @Date 2017年11月30日 下午2:22:35
* @Email
* @Description: 桥接模式-新司机类
*/
public class NewDriver extends Driver {
public NewDriver() {
// TODO Auto-generated constructor stub
}
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println("新手开车喽~~,>>>>" + this.getCar().run());
}
}
老司机
/**
* @author
* @version V1.0
* @Date 2017年11月30日 下午2:29:21
* @Email
* @Description: 老司机类
*/
public class OldDriver extends Driver {
public OldDriver() {
// TODO Auto-generated constructor stub
}
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println("老司机发车喽!! >>>>>" + this.getCar().run());
}
}
④具体实现化角色
奔驰
/**
* @author
* @version V1.0
* @Date 2017年11月30日 下午2:33:41
* @Email
* @Description: 奔驰
*/
public class Benz extends Car {
@Override
public String run() {
// TODO Auto-generated method stub
return "Benz Go-->>>>";
}
}
/**
* @author
* @version V1.0
* @Date 2017年11月30日 下午2:36:24
* @Email
* @Description: TODO(用一句话描述该文件做什么)
*/
public class BridgeTest {
public static void main(String[] args) {
Benz benz = new Benz();
Audi audi = new Audi();
/*新司机*/
Driver newBird = new NewDriver();
/*老司机*/
Driver oldBird = new OldDriver();
newBird.setCar(audi);
oldBird.setCar(benz);
newBird.drive();
oldBird.drive();
}
}
故事三、猪八戒的故事
二师兄的故事
一张图说清楚二师兄的前世今生!
【适用场景】
- 适合使用在需要跨越多个平台的图形和窗口系统上。
- 当需要用不同的方式改变接口和实现时,你会发现桥接模式很好用。
【优点】
- 将实现予以解耦,让它和界面之间不再永久绑定。
- 抽象和实现可以独立扩展,不会影响到对方。
- 对于 具体的抽象类 所做的改变,不会影响到客户。
【缺点】
- 缺点是增加了复杂度
【桥梁模式在Java中的应用】
能用图片说明白的事情,绝不BB。
【结束】
小和尚镇楼