1,定义 :桥梁模式:将抽象部分与它的实现部分分离,使它
们都可以独立地变化。(这里的抽象部分和实现部分是指:对象之间的组合关系,共同完成(实现)抽象部分的功能)
【实现部分、抽象部分: 提供的接口可以完全不一样;
而且实现部分内部、抽象部分: 内部的接口也完全可以不一样;
但是实现部分要提供类似的功能才行】
2, 作用 :
系统设计中,总是充满了各种变数,面对这样那样的变动,只能去
不停的修改、设计、测试代码......
怎么办比较好呢?
分析变化的种类,将不变的框架使用抽象类定义出来,
然后再将变化的内容使用具体的子类来分别实现。
面向客户的只是一个抽象类,这种方式可以较好的避免为抽象类中现有接口添加新的实现所带
来的影响,缩小了变化带来的影响。但是这可能会造成子类数量的爆炸,并且在某些时候不是很灵活。
---->>>当这颗继承树上一些子树存在了类似的行为,它们之间存在了重复的功能代码。
这时我们不妨将这些行为提取出来,也采用接口的方式提供出来,
然后以组合的方式将服务提供给原来的子类。
这样就达到了前端和被使用的后端独立的变化,而且还达到了后端的重用。
优势 :
a, 将可能变化的部分单独封装起来,使得变化产生的影响最小,不用编译不必要的代码。
b, 抽象部分和实现部分可以单独的变动,并且每一部分的扩充都不会破坏原有体系
c, 对于客户程序来说,你的实现细节是透明的。
3,应用举例 :
java AWT 框架:在不同系统下开发的软件界面有不同系统独有的风格,而在使用 AWT 的 API 的
时候根本就没有对不同系统的区分,你也根本就不需要去关心这一点
4,使用环境 :
1) 当你的系统中有多个地方要使用到类似的行为,或者是多个类似行为的组合时
2) 系统中某个类的行为可能会有几种不同的变化趋势
3) 某些行为可能要被众多相近的类使用
类图结构:使用dia软件构造类图
xmind 脑图:
在eclipse上开发:类的概览:
第一层结构:两个抽象产品类(一个量贩型,一个调味型),一个产品调度者(负责产品搭配组合)
/**主要产品对象:
量贩型咖啡:生产大杯,中杯,小杯------持有美味型产品对象调味
*/
public abstract class CapacityCoffee {
//属性:持有的对象
private SuggerCoffee sucoffee;
//构造器:封装此调味产品到--自己的实例对象中
public CapacityCoffee(SuggerCoffee sucoffee){
this.setSucoffee(sucoffee);
}
//定义一般方法: 生产出各种杯型的咖啡
public abstract void pourCoffee();
//set() ,get()
public SuggerCoffee getSucoffee() {
return sucoffee;
}
public void setSucoffee(SuggerCoffee sucoffee) {
this.sucoffee = sucoffee;
}
}
/**次要产品对象:
* 调味型咖啡:生产甜的,不甜的两种产品
*/
public abstract class SuggerCoffee {
//定义一般方法: 生产出各种杯型的咖啡
public abstract void pourCoffee();
}
/**
* 调度者: 管理--调味型咖啡==>
* 保证持有对象的单例,
* 使得程序高效工作
*/
public class Singleton_CoffeeDispatcher {
//持有:调味咖啡对象--管理它
private static SuggerCoffee su;
//构造:接受实际中--不同口味的咖啡
public Singleton_CoffeeDispatcher(SuggerCoffee su){
this.su=su;
}
//返回:一个单例对象
public SuggerCoffee getSingletonSuggerCoffee(){
return this.su;
}
}
第二层结构:两种产品的具体子类
//大杯
public class CapacityCoffee_bigCup extends CapacityCoffee{
public CapacityCoffee_bigCup(SuggerCoffee sucoffee) {
super(sucoffee);
}
@Override
public void pourCoffee() {
System.out.print("大杯+");
this.getSucoffee().pourCoffee();//利用:持有的对象生产大杯+调味的咖啡
}
}
//中杯
public class CapacityCoffee_middleCup extends CapacityCoffee{
public CapacityCoffee_middleCup(SuggerCoffee sucoffee) {
super(sucoffee);
}
@Override
public void pourCoffee() {
System.out.print("中杯 + ");
this.getSucoffee().pourCoffee();//利用:持有的对象生产中杯+调味的咖啡
}
}
//小杯
public class CapacityCoffee_smallCup extends CapacityCoffee{
public CapacityCoffee_smallCup(SuggerCoffee sucoffee) {
super(sucoffee);
}
@Override
public void pourCoffee() {
System.out.print("小杯 + ");
this.getSucoffee().pourCoffee();//利用:持有的对象生产小杯+调味的咖啡
}
}
//原味
public class SuggerCoffee_nosweet extends SuggerCoffee{
@Override
public void pourCoffee() {
System.out.println("原味咖啡");
}
}
//甜的
public class SuggerCoffee_sweet extends SuggerCoffee {
@Override
public void pourCoffee() {
System.out.println("甜的咖啡");
}
}
第三层结构:测试结果
public class Test_bridgeModel {
public static void main(String[] args) {
/**
* 甜味系列--->创建调度者(甜味咖啡)
*/
Singleton_CoffeeDispatcher disp=
new Singleton_CoffeeDispatcher(new SuggerCoffee_sweet());
//可以选择各种杯型
CapacityCoffee_bigCup big=new CapacityCoffee_bigCup(disp.getSingletonSuggerCoffee());
CapacityCoffee_middleCup middle=new CapacityCoffee_middleCup(disp.getSingletonSuggerCoffee());
CapacityCoffee_smallCup small=new CapacityCoffee_smallCup(disp.getSingletonSuggerCoffee());
//查看结果:
big.pourCoffee();//大杯+ 甜的咖啡
middle.pourCoffee();//中杯 + 甜的咖啡
small.pourCoffee();//小杯 + 甜的咖啡
/**
* 原味系列:同理,只是需更换一个调度者-->
* 使其管理(原味咖啡)
*/
}
}