您的位置:首页 > 其它

关于设计模式的那点小事--桥接《Bridge》模式(1)

2013-08-10 22:26 218 查看
一、DIP 依赖反转原则

    1、在了解何谓桥接模式之前,我们先来看一下经典的面向对象设计原则之一:DIP原则。所谓DIP原则,即Dependency Inversion Principle,用中文解释就是“依赖反转原则”(下面将要介绍的桥接模式就是基于DIP原则设计的)。

    2、在传统的面向过程的程序设计中,模块之间的关系式:

    (1)高层次模块  依赖  低层次模块 (2)抽象模块  依赖  具体模块

    3、这种依赖关系的弊端是: 底层次的、具体的模块,通常是一些逻辑处理或算法实现,这部分的代码是易变的,不稳定。这样产生的后果就是:让一个系统中稳定的部分依赖那些不稳定的部分,那么不稳定部分的改变将影响到整个系统,从而增加整个系统扩展的复杂度;

    4、PS. 用一个通俗的例子解释上面的话:有一家产品公司,老板(高层次、抽象)做的工作应该是什么?是要告诉工人生产什么样的产品。而产品最终具体的生产制作是由工人来完成的。在面向过程的程序设计中讲的问题就是:不管你老板的本意是要做多么多么好的产品,但最终产品出货的样子还是由工人来决定。这就是
高层次模块依赖低层次模块。

    5、因此,”依赖反转原则“的目的就是要解决上面的问题:我们设计的程序要让具体依赖抽象,既要面向接口编程,不要面向实现编程。

     6、这里还要继续不嫌啰嗦的解释下”面向接口编程“:所谓面向接口编程,就是使用java中的”接口“或”抽象类“进行变量的声明,参数的声明,方法的返回类型声明

二、面向接口编程的程序结构图:



1、Implementor(接口):一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系(这种关联关系就是在abstraction抽象类中声明一个该implementor类型的变量,并声明或定义一些方法来维护这个变量,在下面的F1赛车例子中就是那个tire),在Abstraction中不仅拥有自己的方法,还可以调用到Implementor中定义的方法,使用关联关系来替代继承关系

2、Abstraction(抽象类):其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象(这个对象只是一个引用,它将最终指向implementor的具体实现类的一个实例对象),它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。

3、ConcreteImplementor(接口的具体实现类):具体实现Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象(就是传说中的父类引用指向子类对象),提供给抽象类具体的业务操作方法。

4、RefinedAbstraction(抽象类的具体实现类):扩充由Abstraction定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。

三、桥接模式的一个示例:

看过F1的朋友都知道,有时候会出现下雨情况,这时候车队就会给赛车换轮胎。已这个作为示例,演示一下桥接。

1、接口 Implementor

public interface ITire {
void function();
}

2、抽象类 Abstraction
public abstract class F1 {
public ITire tire;

public void setTire(ITire tire){
this.tire = tire;
ForNewTires();
}

public abstract void ForNewTires();
}

3、实现接口的具体类
(1)干胎

public class DryTyres implements ITire {

@Override
public void function() {
// TODO Auto-generated method stub
System.out.println("天气晴朗,使用干胎");
}

}

(2)中性胎
public class IntermediateTyre implements ITire{

@Override
public void function() {
// TODO Auto-generated method stub
System.out.println("刚刚开始下雨,换中性胎");
}

}
(3)雨胎

public class RainTires implements ITire{

@Override
public void function() {
// TODO Auto-generated method stub
System.out.println("雨胎,适合积水较多时使用");
}

} 4、实现抽象类的具体实类
(1)法拉利

/**
*法拉利
*/
public class F10 extends F1 {

@Override
public void ForNewTires() {
// TODO Auto-generated method stub
System.out.println("这是法拉利赛车");
tire.function();
}

} (2)雷诺
/**
*雷诺 R25
*/
public class RenaultR25 extends F1 {

@Override
public void ForNewTires() {
// TODO Auto-generated method stub
System.out.println("这是雷诺赛车");
tire.function();

}

}

5、client
public static void main(String[] args) {
// TODO Auto-generated method stub
//准备好轮胎和赛车
ITire tire = new DryTyres();
ITire tire2 = new IntermediateTyre();
ITire tire3 = new RainTires();
//法拉利的F10
F10 f10 = new F10();
//雷诺的R25
RenaultR25 r25 = new RenaultR25();
System.out.println("--比赛开始天气晴朗--");
f10.setTire(tire);
r25.setTire(tire);
System.out.println("--比赛中开始下雨--");
f10.setTire(tire2);
r25.setTire(tire2);
System.out.println("--比赛中雨越下越大,出现积水--");
f10.setTire(tire3);
r25.setTire(tire3);

}


当然,随着科技的发展,未来轮胎种类可能增多,想要组合,采用桥接模式还是比较方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: