标签:数据 阶段 specific 插入 net 实例 png str 定义
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。
Adpater模式又叫包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
Adapter模式一般包含两个版本:类适配器模式和对象适配器模式。类适配器模式通过继承一个类与接口(Java、C#等不支持多重继承的语言),在接口的实现中调用适配者的方法,如下图所示。
对象适配器通过对象的组合,适配器类中包含适配者的实例对象,在接口的实现方法中调用实例对象的方法。
适配器,对Adaptee与Target进行适配。
适配者,提供一个方法,但这个方法与Target接口不兼容,需要适配。
特定领域相关使用的接口。
假设我们有一个转换器程序,能够将系统中的数据导出到不同格式的文件,只需要实现IExporter接口,客户端就可以动态调用程序输出不同格式的文件。
interface IExporter
{
void Export();
}
class ExportToExcel : IExporter
{
public void Export()
{
Console.WriteLine("Export to Excel...");
}
}
//客户端调用
static void Main(string[] args)
{
IExporter exporter = new ExportToExcel();
exporter.Export();
Console.ReadLine();
}
公司购买了一个第三方类库PDFWriter,使用这个类库可以轻松地将数据导入到PDF文件中,但是,它只提供了WriteToPDF方法,这与我们的IExporter接口不兼容。
//这里仅仅是为了方便展示示例提供,我们没有第三方类库的源码
class PDFWriter
{
public void WriteToPDF()
{
Console.WriteLine("Write to PDF..");
}
}
由于没有源码,无法进行修改。当然,即使可以修改,也不应该为了实现一个应用去实现特定领域的接口。为了使我们的转换器程序也能够动态调用WriteToPDF方法,添加类PDFAdapter。
class PDFAdapter : IExporter
{
private PDFWriter writer = new PDFWriter();
public void Export()
{
writer.WriteToPDF();
}
}
通过适配器进行动态调用。
static void Main(string[] args)
{
IExporter exporter = new PDFAdapter();
exporter.Export();
Console.ReadLine();
}
如果适配器同时包含目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法,那么这个适配器就是一个双向适配器,结构示意图如下:
代码如下:
interface IAdaptee
{
void SpecificRequest();
}
class ConcreteAdaptee : IAdaptee
{
public void SpecificRequest()
{
Console.WriteLine("SpecificRequest by ConcreteAdaptee");
}
}
interface ITarget
{
void Request();
}
class ConcreteTarget : ITarget
{
public void Request()
{
Console.WriteLine("Request by ConcreteTarget");
}
}
class Adapter : IAdaptee, ITarget
{
private IAdaptee adaptee;
private ITarget target;
public Adapter(IAdaptee adaptee)
{
this.adaptee = adaptee;
}
public Adapter(ITarget target)
{
this.target = target;
}
public void Request()
{
adaptee.SpecificRequest();
}
public void SpecificRequest()
{
target.Request();
}
}
观察以上介绍的Adapter类,有一个共性,就是只能适配固定的Adaptee(编译阶段就已经确定),不够灵活。而可插入适配器则是可以适配包含不同接口的Adaptee,换句话来说,可插入适配器允许适配在程序运行时动态传入的适配者。下面我们介绍使用Action委托的方式来实现可插入适配器:
首先创建Cat类和Dog类,并且这两个类拥有不同的方法。
class Cat
{
public void Miaow()
{
Console.WriteLine("miao miao miao");
}
}
class Dog
{
public void Bark()
{
Console.WriteLine("wang wang wang");
}
}
创建可插入适配器,由于不确定适配者的类型及接口,只知道将来客户端要调用MakeSound方法。也就是说,适配器本身不知道将来会适配什么样的适配者,也不知道调用适配者的哪个方法,这一切都是由客户端动态传入。
class PluggableAdapter
{
public Action MakeSound { get; private set; }
public PluggableAdapter(Action makeSound)
{
this.MakeSound = makeSound;
}
}
客户端调用,向PluggableAdapter的构造函数传入委托方法,完成适配。
static void Main(string[] args)
{
Dog dog = new Dog();
(new PluggableAdapter(dog.Bark)).MakeSound();
Console.ReadLine();
}
使用一个已经存在的类,但它提供的方法与系统中定义的接口不兼容
使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它们父类的接口
标签:数据 阶段 specific 插入 net 实例 png str 定义
原文地址:https://www.cnblogs.com/Answer-Geng/p/9099026.html