就他吧-9ta8为您提供:身份证查询、15位转16位身份证,手机号码归属地查询,IP地址查询服务,城市天气预报查询,列车时刻表简易快速查询等等查询服务,就他吧欢迎您的光临!!
随笔- 96  评论- 750  文章- 16 

Dot Net设计模式—适配器模式

1.概述
1.1意图

        使接口不兼容的类能够协同工作。通常情况下,这些接口不兼容的类在逻辑上的功能是一致或者相似的。例如采用RS232协议和TCP/IP的目的都是为了传输数据,支持这两种协议的API却是截然不同的。

1.2结构
        适配器有类适配器和对象适配器两种类型,二者的意图相同,只是实现的方法和适用的情况不同。类适配器采用继承来实现,对象适配器则采用组合的方法来实现。

(1)类适配器:类适配器通过多生继承对一个接口与另一个接口进行匹配,其结构如图所示。

                               
        Target定义了Client使用的与特定领域相关的接口,Client通过调用Target实现某一个特定的操作。Adaptee是一个已经存在的类,需要与Target协同工作,这个接口需要适配。Adapter适配器适配Adaptee和Target接口。

在类适配器中,通过继承获得Adaptee中的方法。

Pulic class Adapter:Adaptee,Target
{
   
#region Target 成员
   
public void Do( )
   
{
       
this.Execute( );
   }

   
#endregion

}


        类适配器的使用有一这限制,由于.NET不支持多重继承,即一个类只能有一个父类。因此当Target是一个类,而不是一个接口时无法实现类适配器,这时需要使用对象适配器。

(2)对象适配器:对象适配器采用对象组合,通过引用一个类与另一个类接口,其结构如图所示。
                                      

在对象适配器中通过组合获得Adaptee对象:

 public class Adapter:Target
 
{
     
private Adaptee adaptee;
     
public Adapter(Adaptee ap)
     
{
          adaptee 
= ap;
      }

      
#region Target 成员
      
public void Do( )
      
{
          adaptee.Execute( );
      }

      
#endregion

}

1.3使用场合
        适配器模式适用于以下情况。
(1)需要使用一个已经存在的类,但接口与设计要求不符。
(2)希望创建一个可以复用的类,该类可以与其他不相关的类或者是将来不可预见的类协同工作。

        在使用适配器时应注意理解适配器的方向性,即注意区分适配器中的Adaptee(适配对象)和Target(目标),在适配器的原理图中很容易看出Target,即被客户操作的是目标。

2.多媒体播放对象
        回到上节的问题,我们在开发多媒体播放器时,希望可以采用RealPlay和 MS MediaPlay两种播放器。而二者的接口完全不同,并且我们可能在将来引入其他播放器。

        为了使程序兼容两种播放器,我们定义了一个播放器的接口。然后用两个适配器分别实现这个接口,并调用RealPlay和 MS Media Player的API,这是典型的对象适配器。

采用对象适配器的结构如图所示。


代码如下:
'播放器的接口
Public Interface AudioPlayer
    
Sub DoPlay()
    
Sub DoStop()
    
Sub DoPause()
    
Property Source() As String
End Interface

'采用Real Player API的播放器
Public Class RealAuidoPlayer
    
Implements AudioPlayer
    
Private mAP As AxRealAudioObjects.AxRealAudio
    
Public Sub New(ByVal c As Control)
        mAP 
= New AxRealAudioObjects.AxRealAudio
        c.Controls.Add(mAP)
        mAP.Visible 
= False
    
End Sub

    
Public Sub DoPause() Implements AudioPlayer.DoPause
        mAP.DoPause()
    
End Sub


    
Public Sub DoPlay() Implements AudioPlayer.DoPlay
        mAP.DoPlay()
    
End Sub


    
Public Sub DoStop() Implements AudioPlayer.DoStop
        mAP.DoStop()
    
End Sub


    
Public Property Source() As String Implements AudioPlayer.Source
        
Get
            
Return mAP.Source
        
End Get
        
Set(ByVal Value As String)
            mAP.Source 
= Value
        
End Set
    
End Property

End Class


'采用MS Media Player 的播放器类
Public Class MediaPlayer
    
Implements AudioPlayer
    
Private mAP As WMPLib.WindowsMediaPlayerClass
    
Private ms As String

    
Public Sub New()
        mAP 
= New WMPLib.WindowsMediaPlayerClass
    
End Sub


    
Public Sub DoPause() Implements AudioPlayer.DoPause
        mAP.pause()
    
End Sub


    
Public Sub DoPlay() Implements AudioPlayer.DoPlay
        mAP.play()
    
End Sub


    
Public Sub DoStop() Implements AudioPlayer.DoStop
        mAP.
stop()
    
End Sub


    
Public Property Source() As String Implements AudioPlayer.Source
        
Get
            
Return mAP.URL
        
End Get
        
Set(ByVal Value As String)
            mAP.URL 
= Value
            mAP.pause()
        
End Set
    
End Property

End Class

采用类适配器的结构如图所示。


以RealPlay为例,代码如下:
 1'采用Real Play API的播放器类,类适配器
 2Public Class RealAudioPlayerClass
 3    Inherits AxRealAudioObjects.AxRealAudio
 4    Implements AudioPlayer
 5
 6    Public Sub New(ByVal c As Control)
 7        c.Controls.Add(Me)
 8        Me.Visible = False
 9    End Sub

10
11    Public Sub DoPause() Implements AudioPlayer.DoPause
12        MyBase.DoPause()
13    End Sub

14
15    Public Sub DoPlay() Implements AudioPlayer.DoPlay
16        MyBase.DoPlay()
17    End Sub

18
19    Public Sub DoStop() Implements AudioPlayer.DoStop
20        MyBase.DoStop()
21    End Sub

22
23    Public Property Source() As String Implements AudioPlayer.Source
24        Get
25            Return MyBase.Source
26        End Get
27        Set(ByVal Value As String)
28            MyBase.Source = Value
29        End Set
30    End Property

31End Class

32


3..NET中的适配器——DataAdapter
        ADO.NET为统一的数据访问提供了多个接口和基类,其中最重要的接口之一是IdataAdapter。与之相对应的DataAdpter是一个抽象类,它是ADO.NET与具体数据库操作之间的数据适配器的基类。DataAdpter起到了数据库到DataSet桥接器的作用,使应用程序的数据操作统一到DataSet上,而与具体的数据库类型无关。甚至可以针对特殊的数据源编制自己的DataAdpter,从而使我们的应用程序与这些特殊的数据源相兼容。

        例如,在多数据源的数据采集系统中,需要从自定义实时数据库中读出并处理数据。我们已经有了数据处理类和数据显示类,这些类是为关系数据库开发的,但同样可以用在实时数据显示中。由于这些类操作的是DataSet,因此我们可以定义一个特殊的适配器实现从实时数据库接口对象中填充DataSe,这样使得针对这些自定义的数据库的操作与一般的关系数据库完全一样。由于针对实时数据库只涉及查询,不涉及更新和删除,所以实现并不复杂,其结构如图所示。

                           
 
        这里省略了实现的代码。采用数据适配器可以使不同格式的数据源都可以被相同的上层应用使用,从而提高了系统的可扩展性和可维护性。

posted on 2005-08-13 16:10  振河  阅读(2820)  评论(2编辑  收藏

  就他吧-9ta8伴您开心每一天