目的

解决旧实现与新接口不兼容的问题

为什么说组合优于继承呢?
      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通过组合解耦,支持动态替换和多适配对象。
  • 符合依赖倒置原则,便于单元测试
缺点
  • 需管理被适配对象的生命周期,可能增加内存开销。