C# 理解适配器模式

C# 理解适配器模式,c#,design-patterns,adapter,C#,Design Patterns,Adapter,我试图了解适配器模式及其在现实世界中的使用。在浏览了互联网和www.dofactory.com上的各种文章之后,我创建了这个示例代码。我只是想知道我的理解是否正确。在下面的示例中,我在适配器类中创建了MSDAO对象。后来我把它改成了OracleDAO 类客户端 { 静态void Main(字符串[]参数) { ITarget objAdapter=新适配器(); 对象dummyObject=objAdapter.GetData(); } } 接口目标 { public void GetData(

我试图了解适配器模式及其在现实世界中的使用。在浏览了互联网和www.dofactory.com上的各种文章之后,我创建了这个示例代码。我只是想知道我的理解是否正确。在下面的示例中,我在适配器类中创建了MSDAO对象。后来我把它改成了OracleDAO

类客户端
{
静态void Main(字符串[]参数)
{
ITarget objAdapter=新适配器();
对象dummyObject=objAdapter.GetData();
}
}
接口目标
{
public void GetData();
}
//使用MSDAO的决定
类适配器:ITarget
{
public void GetData()
{
MSDAO objmsdao=新的MSDAO();
objmsdao.GetData();
}
}
//一个月后,决定使用OracaleDAO,因此代码发生了变化
类适配器:ITarget
{
public void GetData()
{
OracleDAO objoracledao=新的OracleDAO();
objoracledao.GetData();
}
}

通常,适配器模式将一个接口转换为另一个接口,但它可以简单地包装行为,将类与底层实现隔离开来。在您的例子中,您使用的是适配器,但是您也可以很容易地定义DAO对象来简单地实现接口并根据接口编程。适配器模式通常在您无法控制目标类时使用。适配器模式的主要用途是为未实现接口的框架类创建包装器

假设我想模拟一个框架类,它没有实现接口(也没有虚拟方法)。对于许多模拟API,这是很难或不可能做到的。那么,我要做的就是将我自己的接口定义为我所针对的类的签名的子集。我实现了一个实现这个接口的包装器类,并将调用简单地委托给包装好的框架类。此包装器类用作框架类的适配器。我的类使用这个适配器而不是框架类,但是得到框架类的行为

 public interface IFoo
 {
     void Bar();
 }

 public class FooWrapper : IFoo
 {
      private FrameworkFoo Foo { get; set; }

      public FooWrapper( FrameworkFoo foo )
      {
           this.Foo = foo;
      }

      public void Bar()
      {
           this.Foo.Bar();
      }
 }
还可以考虑这样一种情况,即您有两个不同的类,它们具有基本相同的功能,但签名不同,并且希望能够互换使用它们。如果您不能转换这些(或者由于其他原因不想转换),您可能需要编写一个适配器类,该类定义一个公共接口,并在该接口的方法和目标类上可用的方法之间进行转换

框架类:

public class TargetA
{
    public void Start() { ... }
    public void End() { ... }
}

public class TargetB
{
    public void Begin() { ... }
    public void Terminate() { ... }
}
它们的适配器

public interface ITargetAdapter
{
    void Open();
    void Close();
}

public class AdapterA : ITargetAdapter
{
     private TargetA A { get; set; }

     public AdapterA( TargetA a )
     {
           this.A = a;
     }

     public void Open() { this.A.Start(); }
     public void Close() { this.A.End(); }
}

public class AdapterB : ITargetAdapter
{
     private TargetB B { get; set; }

     public AdapterB( TargetB a )
     {
           this.B = a;
     }

     public void Open() { this.B.Begin(); }
     public void Close() { this.B.Terminate(); }
}
然后用作:

ITargetAdapter adapter = new AdapterA( new TargetA() );
adapter.Open();
adapter.Close();     

类中存在.NET framework内部的规范示例

此位图有一个构造函数,可用于从以下位置加载图像:

您不知道的是,.NET
Bitmap
类在内部是GDI+类的包装器,其构造函数采用:

所以在C#world,当我打电话时:

new Bitmap(stream);
它必须掉头呼叫:

IStream stm;
IntPtr gpBitmap;
GdipCreateBitmapFromStream(stm, out gpBitmap);
问题是如何将.NET对象呈现给需要COMIStream接口的方法

因此,内部
GPStream
类:

internal class GPStream : IStream
{
   GPStream(Stream stream) { ... }
}
您需要向您的
对象提供一个
IStream
接口:

