Adapter适配器(结构型模式)

适配 ( 转换 ) 的概念无处不在……

适配,即在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口。

(即编写一个具有所需要的接口的类,然后让它和拥有不同接口的类进行通信)

 

动机:

在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。

如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?

意图:

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

结构——对象适配器:

把原始类包含在新类里,然后在新类里创建方法去转换调用。 

结构——类适配器:

从一个不一致的类里派生出一个新类,然后添加需要的方法,使新的派生类能匹配所需要的接口。

Adapter模式的几个要点:

l         Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。

l         GoF23定义了两钟Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。

l         Adapter模式可以实现的非常灵活,不必拘泥于GoF23中定义的两中结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。

l         Adapter模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。

 

.NET框架中的Adapter应用

l         .NET中复用COM对象:

COM对象不符合.NET对象的借口

使用tlbimp.exe来创建一个Runtime Callable Wrapper(RCW)以使其符合.NET对象的接口。

l         .NET数据访问类(Adapter变体)
 
各种数据库并没有提供DataSet接口

      使用DbDataAdapter可以将任何各数据库访问/存取适配到一个DataSet对象上。

l         集合类中对现有对象的排序(Adapter变体)

      现有对象未实现IComparable接口

      实现一个排序适配器(继承IComparer接口),然后在其Compare方法中对两个对象进行比较

 

Swimmer.cs代码示例:

using  System;
using  CsharpPats;
namespace  LstAdapter
{
    
/// <summary>
    
/// Summary description for Swimmer.
    
/// </summary>

    public class Swimmer:IComparable     {
        
private string name;         //name
        private string lname, frname;//split names
        private int age;            //age
        private string club;        //club initials
        private float time;            //time achieved
        private bool female;        //sex
    
//---------
        public Swimmer(string line) {
            StringTokenizer tok 
= new StringTokenizer(line,",");
            splitName(tok);
            age 
= Convert.ToInt32 (tok.nextToken());
            club 
= tok.nextToken();
            time 
= Convert.ToSingle (tok.nextToken());
            
string sx = tok.nextToken().ToUpper ();
            female 
= sx.Equals ("F");
        }

        
//---------
        private void splitName(StringTokenizer tok) {
            name 
= tok.nextToken();
            
int i = name.IndexOf (" ");
            
if(i >0 ) {
                frname 
= name.Substring (0, i);
                lname 
= name.Substring (i+1).Trim ();
            }

        }

        
//---------
        public int CompareTo(object swo) {
            Swimmer sw 
= (Swimmer)swo;
            
return lname.CompareTo (sw.getLName() );
        }

        
//---------
        public bool isFemale() {
            
return female;
        }

        
//---------
        public int getAge() {
            
return age;
        }

        
//---------
        public float getTime() {
            
return time;
        }

        
//---------
        public string getName() {
            
return name;
        }

        
//---------
        public string getClub() {
            
return club;
        }

        
//---------
        public string getLName() {
            
return lname;
        }

    }

}


SwimData.cs代码示例:

using  System;
using  System.Collections ;
using  CsharpPats;

namespace  LstAdapter
{
    
/// <summary>
    
/// Summary description for SwimData.
    
/// </summary>

