我完全不了解“桥梁”设计模式。我浏览了各种网站,但没有帮助。
有人可以帮助我理解这一点吗?
我完全不了解“桥梁”设计模式。我浏览了各种网站,但没有帮助。
有人可以帮助我理解这一点吗?
Answers:
在OOP中,我们使用多态性,因此抽象可以具有多种实现。让我们看下面的例子:
//trains abstraction
public interface Train
{
move();
}
public class MonoRail:Train
{
public override move()
{
//use one track;
}
}
public class Rail:Train
{
public override move()
{
//use two tracks;
}
}
引入了新的要求,并且需要引入列车的加速角度,因此请更改以下代码。
public interface Train
{
void move();
}
public class MonoRail:Train
{
public override void move()
{
//use one track;
}
}
public class ElectricMonoRail:MonoRail
{
public override void move()
{
//use electric engine on one track.
}
}
public class DieselMonoRail: MonoRail
{
public override void move()
{
//use diesel engine on one track.
}
}
public class Rail:Train
{
public override void move()
{
//use two tracks;
}
}
public class ElectricRail:Rail
{
public override void move()
{
//use electric engine on two tracks.
}
}
public class DieselRail: Rail
{
public override void move()
{
//use diesel engine on two tracks.
}
}
上面的代码不可维护,并且缺乏可重用性(假设我们可以在同一轨道平台上重用加速机制)。以下代码应用了桥梁模式,并将火车运输和加速度这两个不同的抽象分开。
public interface Train
{
void move(Accelerable engine);
}
public interface Accelerable
{
public void accelerate();
}
public class MonoRail:Train
{
public override void move(Accelerable engine)
{
//use one track;
engine.accelerate(); //engine is pluggable (runtime dynamic)
}
}
public class Rail:Train
{
public override void move(Accelerable engine)
{
//use two tracks;
engine.accelerate(); //engine is pluggable (runtime dynamic)
}
}
public class ElectricEngine:Accelerable{/*implementation code for accelerable*/}
public class DieselEngine:Accelerable{/*implementation code for accelerable*/}
Monorail
因为它不是真正的两个单词,而是一个(复合)单词。MonoRail将是Rail的某个子类,而不是其他类型的Rail(它是)。就像我们不会使用SunShine
或者CupCake
,他们会Sunshine
和Cupcake
尽管大多数设计模式都有有用的名称,但我发现名称“ Bridge”在功能上并不直观。
从概念上讲,您将类层次结构使用的实现详细信息推入另一个对象(通常具有自己的层次结构)。这样,您将消除对这些实现细节的严格依赖,并允许更改该实现的细节。
在小范围内,我将其比喻为使用策略模式来插入新行为。但是,实现对象通常具有更多功能,而不仅仅是像在策略中常见的那样包装算法。当您将该概念应用于整个类层次结构时,较大的模式将成为桥梁。(再次,讨厌这个名字)。
这不是您每天都会使用的一种模式,但是我发现它在管理潜在的类爆炸时很有用,当您(明显)需要多重继承时,这些类可能发生。
这是一个真实的示例:
我有一个RAD工具,可让您在设计图面上放置和配置控件,因此我有一个这样的对象模型:
Widget // base class with design surface plumbing
+ Top
+ Left
+ Width
+ Height
+ Name
+ SendToBack
+ BringToFront
+ OnPropertyEdit
+ OnSelect
+ Validate
+ ShowEditor
+ Paint
+ Etc
TextboxWidget : Widget // text box specific
+ Text
+ MaxLength
+ Font
+ ShowEditor // override base to show a property editor form specific to a Textbox
+ Paint // override to render a textbox onto the surface
+ Etc
ListWidget : Widget // list specific
+ Items
+ SelectedItem
+ ShowEditor // override base to show a property editor form specific to a List
+ Paint // override to render a list onto the surface
+ Etc
依此类推,也许有十几个控件。
但是随后添加了新要求以支持多个主题(look-n-feel)。比方说,我们有以下主题: Win32
,WinCE
,WinPPC
,WinMo50
,WinMo65
。对于与渲染相关的操作,每个主题将具有不同的值或实现,例如DefaultFont,DefaultBackColor,BorderWidth,DrawFrame,DrawScrollThumb等。
我可以创建一个这样的对象模型:
Win32TextboxWidget : TextboxWidget
Win32ListWidget : ListWidget
等,用于一种控制类型
WinCETextboxWidget : TextboxWidget
WinCEListWidget : ListWidget
等等,针对彼此的控件类型(再次)
您了解了这一点–您得到了小部件数量乘以主题数量的类爆炸式增长。使RAD设计人员意识到每个主题都会使它复杂化。另外,添加新主题会强制修改RAD设计器。此外,在主题内有很多通用实现,可以很好地继承,但是控件已经从通用基(Widget
)继承了。
因此,我要做的是创建一个单独的对象层次结构来实现主题。每个小部件都将包含对实现渲染操作的对象的引用。在许多课本中,此类都带有一个后缀,Impl
但我偏离了该命名约定。
所以现在我TextboxWidget
看起来像这样:
TextboxWidget : Widget // text box specific
+ Text
+ MaxLength
+ Font
+ ShowEditor
+ Painter // reference to the implementation of the widget rendering operations
+ Etc
而且我可以让我的各种画家继承我特定主题的基础,这是我以前做不到的:
Win32WidgetPainter
+ DefaultFont
+ DefaultFontSize
+ DefaultColors
+ DrawFrame
+ Etc
Win32TextboxPainter : Win32WidgetPainter
Win32ListPainter : Win32WidgetPainter
一件好事是,我可以在运行时动态加载实现,从而可以在不更改核心软件的情况下添加任意数量的主题。换句话说,我的“实现可以独立于抽象而变化”。
Win32TextboxPainter
,并Win32ListPainter
从Win32WidgetPainter
。您可以对实施方的继承树,但它应该是更通用的(或许StaticStyleControlPainter
,EditStyleControlPainter
和ButtonStyleControlPainter
),并根据需要重写任何需要的基本操作。这更接近于我基于示例的真实代码。
该桥打算将抽象与其具体实现分离开来,以便两者可以独立变化:
桥通过使用composition实现此目的:
关于频繁混乱的补充说明
这种模式与适配器模式非常相似:抽象为实现提供了不同的接口,并使用合成来实现。但:
这些模式之间的主要区别在于它们的意图-Gamma
等人,“ 设计模式,可重用的OO软件的组成部分 ”,1995年。
在这本关于设计模式的极好的开创性著作中,作者还注意到: