Design Patterns(八):Bridge Pattern--VB代码
★★★☆☆
将抽象部分与实现部分分离,使它们都可以独立地变化。
Decouple an abstraction from its implementation so that the two can vary independently.
结构图

角色
l 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
l 修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
l 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
l 具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现。
动机
当一个对象有了两个变化的维度,如何应对这种“多维度的变化”?如何利用面向对象技术来使得这个对象类型可以轻松沿着多个方向变化,而不引入额外的复杂度?
意图
将抽象部分与实现部分分离,使它们都可以独立地变化。
示意性代码

示意性代码
'MainApp test application

Public Class MainAppClass MainApp

Public Shared Sub Main()Sub Main()
'Set implementation and call
Dim ab As Abstraction = New RefinedAbstraction
ab.Implementor = New ConcreteImplementorA
ab.Operation()

'Change implementation and call
ab.Implementor = New ConcreteImplementorB
ab.Operation()

'Wart for user
Console.ReadLine()
End Sub
End Class

'"Abstraction"

Public Class AbstractionClass Abstraction
Protected m_implementor As Implementor

' Property

Public WriteOnly Property Implementor()Property Implementor() As Implementor
Set(ByVal value As Implementor)
m_implementor = value
End Set
End Property


Public Overridable Sub Operation()Sub Operation()
m_implementor.Operation()
End Sub
End Class

'"Implementor"

Public MustInherit Class ImplementorClass Implementor

Public MustOverride Sub Operation()Sub Operation()
End Class

'"RefinedAbstraction"

Public Class RefinedAbstractionClass RefinedAbstraction
Inherits Abstraction

Public Overrides Sub Operation()Sub Operation()
m_implementor.Operation()
End Sub
End Class

'"ConcreteImplementorA"

Public Class ConcreteImplementorAClass ConcreteImplementorA
Inherits Implementor

Public Overrides Sub Operation()Sub Operation()
Console.WriteLine("ConcreteImplementorA Operation")
End Sub
End Class

'"ConcreteImplementorB"

Public Class ConcreteImplementorBClass ConcreteImplementorB
Inherits Implementor

Public Overrides Sub Operation()Sub Operation()
Console.WriteLine("ConcreteImplementorB Operation")
End Sub
End Class
实例
该例子演示了业务对象(BusinessObject)通过Bridge模式与数据对象(DataObject)解耦(相分离)。数据对象的实现可以在不改变客户端代码的情况下动态进行更换。

一个实例
' Bridge pattern -- Real World example

Imports System
Imports System.Collections


Namespace DoFactoryNamespace DoFactory.GangOfFour.Bridge.RealWorld
' MainApp test application

Class MainAppClass MainApp

Private Shared Sub Main()Sub Main()
' Create RefinedAbstraction
Dim customers As New Customers("Chicago")
' Set ConcreteImplementor
customers.Data = New CustomersData()
' Exercise the bridge
customers.Show()
customers.[Next]()
customers.Show()
customers.[Next]()
customers.Show()
customers.[New]("Henry Velasquez")
customers.ShowAll()
' Wait for user
Console.Read()
End Sub
End Class

' 抽象部分,即对象固有的状态和行为
' "Abstraction"

Class CustomersBaseClass CustomersBase
Private dataObject As DataObject
Protected group As String

Public Sub New()Sub New(ByVal group As String)
Me.group = group
End Sub
' Property

Public Property Data()Property Data() As DataObject
Get
Return dataObject
End Get
Set
dataObject = value
End Set
End Property

