Design Pattern Explained 读书笔记六——Bridge

what?

“De-couple an abstraction from its implementation so that the two can vary independently.” ——gof

Show me the Code

bridge模式设计:

Design Pattern Explained 读书笔记六——Bridge_第1张图片

package com.bridge;

/** * * 从Factory里获取Shape对象,调用shape对象的draw(). */
public class Client {

    /** * @param args */
    public static void main(String[] args) {

        Shape myShapes[];
        Factory myFactory = new Factory();

        myShapes = myFactory.getShapes();
        for (int i = 0; i < myShapes.length; i++) {
            myShapes[i].draw();
        }
    }

}
package com.bridge;

/** * * @author zs * * 组合 Drawing 对象(构造器方式) * * drawLine方法 实现——Drawing.drawLine(...) * * drawCircle方法 实现——Drawing.drawCircle(...) * */
public abstract class Shape {

    protected Drawing myDrawing;

    abstract public void draw();

    Shape(Drawing drawing) {

        myDrawing = drawing;

    }

    protected void drawLine(double x1, double y1, double x2, double y2) {

        myDrawing.drawLine(x1, y1, x2, y2);

    }

    protected void drawCircle(double x, double y, double r) {

        myDrawing.drawCircle(x, y, r);
    }
}
package com.bridge;

/** * * @author zs * * * 实现Shape.draw(){drawLine} * * override drawLine() * * 继承了 drawCircle() 没有使用 * * */

public class Rectangle extends Shape {
    private double _x1, _y1, _x2, _y2;

    public Rectangle(Drawing dp, double x1, double y1, double x2, double y2) {
        super(dp);
        _x1 = x1;
        _y1 = y1;
        _x2 = x2;
        _y2 = y2;
    }

    public void draw() {
        drawLine(_x1, _y1, _x2, _y1);
        drawLine(_x2, _y1, _x2, _y2);
        drawLine(_x2, _y2, _x1, _y2);
        drawLine(_x1, _y2, _x1, _y1);
    }

    protected void drawLine(double x1, double y1, double x2, double y2) {
        myDrawing.drawLine(x1, y1, x2, y2);
    }

}
package com.bridge;

/** * @author zs * * 实现Shape.draw(){drawCircle} * * override drawLine() * * 继承了 drawLine() 没有使用 */

public class Circle extends Shape {
    private double _x, _y, _r;

    public Circle(Drawing dp, double x, double y, double r) {
        super(dp);
        x = x;
        _y = y;
        _r = r;
    }

    public void draw() {
        myDrawing.drawCircle(_x, _y, _r);
    }
}
package com.bridge;

/** * * @author zs * * shape中使用的"实现"——抽象分离出 Drawing.java */

abstract public class Drawing {
    abstract public void drawLine(double x1, double y1, double x2, double y2);

    abstract public void drawCircle(double x, double y, double r);
}
package com.bridge;

public class V1Drawing extends Drawing {
    public void drawLine(double x1, double y1, double x2, double y2) {
        DP1.draw_a_line(x1, y1, x2, y2);
    }

    public void drawCircle(double x, double y, double r) {
        DP1.draw_a_circle(x, y, r);
    }
}
package com.bridge;

/** * * @author zs * * V1实现 */
public class V1Drawing extends Drawing {
    public void drawLine(double x1, double y1, double x2, double y2) {
        DP1.draw_a_line(x1, y1, x2, y2);
    }

    public void drawCircle(double x, double y, double r) {
        DP1.draw_a_circle(x, y, r);
    }
}
package com.bridge;

/** * * @author zs * * V2实现 */
public class V2Drawing extends Drawing {
    public void drawLine(double x1, double y1, double x2, double y2) {
        // arguments are different in DP2
        // and must be rearranged
        DP2.drawLine(x1, x2, y1, y2);
    }

    public void drawCircle(double x, double y, double r) {
        DP2.drawCircle(x, y, r);
    }
}

The Bridge Pattern: 关键特征

  • Intent

Decouple a set of implementations from the set of objects using them.

**一组实现(Circle、Rectangle) 与 这组实现中使用的一组对象 分离开来
(分离后:V2Drawing extends Drawing、V1Drawing extends Drawing)。**

  • Problem
    The derivations of an abstract class must use multiple implementations
    without causing an explosion in the number of classes.

    ——>

    …更多的实现

传统继承模式会导致:因为具体Shape实现的不同而需要有多个派生类。(原因就是把Draw实现耦合到Shape中,没有抽象出来)

  • Solution
    Define an interface for all implementations to use and have the deriva-
    tions of the abstract class use that.
    解决上述场景的方法就是 抽象出”绘图逻辑“,并在Shape的实现类中组合。

  • Participants and Collaborators
    The Abstraction defines the interface for the objects being
    implemented. The Implementor defines the interface for the specific implementation classes. Classes derived from the Abstraction use
    classes derived from the Implementor without knowing which particular ConcreteImplementor is in use.

Abstraction(Shape.java) 定义了对象的实现接口。Implementor(Drawing.java)为具体的实现(如,图形的具体绘制)定义接口。 Rectangle、Circle 实现Shape接口,并用组合方式使用 Drawing.java里Drawing.drawLine()或drawCircle(draw()里使,用.drawLine()或drawCircle),对外暴漏出draw(),根本不用关系是使用了drawLine()或drawCircle)。

  • Consequences
    The decoupling of the implementations from the objects that use them increases extensibility. Client objects are not aware of implementation issues.

    把具体的draw…从Shape里解耦出来,客户端只需要调用具体的Shape实现,不关心Shape实现的具体绘制方法(drawCircle…、drawLine…)

  • Implementation

1 Encapsulate the implementations in an abstract class.
封装 实现(抽象化)
2 Contain a handle to it in the base class of the abstraction being implemented.

Design Pattern Explained 读书笔记六——Bridge_第2张图片

Note: In Java, you can use interfaces instead of an abstract class for the
implementation.

在设计以应对变化时,遵循两条原则:

1.找出变化并封装
2.优先使用对象聚集(组合),而非继承。

bridge的不足:

如果出现新的绘图模式,比如新的绘制方法,需要修改Drawing以及它的实现类,但修改内容也是很明确的。

bridge模式中总结出的面向对象设计原则:

对象为自己负责: Shape的实现类中都能够自己绘制自己(draw())。Drawing负责具体的绘制方法。用对象的职责,而不是行为思考问题!
可测试性:传统解决方案需要测试 N(Shape派生种类)*M(Drawing派生种类),Bridge只需要测试 M+N种。
抽象类与封装:略
一个逻辑,实现一次:略

你可能感兴趣的:(设计模式,对象,设计,bridge)