设计模式-结构型之桥接模式

来源:互联网 发布:word 字数统计 mac 编辑:程序博客网 时间:2024/06/06 00:49

模式动机

  假设现在让你设计一个画图软件,要求是可以画出不同形状的图形,如圆形,正方形,长方形,三角形等等,同时这些图形还可以进行上色,比如红色,绿色,黄色等等,最终得到一个带有颜色的图形。此时,应该如何设计呢?首先,第一种方案是为每一种形状都提供一套各种颜色的版本,通过继承来实现,定义一个抽象图形类Shape,然后所有具体图形类如正方形(Square),圆形(Circle)继承于Shape,然后继续继承,定义出各种带颜色的图形如RedSquare,GreenSquare,RedCircle,GreenCircle等等。结构如下图:
  设计1
  以上确实是一种解决方案,但试想一下,如果我们有m种图形,有n种颜色,那我们将便会有m×n个子类,毫无疑问,这样的设计比较欠妥。此时,对于这种有两个维度变化的情况,我们应当考虑桥接模式。

模式定义

  将抽象部分与它的实现部分分离,使它们都可以独立地变化。桥接模式将继承关系转换为关联关系,从而降低类与类之间的耦合,减少了代码量。
  对于上面的那种情况,我们可以把图形和颜色剥离成两个维度,根据实际需要对形状和颜色这两个维度进行组合,这样不仅可以大大减少代码量,而且还可以相互独立,提高可扩展性和可维护性。如下图:
  设计2

模式结构

模式结构
  抽象类:Abstraction
  扩展实现类:RefinedAbstraction
  实现类接口:Implementor
  具体实现类: ConcreteImplementor

代码示例

  下面通过代码来看看桥接模式的具体实现。

//颜色接口,相当于模式结构中的Implementorpublic interface Color {    public abstract String paint();}
//具体颜色类-绿色,相当于模式结构图中的ConcreteImplementorpublic class Green implements Color{    @Override    public String paint() {        return "绿色";    }}
//具体颜色类-红色,相当于模式结构图中的ConcreteImplementorpublic class Red implements Color{    @Override    public String paint() {        return "红色";    }}
//抽象形状类,相当于模式结构图中的Abstractionpublic abstract class Shape {    protected Color color;    public void setColor(Color color){        this.color = color;    }    public abstract void draw();}
//具体形状类-圆形,相当于模式结构中的RefinedAbstractionpublic class Circle extends Shape{    @Override    public void draw() {        System.out.println(this.color.paint() + "圆形");    }}
//具体形状类-正方形,相当于模式结构中的RefinedAbstractionpublic class Square extends Shape{    @Override    public void draw() {        System.out.println(this.color.paint() + "正方形");    }}
/客户端public class Client {    public static void main(String[] args) {        Color green = new Green();        Color red = new Red();        Shape square = new Square();        Shape circle = new Circle();        square.setColor(green);        square.draw();//绿色正方形        square.setColor(red);        square.draw();//红色正方形        circle.setColor(green);        circle.draw();//绿色圆形        circle.setColor(red);        circle.draw();//红色圆形    }}

  可以看到,使用桥接模式大大减少了代码量。主要是因为这里使用的是组合关系,把Color作为Shape的一部分,而不是第一种设计方案中的继承。桥接模式的精髓就在于降低抽象化与实现化耦合关系,在抽象化和实现化之间使用关联关系(组合或者聚合)而不是继承关系,从而使两者可以相对独立。

0 0