(精华)2020年8月28日 二十三种设计模式(六)-适配器模式(Adapter Pattern)

举报
愚公搬代码 发表于 2021/10/19 01:40:44 2021/10/19
【摘要】 适配器模式(Adapter Pattern) 适配器模式属于结构型模式,把一个类的接口变成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。 适配器模式又可以分为4种...

适配器模式(Adapter Pattern)

适配器模式属于结构型模式,把一个类的接口变成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。

适配器模式又可以分为4种类型,类适配器模式、对象适配器模式、单接口适配器模式(缺省适配器模式)和双向适配器模式。后2种模式的实现比较复杂并且在实际开发过程中很少使用,故本博文只讨论前2种模式。

角色

1、抽象目标(Target)

抽象目标类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。在类适配器中,由于C#语言不支持多重继承,所以它只能是接口;

2、适配器(Adapter)

它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配,它是适配器模式的核心;

3、适配者(Adaptee)

适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。

示例

在这里插入图片描述
命名空间AdapterPattern包含ClassBased和ObjectBased子命名空间,分别表示基于类的适配器模式和基于对象的适配器模式。类的适配器中包含家用电器类、电压类、目标动作接口和手机适配器类。对象的适配器中包含适配者、适配器、目标接口和目标基类。本案例尝试使用手机适配器将家用电器的电压从220V适配至3V。

namespace AdapterPattern

  
 
  • 1

类的适配器模式

namespace AdapterPattern.ClassBased

  
 
  • 1
public class Voltage {

    public uint Value { get; set; }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

电压Voltage类,包含一个无符号int类型的电压值。

public class Appliance {

    public Voltage GetVoltage() {
        return new Voltage { Value = 220 };
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

家用电器Appliance类,包含一个获取电压的GetVoltage方法。

public interface ITarget {

    Voltage GetMobileVoltage();

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

目标接口ITarget,包含一个获取手机电压的GetMobileVoltage方法。这是我们要适配的目标动作。

public class MobileAdapter : Appliance, ITarget {
 
    public Voltage GetMobileVoltage() {
        var voltage = GetVoltage();
        Console.WriteLine($"Appliance voltage is {voltage.Value}V!");
 
        voltage.Value = 3;
        Console.WriteLine($"After adapted,it becomes {voltage.Value}V!");
 
        return voltage;
    }
 
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

手机适配器MobileAdapter类,继承自Applicance家用电器并实现ITarget接口。

对象的适配器模式

namespace AdapterPattern.ObjectBased

  
 
  • 1
public class Adaptee {

    public void OriginalMethod() {
        Console.WriteLine("Original Method is being called!");
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

适配者Adaptee类,这是将要被我们适配的类。

public interface ITarget {

    void TargetMethod();

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

目标接口ITarget,定义我们的目标动作。

public class Target : ITarget {

    public virtual void TargetMethod() {
        Console.WriteLine("Target Method is being called!");
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

目标Target类,实现目标接口以实现动作。

public class Adapter : Target {

    private Adaptee _adaptee = new Adaptee();

    public override void TargetMethod() {
        _adaptee.OriginalMethod();
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

适配器Adapter类,继承自Target类。内部维持对适配者的引用并实现一个目标动作。

public class Program {

    private static ClassBased.ITarget _targetClass = null;
    private static ObjectBased.ITarget _targetObject = null;

    public static void Main(string[] args) {
        //Class Pattern
        _targetClass = new ClassBased.MobileAdapter();
        var voltage = _targetClass.GetMobileVoltage();

        Console.WriteLine("-----------------------------");

        //Object Pattern
        _targetObject = new ObjectBased.Adapter();
        _targetObject.TargetMethod();

        Console.ReadKey();
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

以上是调用方的代码,分别演示了类的适配器模式和对象的适配器模式的用法。以下是这2个案例的输出结果:

Appliance voltage is 220V!
After adapted,it becomes 3V!
-----------------------------
Original Method is being called!

  
 
  • 1
  • 2
  • 3
  • 4

优点

1、可以让任何两个没有关联的类一起运行;
2、可以在不修改原有代码的基础上来复用现有类,很好地符合 “开闭原则”;
3、增加了类的透明度和更好的灵活性。

缺点

1、由于C#不支持多重继承,所以最多只能适配一个适配者类,而且目标类必须是抽象类;
2、采用了类和接口的“双继承”实现方式,带来了不良的高耦合。

使用场景

1、系统需要复用现有类,而该类的接口不符合系统的需求;
2、想要建立一个可重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作;
3、对于对象适配器模式,在设计里需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。

文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。

原文链接:codeboy.blog.csdn.net/article/details/107982601

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。