Public Overridable Sub [()Sub [Next]()
dataObject.NextRecord()
End Sub

Public Overridable Sub Prior()Sub Prior()
dataObject.PriorRecord()
End Sub

Public Overridable Sub [()Sub [New](ByVal name As String)
dataObject.NewRecord(name)
End Sub

Public Overridable Sub Delete()Sub Delete(ByVal name As String)
dataObject.DeleteRecord(name)
End Sub

Public Overridable Sub Show()Sub Show()
dataObject.ShowRecord()
End Sub

Public Overridable Sub ShowAll()Sub ShowAll()
Console.WriteLine("Customer Group: " + group)
dataObject.ShowAllRecords()
End Sub
End Class
' "RefinedAbstraction"
' 抽象部分可以独立的变化

Class CustomersClass Customers
Inherits CustomersBase
' Constructor

Public Sub New()Sub New(ByVal group As String)
MyBase.New(group)
End Sub

Public Overloads Overrides Sub ShowAll()Sub ShowAll()
' Add separator lines
Console.WriteLine()
Console.WriteLine("------------------------")
MyBase.ShowAll()
Console.WriteLine("------------------------")
End Sub
End Class

' 实现部分,即客户期望对象在不同环境下的不同表现
' "Implementor"

MustInherit Class DataObjectClass DataObject

Public MustOverride Sub NextRecord()Sub NextRecord()

Public MustOverride Sub PriorRecord()Sub PriorRecord()

Public MustOverride Sub NewRecord()Sub NewRecord(ByVal name As String)

Public MustOverride Sub DeleteRecord()Sub DeleteRecord(ByVal name As String)

Public MustOverride Sub ShowRecord()Sub ShowRecord()

Public MustOverride Sub ShowAllRecords()Sub ShowAllRecords()
End Class
' 实现部分可以独立的变化
' "ConcreteImplementor"

Class CustomersDataClass CustomersData
Inherits DataObject
Private customers As New ArrayList()
Private current As Integer = 0

Public Sub New()Sub New()
' Loaded from a database
customers.Add("Jim Jones")
customers.Add("Samual Jackson")
customers.Add("Allen Good")
customers.Add("Ann Stills")
customers.Add("Lisa Giolani")
End Sub

Public Overloads Overrides Sub NextRecord()Sub NextRecord()
If current <= customers.Count - 1 Then
current += 1
End If
End Sub

Public Overloads Overrides Sub PriorRecord()Sub PriorRecord()
If current > 0 Then
current -= 1
End If
End Sub

Public Overloads Overrides Sub NewRecord()Sub NewRecord(ByVal name As String)
customers.Add(name)
End Sub

Public Overloads Overrides Sub DeleteRecord()Sub DeleteRecord(ByVal name As String)
customers.Remove(name)
End Sub

Public Overloads Overrides Sub ShowRecord()Sub ShowRecord()
Console.WriteLine(customers(current))
End Sub

Public Overloads Overrides Sub ShowAllRecords()Sub ShowAllRecords()
For Each name As String In customers
Console.WriteLine(" " + name)
Next
End Sub
End Class
End Namespace

l 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
l 修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
l 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
l 具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现。
动机
当一个对象有了两个变化的维度,如何应对这种“多维度的变化”?如何利用面向对象技术来使得这个对象类型可以轻松沿着多个方向变化,而不引入额外的复杂度?
意图
将抽象部分与实现部分分离,使它们都可以独立地变化。
示意性代码












































































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

























































































































































































Bridge模式的几个要点:
1、Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
2、所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。得到各个子类之后,便可以任意重组它们,从而获得不同平台上的不同型号。
3、Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多方案更好的解决方法。
4、Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈,换言之两个不会导致纵横交错的结果,并不一定要使用Bridge模式。
我的理解
当对象的抽象部分和实现部分都发生变化时,也就是发生二维变化。假设将变化出M种抽象,N种表现。一般的解决方法是派生出M×N个对象,以满足条件,这个结构遵循了开放-封闭原则,但是它却违背了单一职责原则,即一个类只有一个引起它变化的原因, 抽象部分(即固有的状态和行为)发生变化整个类要变,实现部分( 即类在客户环境下的不同表现)发生变化,整个类也要变。一种更好的解决方案是:将抽象部分与实现部分分离,这样就只需要M+N个对象,通过实现部分与抽象部分的任意组合,得到客户期望的表现。
参考资料
《.NET设计模式(9):桥接模式(Bridge Pattern)》 TerryLee
《设计模式(16)-Bridge Pattern》 吕震宇
《C#面向对象设计模式纵横谈系列课程(8)》 李建中老师
分类:
Design Pattern
随笔分类 (333)
Cnblogs's
Front End
Oracle's
Software's
- Apache HTTP Server
- CodeSmith Community
- Grapecity(FAQ)
- Mybase
- ClubFarPoint(Forum)
- Beyond Compare
- CrystalReport(FAQ)
- 秀丸
- Software Advice
- Software: Business & Nonprofit | Reviews and Top Software at Capterra
- Capterra
- Business Software Reviews from Software Advice
Copyright © 2025 sekihin
Powered by .NET 9.0 on Kubernetes
Powered by .NET 9.0 on Kubernetes
![]() | 本作品采用 知识共享署名-非商业性使用 2.5 中国大陆许可协议进行许可。 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通