    public class SwimData:ICloneable     {
        
protected ArrayList swdata;
        
private int index;
        
//-----
        public SwimData() {
                swdata 
= new ArrayList ();
        }

        
//-----
        public SwimData(ArrayList swd) {
            swdata 
= swd;
            index
=0;
        }

        
//-----
        public int count() {
            
return swdata.Count ;
        }

        
//-----
        public SwimData(string filename)         {
            swdata 
= new ArrayList ();
            csFile fl 
= new csFile(filename);
            fl.OpenForRead ();
            
string s = fl.readLine ();
            
while(s != null{
                Swimmer sw 
= new Swimmer(s);
                swdata.Add (sw);
                s 
= fl.readLine ();
            }

            fl.close ();
        }

        
//-----
        public object Clone() {
            SwimData newsd 
= new SwimData(swdata);
            
return newsd;
        }

        
//-----
        public void moveFirst() {
            index 
= 0;
        }

        
//-----
        public bool hasMoreElements() {
            
return (index < swdata.Count-1 );
        }

        
//-----
        public void sort() {
        
//sort using IComparable interface of Swimmer
            swdata.Sort (0,swdata.Count ,null);
        }

        
//-----
        public Swimmer getSwimmer(int index) {
            
if(index < swdata.Count && index >=0)
                
return (Swimmer)swdata[index++];
            
else
                
return null;
        }

        
//-----
        public Swimmer getSwimmer() {
            
if(index < swdata.Count )
                
return (Swimmer)swdata[index++];
            
else
                
return null;
        }

    }

}


ListAdapter.cs代码示例:

using  System;
using  System.Windows.Forms;

namespace  LstAdapter
{
    
/// <summary>
    
/// Summary description for ListAdapter.
    
/// </summary>

    public class ListAdapter     {
        
private ListBox listbox;    //operates on this one
        public ListAdapter(ListBox lb)         {
            listbox 
= lb;
        }

        
//-----
        public void Add(string s) {
            listbox.Items.Add (s);
        }

        
//-----
        public void Add(Swimmer sw) {
            listbox.Items.Add (sw.getName()
+" "+sw.getTime());
        }

        
//-----
        public int SelectedIndex() {
            
return listbox.SelectedIndex;
        }

        
//-----
        public void Clear() {
            listbox.Items.Clear ();
        }

        
//-----
        public void clearSelection() {
            
int i = SelectedIndex();
            
if(i >= 0{
                listbox.SelectedIndex 
=-1;
            }

        }

    }

}


StringTokenizer.cs代码示例:

using  System;

namespace  CsharpPats
{
    
//String Tokenizer class
    public class StringTokenizer     {
        
private string data, delimiter;
        
private string[] tokens;
        
private int index;
        
public StringTokenizer(string dataLine)         {
            init(dataLine, 
" ");
                }

        
private void init(String dataLine, string delim) {
            delimiter 
= delim;
            data 
= dataLine;
            tokens 
= data.Split (delimiter.ToCharArray() );
            index 
= 0;
        }

        
public StringTokenizer(string dataLine, string delim) {
           init(dataLine, delim);    
        }

        
public bool hasMoreElements() {
            
return (index < (tokens.Length));
        }

        
public string nextToken() {
            
return nextElement();
        }

        
public string nextElement() {
            
string s = tokens[index++];
            
while((s.Length <=0&& (index<tokens.Length ))
                s 
= tokens[index++];
        
return s;
        }

    }

}


CsFile.cs代码示例:

using  System;
using  System.IO ;
namespace  CsharpPats
{
    
/// <summary>
    
/// A simple file handlng class
    
/// </summary>

