一、桥接模式(结构型模式)
1.定义
桥接模式(Bridge Pattern)是将它的抽象部分和实现部分分离,使它们可以独立变化。
2.桥接模式角色
**(1).抽象化(Abstraction)角色:**定义抽象类,并包含一个对实现化对象的引用。
**(2).扩展抽象化(Refined Abstraction)角色:**是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
**(3).实现化(Implementor)角色:**定义实现化角色的接口,供扩展抽象化角色调用。
**(4).具体实现化(Concrete Implementor)角色:**给出实现化角色接口的具体实现。
3.代码实现方式
(1).根据一个维度创建一个实现化角色,定义业务方法。
(2).创建具体实现化角色实现实现化角色,重写业务方法。
(3).根据一个维度创建一个抽象类,定义需要实现的业务方法,组合依赖实现化角色,构造器注入。
(4).创建抽象类的子类实现抽象类,重写业务方法,这里业务方法中调用组合的实现化角色的方法。
4.代码实现
(1).场景
比如啊,描述一辆汽车可以从品牌啊,颜色啊,车型啊等等各个方面描述,这个就存在了多个维度了。
(2).具体代码
package com.tw.designPattern.bridge.car;
/**
* 车身颜色 实现化角色
*/
public interface Color {
String color();
}
package com.tw.designPattern.bridge.car;
/**
* 红色 具体实现化角色
*/
public class Red implements Color {
@Override
public String color() {
return "红色的";
}
}
package com.tw.designPattern.bridge.car;
/**
* 黑色 具体实现化角色
*/
public class Black implements Color {
@Override
public String color() {
return "黑色的";
}
}
package com.tw.designPattern.bridge.car;
/**
* 车 抽象化角色
*/
public abstract class Car {
protected Color color;
public Car(Color color){
this.color = color;
}
abstract String desc();
}
package com.tw.designPattern.bridge.car;
/**
* 宝马车 扩展抽象化角色
*/
public class BMWCar extends Car {
BMWCar(Color color){
super(color);
}
@Override
public String desc() {
return this.color.color() + "宝马车";
}
}
package com.tw.designPattern.bridge.car;
/**
* 奔驰车 扩展抽象化角色
*/
public class BenzCar extends Car{
public BenzCar(Color color) {
super(color);
}
@Override
public String desc() {
return this.color.color() + "奔驰车";
}
}
package com.tw.designPattern.bridge.car;
public class CarTest {
public static void main(String[] args) {
BMWCar bmwCar = new BMWCar(new Red());
String redBMW = bmwCar.desc();
System.out.println(redBMW);
BenzCar benzCar = new BenzCar(new Black());
String blackBenz = benzCar.desc();
System.out.println(blackBenz);
}
}
测试结果
红色的宝马车
黑色的奔驰车
我感觉这个和装饰者模式有点像,说一下我感觉的区别吧。简单说一下啊,比如顶层接口是A啊(就相当于这里面的Car),然后装饰者模式不得给A装饰么,这里的Color类就相当于装饰者(用B表示吧,后面好写一点),在这里它是实现化角色,区别就在这里了啊,装饰者里面是B实现A,是不是说明这里的B就是A,A变了,B你也得跟着变,这就不可以独立变化了,然后通过构造器注入,就实现了构造函数无限嵌套,而桥接模式了,这里是组合依赖了B,A变了也不管我B的事,我B变了也不管了A的事,A只是引用B想使用B的东西,只是从B那拿,而A变化跟B完全没关系,我又不靠你A啥。还有啊这两模式用意也不同,装饰器是为了增强类功能,而桥接是为了抽象和实现独立变化,避免通过继承的那种方式会出现很多类。我感觉就是这样的区别吧。
下面给画个图看看继承方式和组合方式类的个数,画图工具画的有点糙,将就着看吧。
5.我的思考
(1).场景
如果有这么个场景,描述车超过两个维度了怎么搞了,比如车品牌、颜色、车型、功率等等这就四个维度了,我不想全部维度描述这辆车,比我宝马车,我只想说红色的宝马,奔驰车我想说黑色的奔驰Suv,或者说红色的2.5t的奔驰Suv,这样怎么实现独立变化了?下面写一下我的代码实现,通过方法重载来实现,不过不符合开闭原则,如果兄弟姐妹们看到这有好的想法,欢迎分享一下啊。
(2).代码实现
package com.tw.designPattern.bridge.car;
/**
* 车身颜色 实现化角色
*/
public interface Color {
String color();
}
package com.tw.designPattern.bridge.car;
/**
* 红色 具体实现化角色
*/
public class Red implements Color {
@Override
public String color() {
return "红色的";
}
}
package com.tw.designPattern.bridge.car;
/**
* 黑色 具体实现化角色
*/
public class Black implements Color {
@Override
public String color() {
return "黑色的";
}
}
package com.tw.designPattern.bridge.car;
/**
* 车型 实现化角色
*/
public interface Model {
String modelDesc();
}
package com.tw.designPattern.bridge.car;
/**
* 轿车 具体实现化角色
*/
public class Limousine implements Model{
@Override
public String modelDesc() {
return "轿车";
}
}
package com.tw.designPattern.bridge.car;
public class Suv implements Model{
@Override
public String modelDesc() {
return "SUV";
}
}
package com.tw.designPattern.bridge.car;
/**
* 车 抽象化角色
*/
public abstract class Car {
abstract String desc(Color color);
abstract String desc(Color color,Model model);
}
package com.tw.designPattern.bridge.car;
/**
* 宝马车 扩展抽象化角色
*/
public class BMWCar extends Car {
@Override
public String desc(Color color) {
return color.color() + "宝马";
}
@Override
String desc(Color color, Model model) {
return color.color() + "宝马" + model.modelDesc();
}
}
package com.tw.designPattern.bridge.car;
/**
* 奔驰车 扩展抽象化角色
*/
public class BenzCar extends Car{
@Override
public String desc(Color color) {
return color.color() + "奔驰";
}
@Override
String desc(Color color, Model model) {
return color.color() + "奔驰" + model.modelDesc();
}
}
package com.tw.designPattern.bridge.car;
public class CarTest {
public static void main(String[] args) {
Color red = new Red();
Color black = new Black();
BMWCar bmwCar = new BMWCar();
String redBMW = bmwCar.desc(red);
System.out.println(redBMW);
BenzCar benzCar = new BenzCar();
String blackBenz = benzCar.desc(black);
System.out.println(blackBenz);
System.out.println("-----------------------------------");
Limousine limousine = new Limousine();
Suv suv = new Suv();
String redBmwLim = bmwCar.desc(red, limousine);
System.out.println(redBmwLim);
String blackBenzSuv = benzCar.desc(black, suv);
System.out.println(blackBenzSuv);
}
}
测试结果
红色的宝马
黑色的奔驰
-----------------------------------
红色的宝马轿车
黑色的奔驰SUV
这里是通过方法的重载来实现的,也可以实现了抽象与实现可以独立变化,如果再多维度的话,你就加实现化角色,然后重载方法就可以了,我就不知道这是不是还属于桥接模式,如果大家有其他想法,欢迎分享交流,谢谢。
6.优缺点
(1).优点
(1-1).抽象和实现分离,扩展能力好。
(1-2).符合开闭原则(如果只是两个维度的话)。
(1-3).通过组合而不是继承,符合合成复用原则。
(2).缺点
(2-1).由于聚合(组合)关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度。
7.应用场景
(1).当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
(2).当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
(3).当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。
注:内容参考网络上各种资料,还有一些本人的理解和思想,仅为了学习记录和分享一下自己所学之处,如有不足的地方麻烦大牛指出,如有侵权的地方,请联系删除,谢谢