java 桥梁模式_Java设计模式——桥梁模式

24683845_1.gif

几个月后,已经有了大量的DedUser,此时客户提出了一个新的更改。为了能拨国际电话号码、信用卡电话、PIN标识电话等等,必修对现有dial中使用char[10]存储号码改为能够拨打任意长度的电话号码。

显然,所有的调制解调器客户程序都必须更改。客户同意了对调制解调器客户程序的更改,因为他们别无选择。糟糕的是,现在必须要去告诉DedUser的编写者,他们必须要更改他们的代码!你可以想象他们听到这个会有多高兴。本来他们是不用调用dial的。

这就是许多项目都会具有的那种有害的混乱依赖关系。系统某一部分中的一个杂凑体(kludge)创建了一个有害的依赖关系,最终导致系统中完全无关的部分出现问题。

如果使用ADAPTER模式解决最初的问题的话,就可以避免这个严重问题。如图:

24683845_2.gif

BRIDGE模式

看待这个问题,还有另外一个方式。现在,出现了另外一种切分Modem层次结构的方式。如下图:

24683845_3.gif

这不是一个理想的结构。每当增加一款新硬件时,就必须创建两个新类--一个针对专用的情况,一个针对拨号的情况。每当增加一种新连接类型时,就必须创建3个新类,分别对应3款不同的硬件。如果这两个自由度根本就是不稳定的,那么不用多久,就会出现大量的派生类。

在类型层次结构具有多个自由度的情况中,BRIDGE模式通常是有用的。我们可以把这些层次结构分开并通过桥把它们结合到一起,而不是把它们合并起来。如图:

24683845_4.gif

我们把调制解调器类层次结构分成两个层次结构。一个表示连接方法,另一个表示硬件。

这个结构虽然复杂,但是很有趣。它的创建不会影响到调制解调器的使用者,并且还完全分离了连接策略和硬件实现。ModemConnectController的每个派生类代表了一个新的连接策略。在这个策略的实现中可以使用sendlmp、receivelmp、diallmp和hanglmp。新imp方法的增加不会影响到使用者。可以使用ISP来给连接控制类增加新的接口。这种做法可以创建出一条迁移路径,调制解调器的客户程序可以沿着这条路径慢慢地得到一个比dial和hangup层次更高的API。

5. 另外一个实际应用Bridge模式的例子

该例子演示了业务对象(BusinessObject)通过Bridge模式与数据对象(DataObject)解耦。数据对象的实现可以在不改变客户端代码的情况下动态进行更换。

//  Bridge pattern -- Real World example

using  System;

using  System.Collections;

//  "Abstraction"

classBusinessObject

{

//  Fields

privateDataObject dataObject;

protectedstring  group;

//  Constructors

publicBusinessObject(  string  group )

{

this.group  =  group;

}

//  Properties

publicDataObject DataObject

{

set  { dataObject  =  value; }

get  {returndataObject; }

}

//  Methods

virtualpublicvoidNext()

{ dataObject.NextRecord(); }

virtualpublicvoidPrior()

{ dataObject.PriorRecord(); }

virtualpublicvoidNew(  string  name )

{ dataObject.NewRecord( name ); }

virtualpublicvoidDelete(  string  name )

{ dataObject.DeleteRecord( name ); }

virtualpublicvoidShow()

{ dataObject.ShowRecord(); }

virtualpublicvoidShowAll()

{

Console.WriteLine(" Customer Group: {0} ", group );

dataObject.ShowAllRecords();

}

}

//  "RefinedAbstraction"

classCustomersBusinessObject : BusinessObject

{

//  Constructors

publicCustomersBusinessObject(  string  group )

:  base ( group )  {}

//  Methods

overridepublicvoidShowAll()

{

//  Add separator lines

Console.WriteLine();

Console.WriteLine(" ------------------------ ");

base .ShowAll();

Console.WriteLine(" ------------------------ ");

}

}

//  "Implementor"

abstractclassDataObject

{

//  Methods

abstractpublicvoidNextRecord();

abstractpublicvoidPriorRecord();

abstractpublicvoidNewRecord(  string  name );

abstractpublicvoidDeleteRecord(  string  name );

abstractpublicvoidShowRecord();

abstractpublicvoidShowAllRecords();

}

//  "ConcreteImplementor"

classCustomersDataObject : DataObject

{

//  Fields

privateArrayList customers  =newArrayList();

privateintcurrent  =0;

//  Constructors

publicCustomersDataObject()

{

//  Loaded from a database

customers.Add(" Jim Jones ");

customers.Add(" Samual Jackson ");

customers.Add(" Allen Good ");

customers.Add(" Ann Stills ");

customers.Add(" Lisa Giolani ");

}

//  Methods

publicoverridevoidNextRecord()

{

if( current  <=  customers.Count  -1)

current ++ ;

}

publicoverridevoidPriorRecord()

{

if( current  >0)

current -- ;

}

publicoverridevoidNewRecord(  string  name )

{

customers.Add( name );

}

publicoverridevoidDeleteRecord(  string  name )

{

customers.Remove( name );

}

publicoverridevoidShowRecord()

{

Console.WriteLine( customers[ current ] );

}

publicoverridevoidShowAllRecords()

{

foreach (  string  name  in  customers )

Console.WriteLine("   "+  name );

}

}

/**   

///  Client test

///   

publicclassBusinessApp

{

publicstaticvoidMain(  string [] args )

{

//  Create RefinedAbstraction

CustomersBusinessObject customers  =

newCustomersBusinessObject("  Chicago  ");

//  Set ConcreteImplementor

customers.DataObject  =newCustomersDataObject();

//  Exercise the bridge

customers.Show();

customers.Next();

customers.Show();

customers.Next();

customers.Show();

customers.New(" Henry Velasquez ");

customers.ShowAll();

}

}

6. 在什么情况下应当使用桥梁模式

根据上面的分析,在以下的情况下应当使用桥梁模式:

如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。

设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。

一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。

虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值