IStream                                     Stream
=======================================     =====================================
int Read(IntPtr buf, int len);          --> int Read(byte[] buffer, int offset, int count)
int Write(IntPtr buf, int len);         --> void Write(byte[] buffer, int offset, int count);
long Seek(long dlibMove, int dwOrigin); --> long Seek(long offset, SeekOrigin orgin)
...                                         ...
现在您有了一个适配器:

代码是这样的:

IStream stm = new GPStream(stream); //adapter to convert Stream --> IStream
IntPtr gpBitmap;

GdipCreateBitmapFromStream(stm, out gpBitmap);

我添加了一些评论,希望能帮助您了解整个适配器/适配器/客户端/Itarget术语,这有点让人困惑:

internal class Program
{
    private static void Main(string[] args)
    {
        // Brian and freddie know only how to say Greetings. But when they tour
        // internationally, they will need a translator so when they say Greetings()
        // the appropriate non-English response comes out of their mouth.
        // they need to make use of the adapter pattern:

        // When in Japan:
        ITarget translator = new JapaneseTranslator(new JapaneseSpeaker());
        EnglishMan freddie = new EnglishMan(translator);

        // Freddie greets Tokyo, though he doesn't know a word of Japanese
        Console.WriteLine(freddie.Greetings()); //  "teo torriatte!"

        // when in France:
        ITarget translator2 = new FrenchTranslator(new FrenchSpeaker());
        EnglishMan brian = new EnglishMan(translator2);

        // Brian greets the crowd in Paris, though he doesn't know a word in French
        Console.WriteLine(brian.Greetings()); 
          // "So très charmant my dear! Bonjour"

        // alternatively, the translators can also do the greeting:
        Console.WriteLine(translator.Greetings());  //  "Konichiwa, hisashiburi!"
        Console.WriteLine(translator2.Greetings()); // "Bonjour!"
    }

    /// <summary>
    /// This is the client.
    /// </summary>
    public class EnglishMan : ITarget
    {
        private ITarget target;

        public EnglishMan(ITarget target)
        {
            this.target = target;
        }

        public string Greetings()
        {
            return target.Greetings();
        }
    }

    /// <summary>
    /// The target interface
    /// </summary>
    public interface ITarget
    {
        string Greetings();
    }

    /// <summary>
    /// This is the adaptor
    /// </summary>
    public class JapaneseTranslator : ITarget
    {
        private JapaneseSpeaker japanese;

        public JapaneseTranslator(JapaneseSpeaker japanese)
        {
            this.japanese = japanese;
        }

        public string Greetings()
        {
            return japanese.Konnichiwa();
        }
    }

    /// <summary>
    /// This is the adaptee
    /// </summary>
    public class JapaneseSpeaker
    {
        public JapaneseSpeaker()
        {
        }

        public string Konnichiwa()
        {
            return "Konichiwa, hisashiburi!";
        }
    }

    /// <summary>
    /// This is the adaptor
    /// </summary>
    public class FrenchTranslator : ITarget
    {
        private FrenchSpeaker french;

        public FrenchTranslator(FrenchSpeaker french)
        {
            this.french = french;
        }

        public string Greetings()
        {
            return french.Bonjour();
        }
    }

