Design Patterns(七):Adapter Pattern--VB代码

本文介绍了适配器模式的应用场景及其实现方式,包括对象适配器和类适配器等,展示了如何解决接口不兼容的问题,使现有类能够在新环境中复用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构图



动机

  在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。
  如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?

角色

    l         目标(Target)角色:这是客户所期待的接口。因为C#/VB.NET不支持多继承,所以Target必须是接口,不可以是类。
    l         源(Adaptee)角色:需要适配的类。
    l         适配器(Adapter)角色:把源接口转换成目标接口。这一角色必须是类。


意图

    将一个类的接口转换成客房希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

示意性代码

示意性代码
'Adapter pattern -- Structural example
Namespace DoFactoryNameSpace DoFactory.GangOfFour.Adapter.Structural

    
'Mainapp test application 
    Public Class MainAppClass MainApp
        
Public Sub Main()Sub Main()
            
'Create adapter and place a request 
            Dim target As Target = New Adapter
            target.Request()

            
'Wait for user 
            Console.ReadLine()
        
End Sub


        
'"Target" 
        Public Class TargetClass Target
            
Public Overridable Sub Request()Sub Request()
                Console.WriteLine(
"Called TargetRequest()")
            
End Sub

        
End Class


        
'"Adapter" 
        Public Class AdapterClass Adapter
            
Inherits Target

            
Private adaptee As New Adaptee()
            
Public Overrides Sub Request()Sub Request()
                
'Possibly do some other work
                'and then call SpecificRequest 
                adaptee.SpecificRequest()
            
End Sub

        
End Class


        
'"Adaptee" 
        Public Class AdapteeClass Adaptee
            
Public Sub SpecificRequest()Sub SpecificRequest()
                Console.WriteLine(
"Called SpecificRequest()")
            
End Sub

        
End Class

    
End Class

End Namespace


演变

旧程序

旧程序代码
'"Adaptee" 
Public Class AdapteeClass Adaptee
    
Public Sub SpecificRequest()Sub SpecificRequest()
        Console.WriteLine(
"Called SpecificRequest()")
    
End Sub

End Class

        
Public Class MainAppClass MainApp
    
Public Sub Main()Sub Main()

        
Dim adaptee As New Adaptee
        adaptee.SpecificRequest()

        
'wait for user
        Console.ReadLine()

    
End Sub

End Class

继承
客户程序期望通过Request方法使用Adaptee类,但是Adaptee类没有Request方法。这时我们提供一个类即Adapter类,它实现Target接口(此接口包含所有客户期望的方法),并继承于Adaptee。 Adapter类的Request方法重新封装了Adaptee的 SpecificRequest方法,实现了适配的目的。

类适配器
'客户希望的接口
Public Interface ITargetInterface ITarget
    
Sub Request()Sub Request()
End Interface

        
'被适配的对象
Public Class AdapteeClass Adaptee
    
Public Sub SpecificRequest()Sub SpecificRequest()
        Console.WriteLine(
"Called SpecificRequest()")
    
End Sub

End Class


'适配器
Public Class AdapterClass Adapter
    
Inherits Adaptee
    
Implements ITarget

    
Public Sub Request()Sub Request() Implements ITarget.Request
        
'Possibly do some other work
        'and then call SpecificRequest 
        Me.SpecificRequest()
    
End Sub

End Class


'客户程序        
Public Class MainAppClass MainApp
    
Public Sub Main()Sub Main()

        
Dim adapter As Adapter = New Adapter
        adapter.Request()

        
'wait for user
        Console.Readline()

    
End Sub

End Class

委派
客户程序期望通过Request方法使用Adaptee类,但是Adaptee类没有Request方法。这时我们提供一个包装(Wrapper)类即Adapter类,它实现Target接口,此接口包含所有客户期望的方法,并包装了一个Adaptee的实例,从而使客户端与Adaptee衔接起来。

对象适配器
'客户希望的接口
Public Interface ITargetInterface ITarget
    
Sub Request()Sub Request()
End Interface
        
'被适配的对象
Public Class AdapteeClass Adaptee
    
Public Sub SpecificRequest()Sub SpecificRequest()
        Console.WriteLine(
"Called SpecificRequest()")
    
End Sub
End Class

'适配器
Public Class AdapterClass Adapter
    