    public class csFile
    
{
        
private string fileName;
        StreamReader ts;
        StreamWriter ws;
        
private bool opened, writeOpened;
        
//-----------
        public csFile() {
            init();
        }

        
//-----------
        private void init() {
            opened 
= false;
            writeOpened 
= false;
        }

        
//-----------
        public csFile(string file_name)     {
            fileName 
= file_name;
            init();
        }

        
//-----------
        public bool OpenForRead(string file_name){
            fileName 
= file_name;
            
try {
                ts 
= new StreamReader (fileName);
                opened
=true;
            }

            
catch(FileNotFoundException ) {
                
return false;
            }

            
return true;
        }

        
//-----------
        public bool OpenForRead() {
            
return OpenForRead(fileName);
        }

        
//-----------
        public string readLine() {
            
return ts.ReadLine ();
        }

        
//-----------
        public void writeLine(string s) {
            ws.WriteLine (s);
        }

        
//-----------
        public void close() {
            
if (opened)
                ts.Close ();
            
if(writeOpened)
                ws.Close();
        }

        
//-----------
        public bool OpenForWrite() {
            
return OpenForWrite(fileName);
        }

        
//-----------
        public bool OpenForWrite(string file_name) {
            
try{
                ws 
= new StreamWriter (file_name);
                fileName 
= file_name;
                writeOpened 
= true;
                
return true;
            }

            
catch(FileNotFoundException ) {
                
return false;
            }

        }

    }

}


事件代码:

private   void  init()  {
            swdata 
= new SwimData ("swimmers.txt");
            lskids
= new ListAdapter (lsKids);
            lsnewKids 
=  new ListAdapter (lsNewKids);
            reload();
        }


private   void  reload()  {
            lskids.Clear ();
            swdata.moveFirst ();
            
while (swdata.hasMoreElements() ) {
                Swimmer sw 
= swdata.getSwimmer ();
                lskids.Add (sw.getName() );
            }


private   void  btClone_Click( object  sender, EventArgs e)  {
            
int i = lskids.SelectedIndex ();
            
if( i >= 0{
                Swimmer sw 
= swdata.getSwimmer (i);
                lsnewKids.Add (sw.getName() 
+" "+sw.getTime ());
                lskids.clearSelection ();
            }

        }


private   void  btBack_Click( object  sender, System.EventArgs e)  {
            reload();
        }


private   void  putBack_Click( object  sender, EventArgs e)  {
            
int i = lsnewKids.SelectedIndex ();
            
if(i >= 0)
                lsNewKids.Items.RemoveAt (i); 
        }


使用DataGrid

LstAdapter.cs代码示例:

using  System;

namespace  GridAdapt
{
    
/// <summary>
    
/// Summary description for LstAdapter.
    
/// </summary>

    public interface LstAdapter     {
         
void Add(Swimmer sw) ;
         
int SelectedIndex() ;
         
void Clear() ;
         
void clearSelection() ;
    }

}


GridAdapter.cs代码示例:

using  System;
using  System.Windows.Forms ;
using  System.Data;
namespace  GridAdapt
{
    
/// <summary>
    
/// Summary description for GridAdapter.
    
/// </summary>

    public class GridAdapter:LstAdapter     {
        
private DataGrid grid;
        
private DataTable dTable;
        
private int row;
        
//-----
        public GridAdapter(DataGrid grd)         {
            grid 
= grd;
            dTable 
= (DataTable)grid.DataSource;
            grid.MouseDown 
+=new System.Windows.Forms.MouseEventHandler (Grid_Click);
            row 
= -1;        
        }

        
//-----
        public void Grid_Click(object sender, System.Windows.Forms.MouseEventArgs  e) {
            DataGrid.HitTestInfo hti 
= grid.HitTest (e.X, e.Y);
            
if(hti.Type  == DataGrid.HitTestType.Cell ){
                row 
= hti.Row ;
            }

        }

        
//-----
        public void Add(Swimmer sw) {
            DataRow row 
= dTable.NewRow();
            row[
"Frname"= sw.getFrname();
            row[
1= sw.getLName();
            row[
2= sw.getAge();  //This one is an integer
            dTable.Rows.Add(row);
            dTable.AcceptChanges();
        }

        
//-----
        public int SelectedIndex() {
            
return row;
        }

        
//-----
        public void Clear() {
            
int  count = dTable.Rows.Count ;
            
for(int i=0; i< count; i++{
                dTable.Rows[i].Delete ();
            }

        }

        
//-----
        public void clearSelection() {}
    }

}


事件代码:

private   void  init()  {
            swdata 
= new SwimData ("swimmers.txt");
            lskids
= new ListAdapter (lsKids);
            createGrid();    
            lsNewKids 
=  new GridAdapter (dGrid);
            reload();
        }


private   void  createGrid()  {
            dTable 
= new DataTable("Kids");
            dTable.MinimumCapacity 
= 100;
            dTable.CaseSensitive 
= false;

            DataColumn column 
= 
                
new DataColumn("Frname",System.Type.GetType("System.String"));
            dTable.Columns.Add(column);
            column 
= new DataColumn("Lname", System.Type.GetType("System.String"));
            dTable.Columns.Add(column);
            column 
= new DataColumn("Age", System.Type.GetType("System.Int16"));

            dTable.Columns.Add(column);

            dGrid.DataSource 
= dTable;
            dGrid.CaptionVisible 
= false;    //no caption
            dGrid.RowHeadersVisible = false//no row headers
            dGrid.EndInit();
        
        }


private   void  reload()  {
            lskids.Clear ();
            swdata.moveFirst ();
            
while (swdata.hasMoreElements() ) {
                Swimmer sw 
= swdata.getSwimmer ();
                lskids.Add (sw.getName() );
            }


private   void  btClone_Click( object  sender, System.EventArgs e)  {
            
int i = lskids.SelectedIndex ();
            
if( i >= 0{
                Swimmer sw 
= swdata.getSwimmer (i);
                lsNewKids.Add (sw);
                lskids.clearSelection ();
            }

        }


private   void  btBack_Click( object  sender, System.EventArgs e)  {
            reload();
        }


使用TreeView

TreeAdapter.cs代码示例:

using  System;
using  System.Windows.Forms;
namespace  TreeAdapt
{
    
/// <summary>
    
/// Summary description for TreeAdapter.
    
/// </summary>

    public class TreeAdapter:LstAdapter     {
        
private TreeView tree;
        
//------
        public TreeAdapter(TreeView tr)         {
            tree
=tr;
        }

        
//------
        public void Add(Swimmer sw) {
            TreeNode nod;
        
//add a root node  
            nod = tree.Nodes.Add(sw.getName());
        
//add a child node to it
        nod.Nodes.Add(sw.getTime().ToString ());
        tree.ExpandAll ();
        }

        
//------
        public int SelectedIndex() {
            
return tree.SelectedNode.Index ;
        }

        
//------
        public void Clear() {
        TreeNode nod;
            
for (int i=0; i< tree.Nodes.Count ; i++{
                nod 
= tree.Nodes [i];
                nod.Remove ();
            }

        }

        
//------
        public void clearSelection() {}
    }

}


事件代码:

private   void  init()  {
            swdata 
= new SwimData ("swimmers.txt");
            lskids
= new ListAdapter (lsKids);
            lsNewKids 
=  new TreeAdapter (Tree);
            reload();
        }


private   void  reload()  {
            lskids.Clear ();
            swdata.moveFirst ();
            
while (swdata.hasMoreElements() ) {
                Swimmer sw 
= swdata.getSwimmer ();
                lskids.Add (sw.getName() );
            }

        
        }


private   void  btClone_Click( object  sender, System.EventArgs e)  {
            
int i = lskids.SelectedIndex ();
            
if( i >= 0{
                Swimmer sw 
= swdata.getSwimmer (i);
                lsNewKids.Add (sw);
                lskids.clearSelection ();
            }

        }


private   void  btBack_Click( object  sender, System.EventArgs e)  {
            reload();
        }


类适配器

using  System;
using  System.Collections;
using  System.ComponentModel;
using  System.Drawing;
using  System.Data;
using  System.Windows.Forms;

namespace  ClassAdapt
{
    
public class MyList : System.Windows.Forms.ListBox, ListAdapter {
        
private System.ComponentModel.Container components = null;
      
//-----
        public MyList()         {
            InitializeComponent();
        }

        
//-----
        public void Add(string s) {
            
this.Items.Add (s);
        }

        
//-----
        public void Add(Swimmer sw) {
            
this.Items.Add (sw.getName() + 
                
" " + sw.getAge ().ToString () );
        }

        
//-----
        public void Clear() {
            
this.Items.Clear ();
        }

        
//-----
        public void clearSelection() {
            
this.SelectedIndex = -1;
        }

        
protected override void Dispose( bool disposing )
        
{
            
if( disposing )
            
{
                
if(components != null)
                
{
                    components.Dispose();
                }

            }

            
base.Dispose( disposing );
        }


        
Component Designer generated code
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值