代码改变世界

设计模式之桥接模式

2013-05-10 20:56  youxin  阅读(322)  评论(0)    收藏  举报

  在软件系统中,有些类由于其本身的固有特性,使得它具有两个或多个变化维度,这种变化维度又称为变化原因。对于这种多维度变化的系统,桥接模式提供了一套完整的解决方案,并且降低了系统的复杂性。

模式动机:

 设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下2种解决办法:

1.为每种形状都提供一套各种颜色的版本,如下:

4种形状,3种颜色,我们需要4*3=12个类,简直就是class boom。而且每增加一个形状,我们都要增加3个颜色类增加一种颜色,其他形状都要增加

2.第二种方案是设计4个形状类,3个颜色类,根据需要对形状和颜色进行组合。

需要的类是4+3=7个。在该设计方案中,如果需要增加一种新的形状或新的颜色,只需要增加一个新的形状类和颜色类几口。

很明显,设计方案2要好的多,就是我吗所说的桥接模式,桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

定义:

Decouple an abstraction from its implementation so that the two can vary independently.

将抽象与实现分离,使他们能独立变化。

The classes and/or objects participating in this pattern are:

  • Abstraction   (BusinessObject)
    • defines the abstraction's interface.
    • maintains a reference to an object of type Implementor.
  • RefinedAbstraction   (CustomersBusinessObject)
    • extends the interface defined by Abstraction.
  • Implementor   (DataObject)
    • defines the interface for implementation classes. This interface doesn't have to correspond exactly to Abstraction's interface; in fact the two interfaces can be quite different. Typically the Implementation interface provides only primitive operations, and Abstraction defines higher-level operations based on these primitives.(定义类的实现接口,该接口不一定要与Abstract的接口完全一致,事实上这2个接口可以完全不同,一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。
  • ConcreteImplementor   (CustomersDataObject)
    • implements the Implementor interface and defines its concrete implementation.

 如何理解将抽象和实现分离?

可以这样理解:对一个事物进行抽象,得到了一个行为。 比如对Shape进行抽象,得到了Draw的行为。Draw是在哪里实现的?不是在它抽象而来的类Shape,而是在另外一个类实现的。哪个类呢?Drawing类。

Draw是从Shape抽象出来的行为,但是不在Shape中予以实现。这就是抽象和实现分离。

为什么要这样呢?因为Draw的方法可能不同,比如可以用实线,也可以用虚线。为了更好的隐藏变化,所以将其分离。由于本文不是介绍Bridge模式,不再深入介绍它的好处。

参考:http://www.cnblogs.com/idior/articles/97283.html

桥接模式实例:

现在需要提供大小中3种型号的画笔,能够绘制5种不同的颜色。我们简化这个过程。(代码中型号为大小2中,颜色为Red,Blue,Green3种)。

Color类:

public abstract class Color {
    
    abstract void bepaint(String penType,String name);

}

继承的类:

public class Red extends Color {

    void bepaint(String penType, String name) {
        System.out.println(penType+"  红色的"+name+".");

    }

}
public class Blue extends Color {

    void bepaint(String penType, String name) {
        System.out.println(penType+"蓝色的"+name+".");

    }

}
public class Green extends Color {

    void bepaint(String penType, String name) {
        System.out.println(penType+"绿色的"+name+".");

    }

}

画笔:

public abstract class Pen {
    protected Color color;
    public void setColor(Color color)
    {
        this.color=color;
    }
    public abstract void draw(String name);

}

Pen中有Color类,从而建立了关联。也就是说在Pen及其子类中可以调用在Color接口中定义的方法,在Pen中定义了抽象业务方法draw(),在其子类中将实现该方法。

public class SmallPen extends Pen {

    public void draw(String name) {
        String penType="小号毛笔绘制";
        this.color.bepaint(penType, name);

    }

}

public class LargePen extends Pen {

    public void draw(String name) {
        String penType="大号毛笔绘制";
        this.color.bepaint(penType, name);

    }

}

Main类:

public class Main  {
    public static void main(String[] args)
    {
        Color color=new Red();
        Pen  pen=new SmallPen();
        pen.setColor(color);
        pen.draw("--你好");
        
        pen.setColor(new Blue());
        pen.draw("--你好");
        
        pen=new LargePen();
        pen.setColor(new Red());
        pen.draw("你好");
        
        
   }
}