您的位置:首页 > Web前端 > JavaScript

JS设计模式三:桥接模式

2017-04-20 23:27 309 查看
JS设计模式三:桥接模式
2013-12-25 11:56:46

分类: JavaScript

桥接模式

    桥接模式是软件设计模式中最复杂的设计模式之一。需要将事物的对象和具体的行为,具体特征分离开来,使其可以各自独立的变化。桥接模式则在中间起类似于总调控的作用。

    事物对象是一个较为抽象的概念,如‘圆形’,‘三角形’归于抽象的‘形状’之下,‘画圆形’和‘画三角形’则归于具体行为的‘画图’之下,然后‘形状’这个抽象可以调用‘画图’行为方法。

    具体代码示例(来自维基百科):

    下语言的代码用于写出两个不同的圆的坐标和半径。

API1.circle at 1:2 7.5
API2.circle at 5:7 27.5


/** "Implementor" */

interface DrawingAPI

{

    public
void drawCircle(double x,
double y,
double radius);

}

 

/** "ConcreteImplementor" 1/2 */

class DrawingAPI1
implements DrawingAPI

{

   public
void drawCircle(double x,
double y,
double radius)

   {

        System.out.printf("API1.circle
at %f:%f radius %f\n", x, y,
radius);

   }

}

 

/** "ConcreteImplementor" 2/2 */

class DrawingAPI2
implements DrawingAPI

{

   public
void drawCircle(double x,
double y,
double radius)

   {

        System.out.printf("API2.circle
at %f:%f radius %f\n", x, y,
radius);

   }

}

 

/** "Abstraction" */

interface
Shape

{

   public
void
draw();
// low-level

   public
void resizeByPercentage(double pct);
// high-level

}

 

/** "Refined Abstraction" */

class CircleShape
implements
Shape

{

   private
double x, y,
radius;

   private DrawingAPI drawingAPI;

   public CircleShape(double
x,
double y,
double radius, DrawingAPI drawingAPI)

   {

       this.x
= x;
this.y
= y;
this.radius
= radius;

       this.drawingAPI
= drawingAPI;

   }

 

   // low-level i.e. Implementation specific

   public
void
draw()

   {

        drawingAPI.drawCircle(x,
y, radius);

   }

   // high-level i.e. Abstraction specific

   public
void resizeByPercentage(double pct)

   {

        radius *= pct;

   }

}

 

/** "Client" */

class BridgePattern
{

   public
static
void main(String[]
args)

   {

       Shape[] shapes
=
new Shape[2];

       shapes[0]
=
new CircleShape(1, 2,
3,
new DrawingAPI1());

       shapes[1]
=
new CircleShape(5, 7,
11,
new DrawingAPI2());

 

       for
(Shape
shape
: shapes)

       {

           shape.resizeByPercentage(2.5);

           shape.draw();

       }

   }

}

JS中的桥接模式

    简单的桥接模式,无非就是在设计API的时候可以弱化对象间(对象与类)的耦合程度。

function sendInfo( element
){

    var
id
= element.id;

    ajax(
"GET","info.json?id="+id,
function( result
){

         ...

    });

     ...

}

     然后我们在很多地方或者事件中使用了sendInfo的方法,但是很明显该方法内部的 ajax 请求和整体的实现“性质”不太一样,那么将 ajax 请求方法独立出来,创建一个桥接与 ajax 和 回调函数以及其他代码运行的函数,就可以使整体的结构更加清晰合理,降低原有函数内部方法之间调用的耦合度。

    那么就需要对他的结构使用最简单的桥接模式的处理下

function sendInfo( element
){

    var
id
= element.id,

    callback =
function( result
){

      // ...

    }

    sendInfoBridge( id, callback);

   // ...

}

function sendInfoBridge( id, callback){

    ajax(
"GET","info.json?id="+id,
function( result
){

        callback( result
);

    });

    // ...

}

    那么简单的处理后 从结构上来说变得更为清晰,使得 sendInfo 中的部分方法脱离出来形成独立的方法。此处桥接可以看为 ajax 请求 与 id,callback 等的桥接。

桥接模式联结多个类

var Class1
=
function( a, b,
c ){

    this.a
= a;

    this.bc
= b*c;

}

var Class2
=
function( d
){

    this.d
= d;

}

function BridgeClass(a,
b, c, d){

    this.class1
=
new Class1(a, b,
c);

    this.class2
=
new Class2(d);

}

    但是 在此的作用并没有降低耦合度什么的,反而使新创建的构造函数依赖于之前的构造函数 Class1 和 Class2,超级类似于门面模式?

    其实还是因为这里的实例太过于简单,简单来说,Class1 和 Class2 就是两个“性质”不一样的类,相当于最上面 维基百科 代码示例中的 shape 和 DrawingAPI, 而
BridgeClass 是将两个类联结在一起,使得 shape 可以调用 DrawingAPI 的中间桥接。也不用认为是依赖于之前的构造函数 Class1 和 Class2 因为本身就是实现两者,视为两代码从主程序中独立出来而并非依赖。

    该方式与适配器模式和门面模式(外观模式)都有点相似,不过

        与适配器模式不同之处 : 没有要求客户提供适配的数据。可以视为一种包装器,对接口进行适配以保证不同环境中兼容。

        与门面模式不同之处 : 门面模式仅仅是提供一个简化的接口供客户使用,提供一个高级接口使得子系统更容易使用。而桥接模式中 Class1
和 Class2 是能独立于 BridgeClass 发生改变的,门面模式却不同。

    在很多时候,我们会发现可能一些代码构建的太不合理,过于复杂,明明有更简单的方式来处理逻辑。但是也许是我们没有看到这样的处理方式代码的整体的影响。在此不举一些很复杂的例子,因为往往复杂的牛逼哄哄的例子往往都没啥心情学习与了解。

参考资料:

    1. 维基百科-桥接模式  http://zh.wikipedia.org/wiki/%E6%A9%8B%E6%8E%A5%E6%A8%A1%E5%BC%8F

    2.《JS设计模式》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: