乐趣区

关于设计模式:设计模式学习笔记十桥接模式

1 定义

桥接模式:将形象局部与其实现局部拆散,使它们都能够独立地变动。
它是一种对象结构型模式,又称为柄体模式或者接口模式。

2 概述

桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变动的维度,通过该模式能够将这两个维度分离出来,使两者能够独立扩大,让零碎变得更加合乎 SRP。

比方,设计一个跨平台的图像浏览零碎,反对的图片格式包含:

  • PNG
  • BMP
  • JPG
  • GIF

等等,而反对的零碎包含:

  • Windows
  • Unix
  • Linux

等等,这样,零碎与图片格式就是两个不同的维度,能够利用桥接模式将这两个维度拆散,使得它们能够独立变动,减少新的图片格式或者新的零碎时,都不会对另一个维度造成任何影响。

3 角色

  • Abstraction(抽象类):用于定义抽象类的接口,个别是抽象类而不是接口,具备一个 Implementor 的成员,与 Implementor 为关联关系,既能够蕴含形象的业务办法,也能够蕴含具体业务办法
  • RefinedAbstraction(裁减抽象类):裁减由 Abstraction 定义的接口,通常为具体类,实现了在 Abstraction 中的形象业务办法,同时能够调用 Implementor 中的业务办法
  • Implementor(实现类接口):实现类的接口,相比起 Abstractoin 提供的更多更简单的操作,Implementor个别只提供基本操作,具体实现交由子类解决
  • ConcreteImplementor(具体实现类):具体实现 Implementor 接口,不同的 ConcreteImplementor 提供不同实现的基本操作

结构图如下:

4 步骤

  • 辨认维度:首先辨认出零碎中两个独立变动的维度
  • 继承:辨认出维度后,将它们设计为两个独立的继承等级构造,比方下面的图片格式以及零碎,将图片格式与零碎设为形象层,而 BMP,GIF 等继承图片格式形象层,Windows 等具体系统集成零碎形象层
  • 建设形象耦合:在形象层建设一个形象关联
  • 扩大:建设形象耦合后,依据须要对两个维度进行独立扩大,比方减少新的图片格式 WBEP,减少新的操作系统 Mac 等

5 实例

跨平台的图片浏览零碎,反对的图片格式包含 PNG,JPG,BMP,GIF 等,反对的零碎包含 Linux,Unix,Windows 等,应用桥接模式设计。

  • 图片维度:抽象类 Image,BMP,GIF 等继承ImageImage 具备一个 ImageShow 的成员变量
  • 零碎维度:Linux,Unix,Windows 实现图片显示接口ImageShow

代码如下:

public class Test
{public static void main(String[] args) {Image image = new GIF();
        image.setImageShow(new Linux());
        image.show();}
}

//Image 抽象类
abstract class Image
{
    protected ImageShow imageShow;
    public void setImageShow(ImageShow imageShow)
    {this.imageShow = imageShow;}
    public abstract show();}

class BMP extends Image
{
    @Override
    public void show()
    {imageShow.show("BMP");
    }
}

class GIF extends Image
{
    @Override
    public void show()
    {imageShow.show("GIF");
    }
}

class PNG extends Image
{
    @Override
    public void show()
    {imageShow.show("PNG");
    }
}

class JPG extends Image
{
    @Override
    public void show()
    {imageShow.show("JPG");
    }
}

// 图片显示接口
interface ImageShow
{void show(String name);
}

class Windows implements ImageShow
{
    @Override
    public void show(String name)
    {System.out.println("Windows show"+name);
    }
}

class Linux implements ImageShow
{
    @Override
    public void show(String name)
    {System.out.println("Linux show"+name);
    }
}

class Unix implements ImageShow
{
    @Override
    public void show(String name)
    {System.out.println("Unix show"+name);
    }
}

更换图片格式只须要批改 Image 的父类:

Image image = new GIF();
Image image = new BMP();
Image image = new JPG();
Image image = new PNG();

而更换操作系统只须要批改传入 setter 的参数:

image.setImageShow(new Linux());
image.setImageShow(new Windows());
image.setImageShow(new Unix());

这样就能够把图片以及零碎两个维度拆散,并可能独立扩大,减少新的图片格式,只须要减少一个新的继承 Image 的类即可,减少新的零碎只需实现 ImageShow 接口即可。
因为例子简略应用反射进行简化代码并减少了新的零碎以及图片格式,代码如下:

public class Test
{public static void main(String[] args) {Image image = new WBEP();
        image.setImageShow(new Mac());
        image.show();}
}

abstract class Image
{
    protected ImageShow imageShow;
    public void setImageShow(ImageShow imageShow)
    {this.imageShow = imageShow;}
    public void show()
    {imageShow.show(getClass().getName());
    }
}

class BMP extends Image{}
class GIF extends Image{}
class PNG extends Image{}
class JPG extends Image{}
class WBEP extends Image{}

interface ImageShow
{void show(String name);
}

abstract class ImageSystem implements ImageShow
{public void show(String name)
    {System.out.println(getClass().getName()+"show"+name);
    }
}

class Windows extends ImageSystem{}
class Linux extends ImageSystem{}
class Unix extends ImageSystem{}
class Mac extends ImageSystem{}

6 次要长处

  • 低耦合:拆散形象接口及其实现局部,桥接模式应用“对象间的关联关系”解耦了形象和实现之间固有的绑定关系,使得形象和实现能够依照各自的维度变动。也就是说,形象和实现不再同一个继承档次中,而是让形象作为父类,实现作为子类,这样就能够任意组合子类,从而取得多维度的组合对象
  • 取代多重继承:很多状况下桥接模式能够取代多重继承,多重继承违反了 SRP(繁多权责准则),复用性差,而且类的个数多,桥接模式能够无效缩小子类个数
  • 进步扩展性:桥接模式进步了零碎的扩展性,在两个维度中任意扩大一个维度,都不须要批改原有零碎,合乎开闭准则

7 次要毛病

  • 减少了解难度:桥接模式会减少零碎的了解以及设计难度,因为关联关系建设在形象层,要求开发者一开始就针对形象层进行设计以及编程
  • 须要正确辨认形象层:桥接模式要求正确识别系统中两个独立变动的维度,因而适用范围有肯定局限,正确辨认独立维度须要肯定教训积攒

8 实用场景

  • 如果一个零碎须要在抽象类和具体类之间减少更多的灵活性,防止在两个档次之间建设动态的继承关系,通过桥接模式能够使它们在形象层建设一个关联关系
  • 形象局部和实现局部能够以继承的形式独立扩大而互不影响,在程序运行时能够动静将一个抽象类子类的对象和一个实现类子类的对象进行动静组合
  • 一个类存在两个(或多个)独立变动的维度,且这两个(或多个)维度都须要独立进行扩大
  • 对于不心愿应用继承或因为多重继承导致系统类的个数急剧减少的零碎

9 总结

退出移动版