赞
踩
[把你的理性思维慢慢变成条件反射]
本文,我们讲介绍桥接模式,文章主题结构与上文一致。惯例,先来看看我们示例工程的环境:
操作系统:win7 x64
其他软件:eclipse mars,jdk8
-------------------------------------------------------------------------------------------------------------------------------------
驱动程序,机械硬件基础与软件应用紧耦合的产品(如:Window版的应用,IOS版的应用)
要点一:基础平台与软件应用过度耦合导致相同功能重复造轮子。
要点二:在软件实现中, 过度使用继承关系,导致子类对象严重受限于父类。
创建Platfrom.java文件,具体内容如下:
- package com.yonyou.iuap.gof_Bridge;
-
- public class Platform {
- public void software(){
- System.out.println(" software run ...");
- }
- }
创建Window.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge;
-
- public class Window {
- public static void main(String[] args) {
- Platform pf = new Platform();
- pf.software();
- }
- }
这里为说明问题,我们将方法主类命名为Platform,各位看官需记得此处的software()方法还需要在多个地方使用。
创建PlatformA.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.one;
-
- public class PlatformA extends Software{
- @Override
- public void softwareA(){
- System.out.println("PlatformA softwareA run ...");
- }
- }
创建PlatformB.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.one;
-
- public class PlatformB extends Software{
- @Override
- public void softwareA(){
- System.out.println("PlatformB softwareA run ...");
- }
- }
创建Software.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.one;
-
- public class Software {
- public void softwareA() {
- }
- }
创建Window.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.one;
-
- public class Window {
- public static void main(String[] args) {
- PlatformA pfa = new PlatformA();
- pfa.softwareA();
- PlatformB pfb = new PlatformB();
- pfb.softwareA();
- }
- }
第二种写法虽然进行了一定程度上的抽象,但是,做一种假设,该software需要在很多类当中进行使用。这将导致继承数量极度增长。最后,所有的platform都受制于software单继承。(Platform数量xsoftware数量=需要维护的类的总数量)
创建Abstraction.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.thire;
-
- public class Abstraction {
- protected Implementor implementor;
-
- public void setImplementor(Implementor implementor){
- this.implementor = implementor;
- }
- public void operation(){
- implementor.operation();
- }
- }
创建ConcreteImplementorA.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.thire;
-
- public class ConcreteImplementorA extends Implementor{
-
- @Override
- public void operation() {
- // TODO Auto-generated method stub
- System.out.println("ImplementorA run");
- }
- }
创建ConcreteImplementorB.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.thire;
-
- public class ConcreteImplementorB extends Implementor{
-
- @Override
- public void operation() {
- // TODO Auto-generated method stub
- System.out.println("ImplementorB run");
- }
- }
创建Implementor.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.thire;
-
- public abstract class Implementor {
- public abstract void operation();
- }
创建RefinedAbstraction.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.thire;
-
- public class RefinedAbstraction extends Abstraction{
- @Override
- public void operation(){
- implementor.operation();
- }
- }
创建Window.java文件,具体内容如下:
- package com.csdn.ingo.gof_Bridge.thire;
-
- public class Window {
- public static void main(String[] args) {
- Abstraction ab = new RefinedAbstraction();
- ab.setImplementor(new ConcreteImplementorA());
- ab.operation();
-
- ab.setImplementor(new ConcreteImplementorB());
- ab.operation();
- }
- }
桥接模式结构图:
将抽象部分与它的实现部分分离,使它们都可以独立的变化。
之所以称为桥接模式,是因为软件中存在两个独立变化的维度,通过该模式可以将这两个维度分离开来,各自维护,使得系统更加符合“单一职责原则”。并且,在两个维度的抽象层上,建立一个关联关系,这个关联关系类似一条连接双方的桥。故称为桥接模式。
Abstraction(抽象类):用于定义抽象类的接口,一般情况下是抽象类,而不是接口。其中,需要定义一个Implementor(实现类接口)类型的对象,并且负责该对象的维护,Abstraction与Implementor存在着关联关系。其中既可以有抽象方法,也可以有具体方法。
RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,通常情况下它是一个具体的类,实现了Abstraction定义的抽象方法,并且RefinedAbstraction也可以调用Implementor中定义的业务方法。
Implementor(实现类接口):定义实现类的接口,该接口不需要与Abstraction保持一致,其内容甚至可以完全不相同。一般情况下,Implementor提供了基本操作,而Abstraction定义复杂操作。Implementor负责声明,ConcreteImplementor负责实现。最后,通过关联关系,Abstraction同事拥有复杂操作与基本操作。由此,由关联关系取代继承关系。
ConcreteImplementor(具体实现类):具体实现Implementor中定义的接口方法,具体实现视需求而定。
【以下内容来自其他博文,具体请参考末尾】
在软件开发中,适配器模式通常可以与桥接模式联合使用。适配器模式可以解决两个已有接口间不兼容问题,在这种情况下被适配的类往往是一个黑盒子,有时候我们不想也不能改变这个被适配的类,也不能控制其扩展。适配器模式通常用于现有系统与第三方产品功能的集成,采用增加适配器的方式将第三方类集成到系统中。桥接模式则不同,用户可以通过接口继承或类继承的方式来对系统进行扩展。
桥接模式和适配器模式用于设计的不同阶段,桥接模式用于系统的初步设计,对于存在两个独立变化维度的类可以将其分为抽象化和实现化两个角色,使它们可以分别进行变化;而在初步设计完成之后,当发现系统与已有类无法协同工作时,可以采用适配器模式。但有时候在设计初期也需要考虑适配器模式,特别是那些涉及到大量第三方应用接口的情况。
下面通过一个实例来说明适配器模式和桥接模式的联合使用:
在某系统的报表处理模块中,需要将报表显示和数据采集分开,系统可以有多种报表显示方式也可以有多种数据采集方式,如可以从文本文件中读取数据,也可以从数据库中读取数据,还可以从Excel文件中获取数据。如果需要从Excel文件中获取数据,则需要调用与Excel相关的API,而这个API是现有系统所不具备的,该API由厂商提供。使用适配器模式和桥接模式设计该模块。
在设计过程中,由于存在报表显示和数据采集两个独立变化的维度,因此可以使用桥接模式进行初步设计;为了使用Excel相关的API来进行数据采集则需要使用适配器模式。系统的完整设计中需要将两个模式联用,如图所示:
-------------------------------------------------------------------------------------------------------------------------------------
至此,被说了很多遍的设计模式---桥接模式 结束
参考资料:
图书:《大话设计模式》
其他博文:http://blog.csdn.NET/lovelion/article/details/7563445
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。