- 浏览: 69260 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
fabulasia:
一字不漏的抄过来,有意思?
null buffer || null address -
Gozs_cs_dn:
因为不明白才跑过来看,看完之后还是不明白,可能是我太笨了。我是 ...
工厂方法模式与抽象工厂模式 -
Now......Try:
通俗易懂
工厂方法模式与抽象工厂模式 -
baojieearth:
看了楼主的代码思路一下子清晰了,就是画的几张图看不懂嘿嘿
工厂方法模式与抽象工厂模式 -
xiaolong_1905:
楼主人真好,谢谢!
工厂方法模式与抽象工厂模式
桥梁模式是一个非常有用的模式,也是比较复杂的一个模式。熟悉这个模式对于理解面向对象的设计原则,包括"开-闭"原则(OCP)以及组合/聚合复用原则(CARP)都很有帮助。理解好这两个原则,有助于形成正确的设计思想和培养良好的设计风格。 注:《Java与模式》一书认为Bridge模式不是一个使用频率很高的模式,我不太赞同,我认为Bridge模式中蕴涵了很多设计模式的关键思想在里面,所以我这里采纳了《Design Patterns Explained》一书的作者Alan Shalloway与James R. Trott的观点:The Bridge pattern is quite a bit more complex than the other patterns you just learned; it is also much more useful. 桥梁模式的用意 【GOF95】在提出桥梁模式的时候指出,桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。这句话有三个关键词,也就是抽象化、实现化和脱耦。 抽象化 存在于多个实体中的共同的概念性联系,就是抽象化。作为一个过程,抽象化就是忽略一些信息,从而把不同的实体当做同样的实体对待【LISKOV94】。 实现化 抽象化给出的具体实现,就是实现化。 脱耦 所谓耦合,就是两个实体的行为的某种强关联。而将它们的强关联去掉,就是耦合的解脱,或称脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。 将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥梁模式的用意。 桥梁模式【GOF95】是对象的结构模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。 下图所示就是一个实现了桥梁模式的示意性系统的结构图。 可以看出,这个系统含有两个等级结构,也就是: 桥梁模式所涉及的角色有: 感觉《敏捷软件开发-原则、模式与实践》中关于Bridge模式的例子很好。(《Java与模式》一书33章的对变化的封装一节也写得很不错,推荐大家读一读。它深入的阐述了《Design Patterns Explained》一书中"1)Design to interfaces. 2)Favor composition over inheritance. 3)Find what varies and encapsulate it"的三个观点。)。 如图所示,有大量的调制解调器客户程序在使用Modem接口。Modem接口被几个派生类HayesModem、USRoboticsModem和EarniesModem实现。它很好地遵循了OCP、LSP和DIP。当增加新种类的调制解调器时,调制解调器的客户程序不会受影响。 假定这种情形持续了几年,并有许多调制解调器的客户程序都在使用着Modem接口。现出现了一种不拨号的调制解调器,被称为专用调制解调器。它们位于一条专用连接的两端。有几个新应用程序使用这些专用调制解调器,它们无需拨号。我们称这些使用者为DedUser。但是,客户希望当前所有的调制解调器客户程序都可以使用这些专用调制解调器。他们不希望去更改许许多多的调制解调器客户应用程序,所以完全可以让这些调制解调器客户程序去拨一些假(dummy)电话号码。 如果能选择的话,我们会把系统的设计更改为下图所示的那样。 我们把拨号和通信功能分离为两个不同的接口。原来的调制解调器实现这两个接口,而调制解调器客户程序使用这两个接口。DedUser只使用Modem接口,而DedicateModem只实现Modem接口。但这样做会要求我们更改所有的调制解调器客户程序--这是客户不允许的。 一个可能的解决方案是让DedicatedModem从Modem派生并且把dial方法和hangup方法实现为空,就像下面这样: 几个月后,已经有了大量的DedUser,此时客户提出了一个新的更改。为了能拨国际电话号码、信用卡电话、PIN标识电话等等,必修对现有dial中使用char[10]存储号码改为能够拨打任意长度的电话号码。 显然,所有的调制解调器客户程序都必须更改。客户同意了对调制解调器客户程序的更改,因为他们别无选择。糟糕的是,现在必须要去告诉DedUser的编写者,他们必须要更改他们的代码!你可以想象他们听到这个会有多高兴。本来他们是不用调用dial的。 这就是许多项目都会具有的那种有害的混乱依赖关系。系统某一部分中的一个杂凑体(kludge)创建了一个有害的依赖关系,最终导致系统中完全无关的部分出现问题。 如果使用ADAPTER模式解决最初的问题的话,就可以避免这个严重问题。如图: 请注意,杂凑体仍然存在。适配器仍然要模拟连接状态。然而,所有的依赖关系都是从适配器发起的。杂凑体和系统隔离,藏身于几乎无人知晓的适配器中。 BRIDGE模式 看待这个问题,还有另外一个方式。现在,出现了另外一种切分Modem层次结构的方式。如下图: 这不是一个理想的结构。每当增加一款新硬件时,就必须创建两个新类--一个针对专用的情况,一个针对拨号的情况。每当增加一种新连接类型时,就必须创建3个新类,分别对应3款不同的硬件。如果这两个自由度根本就是不稳定的,那么不用多久,就会出现大量的派生类。 在类型层次结构具有多个自由度的情况中,BRIDGE模式通常是有用的。我们可以把这些层次结构分开并通过桥把它们结合到一起,而不是把它们合并起来。如图: 我们把调制解调器类层次结构分成两个层次结构。一个表示连接方法,另一个表示硬件。 这个结构虽然复杂,但是很有趣。它的创建不会影响到调制解调器的使用者,并且还完全分离了连接策略和硬件实现。ModemConnectController的每个派生类代表了一个新的连接策略。在这个策略的实现中可以使用sendlmp、receivelmp、diallmp和hanglmp。新imp方法的增加不会影响到使用者。可以使用ISP来给连接控制类增加新的接口。这种做法可以创建出一条迁移路径,调制解调器的客户程序可以沿着这条路径慢慢地得到一个比dial和hangup层次更高的API。 该例子演示了业务对象(BusinessObject)通过Bridge模式与数据对象(DataObject)解耦。数据对象的实现可以在不改变客户端代码的情况下动态进行更换。 根据上面的分析,在以下的情况下应当使用桥梁模式:一、 桥梁(Bridge)模式
二、 桥梁模式的结构
三、 桥梁模式的示意性源代码
using System;
// "Abstraction"
class Abstraction
{
// Fields
protected Implementor implementor;
// Properties
public Implementor Implementor
{
set { implementor = value; }
}
// Methods
virtual public void Operation()
{
implementor.Operation();
}
}
// "Implementor"
abstract class Implementor
{
// Methods
abstract public void Operation();
}
// "RefinedAbstraction"
class RefinedAbstraction : Abstraction
{
// Methods
override public void Operation()
{
implementor.Operation();
}
}
// "ConcreteImplementorA"
class ConcreteImplementorA : Implementor
{
// Methods
override public void Operation()
{
Console.WriteLine( " ConcreteImplementorA Operation " );
}
}
// "ConcreteImplementorB"
class ConcreteImplementorB : Implementor
{
// Methods
override public void Operation()
{
Console.WriteLine( " ConcreteImplementorB Operation " );
}
}
/// <summary>
/// Client test
/// </summary>
public class Client
{
public static void Main( string [] args )
{
Abstraction abstraction = new RefinedAbstraction();
// Set implementation and call
abstraction.Implementor = new ConcreteImplementorA();
abstraction.Operation();
// Change implemention and call
abstraction.Implementor = new ConcreteImplementorB();
abstraction.Operation();
}
}
四、 调制解调器问题
五、 另外一个实际应用Bridge模式的例子
using System;
using System.Collections;
// "Abstraction"
class BusinessObject
{
// Fields
private DataObject dataObject;
protected string group;
// Constructors
public BusinessObject( string group )
{
this .group = group;
}
// Properties
public DataObject DataObject
{
set { dataObject = value; }
get { return dataObject; }
}
// Methods
virtual public void Next()
{ dataObject.NextRecord(); }
virtual public void Prior()
{ dataObject.PriorRecord(); }
virtual public void New( string name )
{ dataObject.NewRecord( name ); }
virtual public void Delete( string name )
{ dataObject.DeleteRecord( name ); }
virtual public void Show()
{ dataObject.ShowRecord(); }
virtual public void ShowAll()
{
Console.WriteLine( " Customer Group: {0} " , group );
dataObject.ShowAllRecords();
}
}
// "RefinedAbstraction"
class CustomersBusinessObject : BusinessObject
{
// Constructors
public CustomersBusinessObject( string group )
: base ( group ) {}
// Methods
override public void ShowAll()
{
// Add separator lines
Console.WriteLine();
Console.WriteLine( " ------------------------ " );
base .ShowAll();
Console.WriteLine( " ------------------------ " );
}
}
// "Implementor"
abstract class DataObject
{
// Methods
abstract public void NextRecord();
abstract public void PriorRecord();
abstract public void NewRecord( string name );
abstract public void DeleteRecord( string name );
abstract public void ShowRecord();
abstract public void ShowAllRecords();
}
// "ConcreteImplementor"
class CustomersDataObject : DataObject
{
// Fields
private ArrayList customers = new ArrayList();
private int current = 0 ;
// Constructors
public CustomersDataObject()
{
// 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
public override void NextRecord()
{
if ( current <= customers.Count - 1 )
current ++ ;
}
public override void PriorRecord()
{
if ( current > 0 )
current -- ;
}
public override void NewRecord( string name )
{
customers.Add( name );
}
public override void DeleteRecord( string name )
{
customers.Remove( name );
}
public override void ShowRecord()
{
Console.WriteLine( customers[ current ] );
}
public override void ShowAllRecords()
{
foreach ( string name in customers )
Console.WriteLine( " " + name );
}
}
/// <summary>
/// Client test
/// </summary>
public class BusinessApp
{
public static void Main( string [] args )
{
// Create RefinedAbstraction
CustomersBusinessObject customers =
new CustomersBusinessObject( " Chicago " );
// Set ConcreteImplementor
customers.DataObject = new CustomersDataObject();
// Exercise the bridge
customers.Show();
customers.Next();
customers.Show();
customers.Next();
customers.Show();
customers.New( " Henry Velasquez " );
customers.ShowAll();
}
}
六、 在什么情况下应当使用桥梁模式
发表评论
-
设计模式原则
2011-09-24 18:08 1071计算机是一门所有的问题都可以通过增加一个中间层来解决的 ... -
Builder生成器模式1——转载
2011-09-17 16:28 890Builder模式定义: 将一个 ... -
Builder生成器模式2——转载
2011-09-17 16:24 1090Builder生成器模式是一种创建型模式,它主要是应 ... -
代理模式————转载
2011-09-17 12:55 1033一、引子 我们去科技市场为自己的机器添加点奢侈的配件,很 ... -
桥接模式——转载
2011-09-16 17:30 875Bridge桥接模式是一种结构型模式,它 ... -
中介者模式——转载
2011-09-15 20:50 930一、中介者模式简介 ... -
责任链模式——转载
2011-09-14 19:49 799一、引言 初看责任链模式,心里不禁想起了一个 ... -
观察者模式——转载
2011-09-14 00:03 817一、引子 还记得警匪片上,匪徒们是怎么配合实施犯罪的吗? ... -
策略模式
2011-09-11 00:39 1041一、引子 18日下午3时一刻,沈阳,刚刚下完一场几年 ... -
工厂方法模式与抽象工厂模式
2011-09-10 23:55 34464本文是转的 一、引 ... -
模板方法与策略模式
2011-09-11 00:47 969模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟 ... -
适配器模式与装饰者模式
2011-09-06 20:15 4467适配器模式:将一个类的接口,转换成客户期望的另外一个接口。适配 ... -
command模式
2011-09-01 21:01 768command模式: command模式允许我们将动作封装成 ...
相关推荐
FC_AE_1553桥接芯片研究——光纤通道接口
2. **结构差异**:桥接模式包含抽象、实现和桥接角色,实现部分和抽象部分通过桥接角色关联;策略模式由策略接口和具体策略类组成,客户端通过持有策略接口来调用具体策略的算法。 3. **灵活性**:桥接模式更注重于...
2. 当抽象和实现之间存在明显的依赖关系时,使用桥接模式可以降低这种依赖,使两者可以独立演化。 3. 当希望避免由于类的爆炸性增长导致的类数量过多问题时,可以使用桥接模式。 视频资源“7.Bridge 桥接模式(结构...
2. 支持多继承:在某些不支持多继承的语言中,可以通过桥接模式实现类似效果。 3. 更好的可扩展性:随着新功能需求的增加,只需添加新的实现类,而无需修改现有代码。 桥接模式适用于以下场景: - 当系统需要在抽象...
VMWare 6.0 桥接模式虚拟机网络配置 VMWare 6.0 桥接模式虚拟机网络配置是虚拟机网络配置中的一种简单而又重要的网络连接模式。通过以下步骤可以设置桥接模式虚拟机网络配置:首先,确保在相应虚拟机的以太网设置...
桥接模式是一种设计模式,它将抽象部分与实现部分分离,使得它们可以独立进行变化。在C++中,桥接模式的应用有助于降低系统的耦合度,提高代码的可扩展性和可维护性。以下是对桥接模式及其C++实现的详细解释。 首先...
2. 多维度的分类:如果一个类有多个变化维度,桥接模式可以将这些维度分离,形成独立的继承层次结构,降低复杂度。 3. 符合开闭原则:对扩展开放,对修改关闭,可以在不修改原有代码的基础上增加新的实现。 在实际...
桥接模式(Bridge Pattern)是设计模式中结构型模式的一种,它的主要目的是将抽象部分与实现部分解耦,使得它们可以独立地进行变化。在Java编程中,这种模式的应用可以帮助我们构建更加灵活、可扩展的代码结构。 ...
步骤2:查看VMware虚拟网络编辑器的VMnet0桥接模式设置 编辑>>虚拟网络编辑器>>选择桥接模式>>修改为电脑的网卡实际名 步骤3:上一步骤依然不能解决虚拟机上网则设置: 步骤4、保存退出,选择刚设置好的...
桥接模式是软件设计模式中的一种结构型模式,它的主要目的是为了实现抽象和实现的解耦,使得两者可以独立地进行扩展。在桥接模式中,抽象类(Abstraction)不直接引用具体实现(Implementation),而是通过一个桥接...
"ADSL 桥接模式和路由模式的区别" 在 ADSL 宽带接入方式中,桥接模式和路由模式是两种常见的工作模式。_bridge 模式是 ADSL ROUTER 的默认工作模式,主要用于单台电脑的接入,需要代理服务器或网关设备将局域网中的...
桥接模式是设计模式中的一种结构型模式,其主要目的是为了分离抽象部分和实现部分,以便两者能够独立地进行变化。这种模式的核心理念是通过引入一个抽象层来封装多种可能的实现,使得抽象和实现之间形成一种“桥接”...
桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立进行变化。这种模式在软件设计中扮演着重要的角色,尤其是在面对需求频繁变动或系统需要支持多平台、多设备的情况下。 首先,我们要理解...
桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立进行变化。这种模式在软件工程中被广泛应用于处理组件之间的耦合问题,使得系统具有更好的可扩展性和灵活性。 桥接模式的主要组成部分...
**Android桥接模式详解** 桥接模式是一种设计模式,它将抽象部分与实现部分分离,使得它们可以独立地进行变化。在Android开发中,尤其是在构建可扩展和灵活的架构时,这种模式尤其有用。本文将深入探讨桥接模式在...
桥接模式是设计模式中的一种结构型模式,它旨在将抽象部分与实现部分解耦,使得它们可以独立地变化。这种模式将抽象类和它的实现类进行分离,通过一个抽象接口来连接它们,使得两者可以独立发展,增加了系统的灵活性...
桥接模式(Bridge Pattern)是面向对象设计中的一种结构型模式,它将抽象部分与实现部分分离,使得它们可以独立地进行变化。在C#编程中,桥接模式的应用能够帮助我们更好地解耦系统,提高代码的灵活性和可扩展性。 ...
桥接模式是一种设计模式,属于结构型模式,其主要目的是将抽象部分与实现部分分离,使得它们可以独立地进行变化。这种模式通过引入一个抽象化角色来实现抽象部分与实现部分的解耦,使得这两部分可以独立扩展。在这个...
桥接模式(Bridge Pattern)是一种结构型设计模式,它旨在将抽象部分与其实现部分分离,使得它们可以独立地进行变化。在C#编程中,这种模式尤其有用,因为随着软件系统的复杂性增加,类的继承层次可能会变得难以管理...
利用桥接模式完成以下实例: 1、编辑与作者。出版社的编辑负责策划图书,并遴选作者完成图书的编著,然后根据图书的印张发布图书。作者负责完成图书的编著工作。 2、模拟毛笔:现需要提供大中小3种型号的画笔,...