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

来源:互联网 发布:淘宝网广场舞长裤套装 编辑:程序博客网 时间:2024/05/18 17:23


一、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);             }


当然,随着科技的发展,未来轮胎种类可能增多,想要组合,采用桥接模式还是比较方便。







原创粉丝点击