了解适配器模式
我试图了解适配器模式及其在现实世界中的使用。 在浏览了互联网和 www.dofactory.com 上的各种文章后,我创建了这个示例代码。 我只是想知道我的理解是否正确。 在下面的示例中,我在 Adapter 类中创建了 MSDAO 对象。 后来我把它改成了OracleDAO。
class Client
{
static void Main(string[] args)
{
ITarget objAdapter = new Adapter();
object dummyObject = objAdapter.GetData();
}
}
Interface ITarget
{
public void GetData();
}
//Decision to use MSDAO
class Adapter : ITarget
{
public void GetData()
{
MSDAO objmsdao = new MSDAO();
objmsdao.GetData();
}
}
//After a month, the decision to use OracaleDAO was taken, so the code change
class Adapter : ITarget
{
public void GetData()
{
OracleDAO objoracledao = new OracleDAO();
objoracledao.GetData();
}
}
I am trying to understand Adapter pattern and its use in real world. After going through various articles on internet and www.dofactory.com, I created this sample code. I just want to know whether my understanding is correct. In the example below I have created MSDAO object in the Adaptor class. Later I changed it to OracleDAO.
class Client
{
static void Main(string[] args)
{
ITarget objAdapter = new Adapter();
object dummyObject = objAdapter.GetData();
}
}
Interface ITarget
{
public void GetData();
}
//Decision to use MSDAO
class Adapter : ITarget
{
public void GetData()
{
MSDAO objmsdao = new MSDAO();
objmsdao.GetData();
}
}
//After a month, the decision to use OracaleDAO was taken, so the code change
class Adapter : ITarget
{
public void GetData()
{
OracleDAO objoracledao = new OracleDAO();
objoracledao.GetData();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
通常,适配器模式将一个接口转换为另一个接口,但它可以简单地包装行为以将您的类与底层实现隔离。 在您的例子中,您使用的是适配器,但您可以轻松地定义 DAO 对象来简单地实现接口并针对接口进行编程。 当您无法控制目标类时,通常会使用适配器模式。 我对适配器模式的主要用途是为不实现接口的框架类创建包装器。
假设我想模拟一个没有实现接口(并且没有虚拟方法)的框架类。 对于许多模拟 API,这是很难或不可能做到的。 然后,我要做的就是将我自己的接口定义为我所针对的类的签名的子集。 我实现了一个包装类,该类实现了该接口,并简单地将调用委托给包装的框架类。 该包装类充当框架类的适配器。 我的类使用此适配器而不是框架类,但获得框架类的行为。
还要考虑这样的情况:您有几个不同的类,它们具有基本相同的功能,但签名不同,并且您希望能够互换使用它们。 如果您无法转换这些(或者由于其他原因不想这样做),您可能需要编写一个适配器类来定义一个公共接口并在该接口的方法与目标类上可用的方法之间进行转换。
框架类:
它们的适配器
然后用作:
Generally the adapter pattern transforms one interface into another, but it can simply wrap the behavior to isolate your class from the underlying implementation. In your case, you are using an adapter, but you could just as easily have defined the DAO objects to simply implement the interface and programmed against the interface. The adapter pattern is usually used when you don't have control over the target class. My primary use of the adapter pattern would be to create wrappers for a framework class that doesn't implement an interface.
Say I want to mock out a framework class which doesn't implement an interface (and doesn't have virtual methods). With many mocking apis this is hard or impossible to do. What I will do, then, is define my own interface as a subset of the signature of the class I'm targeting. I implement a wrapper class that implements this interface and simply delegates the calls to the wrapped framework class. This wrapper class works as an adapter for the framework class. My classes use this adapter instead of the framework class, but get the framework class' behavior.
Consider also the case where you have a couple of different classes that have basically the same functionality, but different signatures and you want to be able to use them interchangeably. If you can't transform these (or don't want to for other reasons), you may want to write an adapter class that defines a common interface and translates between that interface's methods and the methods available on the target classes.
Framework classes:
An adapter for them
Then used as:
.NET 框架内的规范示例位于
System.Drawing.Bitmap
类。此位图有一个构造函数,可让您从
Stream
:您不知道的是,.NET
Bitmap
类在内部是 GDI+位图
类,及其构造函数采用IStream
:所以在 C# 世界中,当我调用:
它必须转身调用:
问题是如何呈现一个 . NET Stream 对象到需要 COM IStream 接口的方法。
因此,内部
GPStream
类:您需要向您的
Stream
对象提供一个IStream
接口:所以现在您有了一个适配器:
代码是这样的:
A canonical example inside the .NET framework exists in the
System.Drawing.Bitmap
class.This Bitmap has a constructor that lets you load an image from a
Stream
:what you don't know, is that internally the .NET
Bitmap
class is a wrapper around the GDI+Bitmap
class, and its constructor that takes anIStream
:So in the C# world, when i call:
it has to turn around and call:
The question is how to present a .NET Stream object to a method that expects a COM IStream interface.
Hence the internal
GPStream
class:You need to present an
IStream
interface to yourStream
object:So now you have an adapter:
And the code is something like:
我会保持非常简单。 如果一个调用者想要调用
MSDAO
的GetData
方法,而另一个调用者想要调用OracleDAO
,该怎么办?或者将来还可以添加其他类。
在这种情况下,您的解决方案将不起作用。
因此,我建议将 GetData 方法声明为适配器类的虚拟方法。
添加新的适配器类,扩展适配器类并实现您的
ITarget
接口,并相应地实现GetData
(声明它override
)方法。如果以后有新课程,请重复上述步骤。
I’ll keep it very simple. What if one caller wants to call the
GetData
method ofMSDAO
and other caller wantsOracleDAO
.Or in future other class can also be added.
In that case your solution will not work.
So I would suggest to declare the
GetData
method asvirtual
of the adaptee class.Add a new adapter class, extend the adaptee class and implement your
ITarget
interface and implement theGetData
(declare itoverride
) method accordingly.Repeat the above step if you will have new class in future.