我只是设计模式的初学者,只是学习了理论定义以及如何在代码中实现,但是喜欢了解鼓励使用适配器模式的各种现实情况/案例/场景?
C#中的例子表示赞赏。
答案 0 :(得分:5)
假设您有一个解析HTML文件的类,以确保它们有效。它看起来像这样:
public class Parser
{
public Parser(string filePath)
{
...
}
public void Parse()
{
...
}
public bool IsValid()
{
...
}
}
让我们假设您在应用程序中使用它。应用程序代码可能如下所示:
Parser p = new Parser("file.html");
p.Parse();
if(p.IsValid())
print "yay"
else
print "lame"
你写了Parser
课,它的效果很好,但是你的朋友写了另一个更好的作品。让我们说他们的课程看起来像这样:
public class BetterParser
{
public bool ParseHtml(FileStream fs)
{
...
}
}
现在您想要使用朋友的BetterParser
课而不是Parser
课程,但它并不适用于您的代码,因为它有不同的方法名称和略有不同的工作方式。您可以将上面的应用程序代码更改为以下内容:
FileStream fs = GetStream("test.html")
BetterParser bp = new BetterParser()
if(bp.ParseHtml(fs))
print "yay"
else
print "lame"
这很好,但是如果你有一个大型应用程序,你的Parser
类在哪里被使用呢?您可能不想真正改变它所使用的所有地方,因为这需要大量的额外测试和潜在的错误。
您可以做的是使用适配器模式将您的类更改为在其实现中实际使用您朋友的类。
class Parser
{
private BetterParser bp = new BetterParser();
private FileStream fs;
private boolean successful;
public Parser(string file)
{
fs = GetStream(file);
}
public void Parse()
{
successful = bp.ParseHtml(fs);
}
public boolean IsValid()
{
return successful;
}
}
你可以看到你的课程的实现现在在幕后使用你朋友的课程。所以现在使用Parser类的所有代码都不需要改变,你仍然可以使用更好的解析器。
这基本上就是适配器模式的全部内容。它连接两个不能直接相互连接的东西。在这种情况下,Parser类曾经是一个普通的HTML解析器,但它变成了一个适配器,将你的应用程序代码连接到朋友的解析器。
所有这些都是关于将接口与实现分离。您的应用程序代码不应该依赖于解析器类在内部的工作方式,而是必须依赖于该类的接口。事实上,类有一个构造函数,它接受一个文件路径,它有一个名为Parse
的方法,不带参数,以及一个名为IsValid
的方法返回一个布尔值。这些是类接口的所有方面,如果该接口发生更改,您的应用程序也无法再使用该类而不进行更改。因此,您保持接口相同并更改实现。
它比班级
更大人们经常说适配器只是另一个类的“包装器”。在代码级别的适配器上,这可能很多时候都是如此。但是,整个应用程序也可以用作适配器。假设您有一些服务器提供了一些XML Web服务API(即SOAP)。这意味着与之交谈的所有客户都需要了解XML。如果你想连接一个不会说XML的客户端(也许它使用JSON)怎么办?一个选项是在服务器和JSON框之间放一个框。这个新框将作为可以在XML和JSON之间进行转换的适配器。客户端使用JSON与适配器通信,适配器使用XML与服务器通信。
答案 1 :(得分:0)
您可以考虑查看http://www.dofactory.com/net/adapter-design-pattern一两个例子。
AlexAtNet说“适配器”是“包装器”是正确的。如果您的消费者需要特定的接口但是您的源类具有不同的接口,那么您需要构建源的适配器以匹配消费者期望的接口。这里有一篇关于适配器与网桥的文章:http://fernandozamorajimenez.blogspot.com/2009/12/as-i-was-preparing-for-upcoming.html