    /// <summary>
    /// This is the adaptee
    /// </summary>
    public class FrenchSpeaker
    {
        public string Bonjour()
        {
            return "Bonjour!!";
        }
    }
}
内部类程序
{
私有静态void Main(字符串[]args)
{
//布莱恩和弗雷迪只会打招呼。但是当他们巡演的时候
//在国际上,他们需要一名翻译,所以当他们说问候语时()
//适当的非英语回答出自他们的口中。
//他们需要使用适配器模式:
//在日本时:
ITarget translator=新日语翻译程序(新日语说话者());
英国人弗雷迪=新英国人(翻译);
//弗雷迪向东京打招呼,尽管他一句日语都不懂
Console.WriteLine(freddie.hellives());/“teo torriatte!”
//在法国时:
ITarget translator 2=新法语Translator(新法语说话者());
英国人布莱恩=新英国人(翻译员2);
//布莱恩在巴黎向人群致意,尽管他一个法语单词都不懂
Console.WriteLine(brian.hellives());
//“亲爱的,查曼特先生!你好”
//或者,翻译人员也可以做问候语:
Console.WriteLine(translator.hellives());/“Konichawa,hisashiburi!”
Console.WriteLine(translator2.Greetings());/“你好!”
}
/// 
///这是客户。
/// 
公务舱英国人:ITarget
{
私有目标;
英国公众人物(ITarget target)
{
this.target=目标;
}
公共字符串问候语()
{
返回target.Greetings();
}
}
/// 
///目标接口
/// 
公共接口ITarget
{
字符串问候语();
}
/// 
///这是适配器
/// 
公共类日本翻译:ITarget
{
私人日本人说日语;
公共日语翻译(日语口语)
{
这个。日语=日语;
}
公共字符串问候语()
{
返回日语。Konnichiwa();
}
}
/// 
///这是改编者
/// 
公务舱日语说话者
{
公共日语说话者()
{
}
公共字符串Konnichiwa()
{
返回“Konichiwa,hisashiburi!”;
}
}
/// 
///这是适配器
/// 
公共类法语翻译:ITarget
{
私人法语说话者法语;
公共法语翻译(法语说话者法语)
{
法语=法语;
}
IStream stm = new GPStream(stream); //adapter to convert Stream --> IStream
IntPtr gpBitmap;

GdipCreateBitmapFromStream(stm, out gpBitmap);
internal class Program
{
    private static void Main(string[] args)
    {
        // Brian and freddie know only how to say Greetings. But when they tour
        // internationally, they will need a translator so when they say Greetings()
        // the appropriate non-English response comes out of their mouth.
        // they need to make use of the adapter pattern:

        // When in Japan:
        ITarget translator = new JapaneseTranslator(new JapaneseSpeaker());
        EnglishMan freddie = new EnglishMan(translator);

        // Freddie greets Tokyo, though he doesn't know a word of Japanese
        Console.WriteLine(freddie.Greetings()); //  "teo torriatte!"

        // when in France:
        ITarget translator2 = new FrenchTranslator(new FrenchSpeaker());
        EnglishMan brian = new EnglishMan(translator2);

        // Brian greets the crowd in Paris, though he doesn't know a word in French
        Console.WriteLine(brian.Greetings()); 
          // "So très charmant my dear! Bonjour"

        // alternatively, the translators can also do the greeting:
        Console.WriteLine(translator.Greetings());  //  "Konichiwa, hisashiburi!"
        Console.WriteLine(translator2.Greetings()); // "Bonjour!"
    }

    /// <summary>
    /// This is the client.
    /// </summary>
    public class EnglishMan : ITarget
    {
        private ITarget target;

        public EnglishMan(ITarget target)
        {
            this.target = target;
        }

        public string Greetings()
        {
            return target.Greetings();
        }
    }

    /// <summary>
    /// The target interface
    /// </summary>
    public interface ITarget
    {
        string Greetings();
    }

    /// <summary>
    /// This is the adaptor
    /// </summary>
    public class JapaneseTranslator : ITarget
    {
        private JapaneseSpeaker japanese;

        public JapaneseTranslator(JapaneseSpeaker japanese)
        {
            this.japanese = japanese;
        }

        public string Greetings()
        {
            return japanese.Konnichiwa();
        }
    }

    /// <summary>
    /// This is the adaptee
    /// </summary>
    public class JapaneseSpeaker
    {
        public JapaneseSpeaker()
        {
        }

        public string Konnichiwa()
        {
            return "Konichiwa, hisashiburi!";
        }
    }

    /// <summary>
    /// This is the adaptor
    /// </summary>
    public class FrenchTranslator : ITarget
    {
        private FrenchSpeaker french;

        public FrenchTranslator(FrenchSpeaker french)
        {
            this.french = french;
        }

        public string Greetings()
        {
            return french.Bonjour();
        }
    }

    /// <summary>
    /// This is the adaptee
    /// </summary>
    public class FrenchSpeaker
    {
        public string Bonjour()
        {
            return "Bonjour!!";
        }
    }
}
 interface ITarget
    {
      List<string> GetProducts();
    }


    public class VendorAdaptee
    {
       public List<string> GetListOfProducts()
       {
          List<string> products = new List<string>();
          products.Add("Gaming Consoles");
          products.Add("Television");
          products.Add("Books");
          products.Add("Musical Instruments");
          return products;
       }
    }


    class VendorAdapter:ITarget
    {
       public List<string> GetProducts()
       {
          VendorAdaptee adaptee = new VendorAdaptee();
          return adaptee.GetListOfProducts();
       }
    }


    class ShoppingPortalClient
    {
       static void Main(string[] args)
       {
          ITarget adapter = new  VendorAdapter();
          foreach (string product in adapter.GetProducts())
          {
            Console.WriteLine(product);
          }
          Console.ReadLine();
       }
    }