目的
解决旧实现与新接口不兼容的问题
为什么说组合优于继承呢? 1.没有侵入性 2.可以为多个类型服务 3.相对来说要更加灵活一点
一、类适配器模式(慎用)
定义与实现
- 核心机制:通过继承被适配类(Adaptee)并实现目标接口(Target)来实现接口转换。
- C#特性约束:由于C#不支持多重继承,类适配器只能继承一个被适配类,且目标接口必须为接口类型
代码示例
//目标接口
public interface ITarget
{
void Request();
}
//原有实现类
public class Adaptee
{
public void SpecificRequest() { /*...*/ }
}
//类适配器(通过继承原有实现类)
public class Adapter : Adaptee, ITarget {
public void Request() { SpecificRequest(); }
}
优点
- 直接复用被适配类的方法,代码简洁
- 符合开闭原则,无需修改被适配类即可扩展功能
缺点
- 因为C#单继承机制,导致没办法适配多个原有实现类
一、对象适配器模式(慎用)
定义与实现
- 核心机制:通过组合方式持有被适配类的实例,并在适配器中调用其方法。适配器类仅需实现目标接口,无需继承被适配类。
- 灵活性:可适配多个被适配类,甚至动态替换实例
代码示例
主要变化
public class Adapter : ITarget {
private Adaptee _adaptee;
public Adapter(Adaptee adaptee) {
_adaptee = adaptee;
}
public void Request()
{
_adaptee.SpecificRequest();
}
}
目标接口
//背景:现在需要将支付的结果返回统一成PayResult
public record PayResult(bool flag,string msg);
//目标在线支付接口
public interface IPayOnlie
{
/// <summary></summary>
/// amount 金额
/// IdCard 身份证号码
public Task<PayResult> Pay(decimal amount,string IdCard);
}
原有实现
//阿里支付
public class AliPay
{
public async Task<bool> Pay(decimal amount,string IdCard)
{
//模拟业务逻辑
Console.WriteLine($"阿里支付:身份为{IdCard}的用户成功支付{amount}");
return await Task.FromResult(true);
}
}
适配器
public class PayAdapter:IPayOnlie
{
private AliPay _aliPay;
public PayAdapter(AliPay aliPay)
{
_aliPay = aliPay;
}
/// <summary></summary>
/// amount 金额
/// IdCard 身份证号码
public async Task<PayResult> Pay(decimal amount, string IdCard)
{
bool flag = await _aliPay.Pay(amount,IdCard);
string msg = flag?"支付成功":"支付失败";
PayResult result = new PayResult(flag,msg);
return result;
}
}
当有多个适配的现有实现时
public class PaymentAdapter : IPayOnlie {
private AlipayService _alipay;
private WechatPayService _wechatPay;
//多个实现对象注入
public PaymentAdapter(AlipayService alipay, WechatPayService wechatPay) {
_alipay = alipay;
_wechatPay = wechatPay;
}
public void Pay(decimal amount, string IdCard) {
// 根据业务逻辑动态选择支付方式
if (amount > 1000) {
_alipay.AlipayTransfer(amount, orderId); // 大额走支付宝
} else {
_wechatPay.WechatPayment(amount, orderId); // 小额走微信
}
}
}
优点
- 低耦合:适配器与
Adaptee通过组合解耦,支持动态替换和多适配对象。 - 符合依赖倒置原则,便于单元测试
缺点
- 需管理被适配对象的生命周期,可能增加内存开销。