适配器模式(Adapter Pattern)

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/399 访问。

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

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

角色:

1、抽象目标(Target)

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

2、适配器(Adapter)

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

3、适配者(Adaptee)

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

示例:

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

namespace AdapterPattern

一、类的适配器模式 

namespace AdapterPattern.ClassBased
public class Voltage {

    public uint Value { get; set; }

}

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

public class Appliance {

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

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

public interface ITarget {

    Voltage GetMobileVoltage();

}

目标接口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;
} }

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

二、对象的适配器模式 

namespace AdapterPattern.ObjectBased
public class Adaptee {

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

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

public interface ITarget {

    void TargetMethod();

}

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

public class Target : ITarget {

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

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

public class Adapter : Target {

    private Adaptee _adaptee = new Adaptee();

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

适配器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();
} }

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

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

优点:

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/399 访问。

1、可以让任何两个没有关联的类一起运行;

2、可以在不修改原有代码的基础上来复用现有类,很好地符合 “开闭原则”;

3、增加了类的透明度和更好的灵活性。

缺点:

1、由于C#不支持多重继承,所以最多只能适配一个适配者类,而且目标类必须是抽象类;

2、采用了类和接口的“双继承”实现方式,带来了不良的高耦合。

使用场景:

1、系统需要复用现有类,而该类的接口不符合系统的需求;

2、想要建立一个可重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作;

3、对于对象适配器模式,在设计里需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。

C#设计模式之6-适配器模式的更多相关文章

  1. 设计模式 结构型 - 适配器模式 Adapter

    Adapter(适配器模式) ---- 加个“适配器”以便于复用 将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 应用场景 如果 ...

  2. Java设计模式7:适配器模式

    适配器模式 适配器模式说的是,可以把一个类的接口变换成客户端所期待的另一种接口,使得原本因接口不匹配而无法在一起工作的两个类可以一起工作. 适配器模式的用途 适配器模式的用途,在网上找了一幅图,挺形象 ...

  3. 设计模式学习之适配器模式(Adapter,结构型模式)(14)

    参考链接:http://www.cnblogs.com/zhili/p/AdapterPattern.html一.定义:将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于接口不兼 ...

  4. 【读书笔记】读《JavaScript设计模式》之适配器模式

    一.定义 适配器模式可用来在现有接口和不兼容的类之间进行匹配.使用这种模式的对象又叫包装器(wrapper),因为它们是在用一个新的接口包装另一个对象.在设计类的时候旺旺会遇到有些接口不能与现有API ...

  5. IOS设计模式之三(适配器模式,观察者模式)

    本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq) ...

  6. Java设计模式系列之适配器模式

    适配器模式的定义 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.(就类似于我们充电器的转接头将220V的电压转换成我们的手机端 ...

  7. java设计模式笔记(1)-适配器模式

    适配器的定义 适配器就是一个接口转换器,它可以是一个独立的硬件接口设备,允许硬件或电子接口与其它硬件或电子接口相连,也可以是信息接口.比如:电源适配器.三角架基座转接部件.USB与串口的转接设备等. ...

  8. Java程序设计模式系列之适配器模式

    理解适配器设计模式需要从生活中的场景进行联系,在生活当中有那些东西能够称为适配器呢?从字面上理解,"适配"的意思就是让一个东西和另一个东西配对,能够让他们一起工作,比如大家用的笔记 ...

  9. Java设计模式学习记录-适配器模式

    前言 之前已经将五个创建型设计模式介绍完了,从这一篇开始介绍结构型设计模式,适配器模式就是结构型模式的一种,适配器要实现的效果是把“源”过渡到“目标”. 适配器模式 在开发过程中,使用一个已经存在的类 ...

  10. 设计模式入门,适配器模式,c++代码实现

    // test07.cpp : Defines the entry point for the console application.// #include "stdafx.h" ...

随机推荐

  1. 【RPA Starter第三课】第一个Uipath项目:HelloWord

    最后是一个小项目,开启使用Uipath.Uipath云平台,Uipath Orchestrator,Uipath Studio,发布项目.怎么启动机器人.都有详细的步骤. Uipath 的账号是通用的 ...

  2. django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.解决办法

    "E:\API_Manager_PlatForm\venv\lib\site-packages\django\db\backends\mysql\base.py"在这个路径里件把b ...

  3. ciscn_2019_c_1

    0x01 检查文件,64位 检查开启的保护情况 开启了NX保护 0x02 IDA静态分析 在主函数这里并没有常见的gets栈溢出,尝试再这里面的子函数找找,发现了encrypt函数,进去查看 发现这个 ...

  4. 汇总我在IDEA中使用Maven导包遇到的问题

    看吐了吗?我是真吐了 真正遇到这些问题的朋友看到这,是不是有种找到知音的感觉,别怕,你不是在一个人战斗,苦逼的日子里,还有个我陪你一起苦逼,吐了吐了,这问题不知道耗费了我多久的时间,百度好多也解决不了 ...

  5. 题解 洛谷 P2254 【[NOI2005]瑰丽华尔兹】

    发现在同一时间段中,滑动的方向具有唯一性,所以不难得出\(DP\)方程. \(f_{i,j}=max(f_{i,j},f_{i-dx_,j-dy}+dis_{i,j,i-dx_,j-dy})\) \( ...

  6. 目前解决移动端1px边框最好的方法

    在移动端开发时,经常会遇到在视网膜屏幕中元素边框变粗的问题.本文将带你探讨边框变粗问题的产生原因及介绍目前市面上最好的解决方法. 1px 边框问题的由来 苹果 iPhone4 首次提出了 Retina ...

  7. 理解k8s资源限制系列(二):cpu time

    本文介绍几种在K8S中限制资源使用的几种方法. 资源类型 在K8S中可以对两类资源进行限制:cpu和内存. CPU的单位有: 正实数,代表分配几颗CPU,可以是小数点,比如0.5代表0.5颗CPU,意 ...

  8. java实现链表反转

    为什么面试常考链表反转 链表是常用的数据结构,同时也是面试常考点,链表为什么常考,因为链表手写时,大多都会有许多坑,比如在添加节点时因为顺序不对的话会让引用指向自己,因此会导致内存泄漏等问题,Java ...

  9. jupyter的服务器配置安装

    该教程主要针对的是服务器安装,且在后台保持稳定运行的情况. 1.jupyter下载 有网的时候 1. pip install jupyter 离线安装 在有网络的环境下载安装包 2. pip down ...

  10. Python 爬取网易云歌手的50首热门作品

    使用 requests 爬取网易云音乐 Python 代码: import json import os import time from bs4 import BeautifulSoup impor ...