Implements ITarget

    
Private adaptee As New Adaptee()
    
Public Sub Request()Sub Request() Implements ITarget.Request
        
'Possibly do some other work
        'and then call SpecificRequest 
        adaptee.SpecificRequest()
    
End Sub

End Class


'客户程序         
Public Class MainAppClass MainApp
    
Public Sub Main()Sub Main()

        
'Create adapter and place a request 
        Dim adapter As New Adapter
        adapter.Request()

        
'wait for user
        Console.readline()

    
End Sub

End Class


对Adapter模式的改进

旧程序

旧程序代码
'"Adaptee" 
Public MustInherit Class AdapteeClass Adaptee
    
Public MustOverride Sub SpecificRequest()Sub SpecificRequest()
End Class

        
'"ConcreteAdaptee" 
Public Class ConcreteAdapteeAClass ConcreteAdapteeA
    
Inherits Adaptee
    
Public Overrides Sub SpecificRequest()Sub SpecificRequest()
        Console.WriteLine(
"Called SpecificRequestA()")
    
End Sub

End Class

        
'"ConcreteAdaptee" 
Public Class ConcreteAdapteeBClass ConcreteAdapteeB
    
Inherits Adaptee
    
Public Overrides Sub SpecificRequest()Sub SpecificRequest()
        Console.WriteLine(
"Called SpecificRequestA()")
    
End Sub

End Class

        
Public Class MainAppClass MainApp
    
Public Sub Main()Sub Main()

        
Dim c1 As adaptee = New ConcreteAdapteeA
        c1.SpecificRequest()

        
Dim c2 As adaptee = New ConcreteAdapteeA
        c2.SpecificRequest()

        
'wait for user
        Console.Readline()

    
End Sub

End Class

配合泛型对“现存对象”进行适配。

类适配器
'客户希望的新接口
Public Interface ITargetInterface ITarget
    
Sub Request()Sub Request()
End Interface


'适配器
Public  Class AdapterClass Adapter(Of T As {Adaptee, New})
    
Implements ITarget

    
Protected _Adaptee As New T
    
Public Sub Request()Sub Request() Implements ITarget.Request
        
'Possibly do some other work
        'and then call SpecificRequest 
        _Adaptee.SpecificRequest()
    
End Sub

End Class


'客户程序        
Public Class MainAppClass MainApp
    
Public Sub Main()Sub Main()

        
Dim c1 As New Adapter(Of ConcreteAdapteeA)
        c1.Request()

    
Dim c2 As New Adapter(Of ConcreteAdapteeB)
        c2.Request()

        
'wait for user
        Console.Readline()

    
End Sub

End Class

Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。

对象适配器
'客户希望的新接口
Public Interface ITargetInterface ITarget
    
Sub Request()Sub Request()
End Interface
    
'适配器
Public Class AdapterClass Adapter
    
Implements ITarget

    
Private _adaptee As Adaptee
    
Public Sub New()Sub New(Optional ByVal adaptee As Adaptee = Nothing)
        
Me.adaptee = adaptee
    
End Sub


    
Public Sub Request()Sub Request() Implements ITarget.Request
        
'Possibly do some other work
        'and then call SpecificRequest 
        If _adaptee IsNot Nothing Then
            _adaptee.SpecificRequest()
        
End If
    
End Sub

End Class

        
Public Class MainAppClass MainApp
    
Public Sub Main()Sub Main()

        
'Create adapter and place a request 
        Dim c1 As New Adapter(New ConcreteAdapteeA)
        c1.Request()

        
Dim c2 As New Adapter(New ConcreteAdapteeB)
        c2.Request()

        
'wait for user
        Console.Readline()

    
End Sub

End Class


Adapter模式的几个要点:
  1、Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用的环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
  2、GoF23定义了两种Adapter模式的实现结构:对象适配器采用“对象组合”的方式,更符合松耦合精神。(
  3、Adapter模式可以实现的非常灵活,不必拘泥于GoF23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。
  4、Adapter模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。



参考资料
《.NET设计模式(8):适配器模式(Adapter Pattern)》        TerryLee
《我的Design Pattern之旅[7]:使用泛型改進Adapter Pattern (中級)》        真 OO无双
《C#面向对象设计模式纵横谈系列课程(7)》     李建中老师

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值