前置文章: 设计模式的原则
其他设计模式:用心理解设计模式专栏
设计模式相关代码已统一放至 我的 Github
一、定义
结构型模式之一。
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
(将类的接口转换为客户端期望的另一个接口,适配器使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。)
二、结构解析
适配器模式的一般结构有三种角色: 目标接口、被适配者、适配器。
目标接口(Target):定义一个实际需要的接口方法。
被适配者(Adaptee):拥有一个与需求大方向上相符(不可能随意生拉硬套),但实际使用不匹配的接口方法。
适配器(Adapter):实现目标接口,持有被适配者。将目标接口接受到的参数转为被适配者可用的参数,将被适配者的返回值转化为目标接口需要的返回值。
三、评价
适配器模式是一个对接口进行转换的设计模式。
而对接口进行转换的关键是对参数(包括类型和数量)和返回值(C#中仅类型,其他语言中可能也包括数量)进行转换。
适配器非常常见,最典型的如,生活中的电源适配器(转换电压)。
在接口不匹配时,使用适配器,可以避免了对被适配者的修改。保证了系统的安全性。
四、实现
using UnityEngine;
namespace Adapter
{
//-------------辅助说明类-------------
//目标接口需要的参数
public class TargetParameter { }
//目标接口需要的返回值
public class TargetReturnValue { }
//被适配者现有接口需要的参数
public class AdapteeParameter { }
//被适配者现有接口需要的返回值
public class AdapteeReturnValue { }
//-------------辅助说明类-------------
//目标, 定义需要的接口(需要哪些参数,需要返回什么值)
public abstract class Target
{
public abstract TargetReturnValue Request(TargetParameter parameter);
}
//被适配者, 拥有与目标不一致的接口(参数不一致或返回值不一致,或两者都不一致)
public class Adaptee
{
public AdapteeReturnValue SpecificalRequest(AdapteeParameter parameter)
{
Debug.Log("被适配者执行!");
return new AdapteeReturnValue();
}
}
//适配器
public class Adapter : Target
{
private Adaptee adptee = new Adaptee();
public override TargetReturnValue Request(TargetParameter parameter)
{
AdapteeParameter adapteeParameter = this.AdaptParameters(parameter);
AdapteeReturnValue adapteeReturnValue = adptee.SpecificalRequest(adapteeParameter);
TargetReturnValue targetReturnValue = this.AdaptReturnValues(adapteeReturnValue);
return targetReturnValue;
}
//主要步骤1:将目标接口接收到的参数,转为被适配者需要的参数
private AdapteeParameter AdaptParameters(TargetParameter parameter)
{
Debug.Log("适配/转换 参数");
return new AdapteeParameter();
}
//主要步骤2:将被适配者的返回值,转为目标接口需要的参数
private TargetReturnValue AdaptReturnValues(AdapteeReturnValue returnValue)
{
Debug.Log("适配/转换 返回值");
return new TargetReturnValue();
}
}
public class CLient
{
static public void Main()
{
//原来使用被适配者
AdapteeReturnValue adapteeReturnValue = new Adaptee().SpecificalRequest(new AdapteeParameter());
//使用适配器使用被适配者
TargetReturnValue targetReturnValue = new Adapter().Request(new TargetParameter());
}
}
}