C#设计模式系列:适配器模式(Adapter)

  在实际的软件系统设计和开发中,为了完成某项工作需要购买一个第三方的库来加快开发。这带来一个问题,在应用程序中已经设计好的功能接口,与这个第三方提供的接口不一致。为了使得这些接口不兼容的类可以在一起工作,适配器模式提供了一种接口的适配机制。

  适配器模式的设计思想在生活中经常会应用到,如我们在给手机充电的时候,不可能直接在220V电源上直接充电,而是用手机充电器转换成手机需要的电压才可以正常充电,否则就不可以完成充电,这个充电器就起到了适配的作用。

1、适配器模式简介

1.1>、定义

  适配器模式是通过一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的那些类可以一起工作。

  适配器从结构上可以分为类适配器和对象适配器。其中类适配器使用继承关系来对类进行适配,而对象适配器是使用对象引用的方法来进行适配的。

  C#实现类适配器时,Target只能是接口。实现对象适配器时,Target可以是抽象类也可以是接口。

1.2>、使用频率

   中高

2、类适配器模式结构

2.1>、结构图

类适配器结构图

对象适配器结构图

2.2>、参与者

  适配器模式参与者:

  ◊ Target:Client所使用的与特定领域相关的接口。

  ◊ Client:与符合Target接口的对象协调的类。

  ◊ Adaptee:需要适配的类接口。

  ◊ Adapter:适配器,负责Adaptee的接口与Target接口进行适配。

  在适配器模式中,类Adapter实现适配器的功能,它在Client于Adaptee之间加入Adapter,这样Client把请求发给接口为Target的类Adapter,再由Adapter调用Adaptee,从而实现Client调用Adaptee。

3、适配器模式结构实现

3.1>、类适配器结构实现

  ITarget.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
    public interface ITarget
    {
        void Request();
    }
}

  Adaptee.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
    public class Adaptee
    {
        public void SpecificRequest()
        {
            Console.WriteLine("Called SpecificRequest()");
        }
    }
}

  Adapter.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
    public class Adapter : Adaptee, ITarget
    {
        public void Request()
        {
            this.SpecificRequest();
        }
    }
}

  Client.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
    public class Client
    {
        static void Main(string[] args)
        {
            ITarget t = new Adapter();
            t.Request();
        }
    }
}

  运行输出:

Called SpecificRequest()
请按任意键继续. . .

3.2>、对象适配器结构实现

  Client需要调用Request方法,而Adaptee并没有该方法,为了使Client能够使用Adaptee类,需要提供一个类Adapter。这个类包含了一个Adaptee的实例,将Client与Adaptee衔接起来。

  ITarget.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
    public interface ITarget
    {
        void Request();
    }
}

  Target.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
    public class Target : ITarget
    {
        public virtual void Request()
        {
            Console.WriteLine("Called Target Request()");
        }
    }
}

  Adaptee.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
    public class Adaptee
    {
        public void SpecificRequest()
        {
            Console.WriteLine("Called SpecificRequest()");
        }
    }
}

  Adapter.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
    public class Adapter : Target
    {
        private Adaptee _adaptee = new Adaptee();

        public override void Request()
        {
            _adaptee.SpecificRequest();
        }
    }
}

  Client.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
    public class Client
    {
        static void Main(string[] args)
        {
            ITarget t = new Adapter();
            t.Request();
        }
    }
}

4、适配器模式实践应用

  以手机充电的电源适配器为例,用适配器模式的解决方案。

4.1>、类适配器结构实现

  ITarget.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
    public interface ITarget
    {
        void GetPower();
    }
}

  Power.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
    public class Power
    {
        public void GetPower220V()
        {
            Console.WriteLine("从电源中得到220V的电压");
        }
    }
}

  Adapter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
    public class Adapter : Power, ITarget
    {
        public void GetPower()
        {
            this.GetPower220V();
            Console.WriteLine("得到手机的充电电压!");
        }
    }
}

  Client.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
    public class Client
    {
        static void Main(string[] args)
        {
            Console.WriteLine("手机:");
            ITarget t = new Adapter();
            t.GetPower();
        }
    }
}

  运行输出:

手机:
从电源中得到220V的电压
得到手机的充电电压!
请按任意键继续. . .

4.2>、对象适配器结构实现

  ITarget.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
    public interface ITarget
    {
        void GetPower();
    }
}

  Power.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
    public class Power
    {
        public void GetPower220V()
        {
            Console.WriteLine("从电源中得到220V的电压");
        }
    }
}

  Adapter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
    public class Adapter : ITarget
    {
        public Power _power;
        public Adapter(Power power)
        {
            this._power = power;
        }

        /// <summary>
        /// 得到想要的电压
        /// </summary>
        public void GetPower()
        {
            _power.GetPower220V();
            Console.WriteLine("得到手机的充电电压!");
        }
    }
}

  Client.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
    public class Client
    {
        static void Main(string[] args)
        {
            Console.WriteLine("手机:");
            ITarget t = new Adapter(new Power());
            t.GetPower();
        }
    }
}

5、适配器模式应用分析

  适配器模式适用情形:

  ◊ 当适用一个已存在的类,而它的接口不符合所要求的情况;

  ◊ 想要创建一个可以复用的类,该类可以与原接口的类协调工作;

  ◊ 在对象适配中,当要匹配数个子类的时候,对象适配器可以适配它们的父类接口。

   适配器模式特点:

  类适配器

  ◊ 使得Adapter可以重定义Adaptee的部分行为。因为Adapter是Adaptee的一个子类;

  ◊ 仅仅引入了一个对象,并不需要额外的指针间接得到Adaptee。

  对象适配器

  ◊ 允许一个Adapter与多个Adaptee同时工作。Adapter也可以一次给所有的Adaptee添加功能;

  ◊ 使得重定义Adaptee的行为比较困难。需要生成一个Adaptee的子类,然后使Adapter引入这个子类而不是引用Adaptee本身。

时间: 2024-10-14 18:19:37

C#设计模式系列:适配器模式(Adapter)的相关文章

设计模式之适配器模式(Adapter Pattern)

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 1. 解决的问题 即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 模式中的角色 2.1 目标接口(Target):客户所期待的接口.目标可以是具体的或抽象的类,也可以是接口. 2.2 需要适配的类(Adaptee):需要适配的类或适配者类. 2.3 适配器(Adapter):通过包装一个需要适配的对象,把

Java设计模式之适配器模式(Adapter Pattern)

Adapter Pattern的作用是在不改变功能的前提下转换接口.Adapter分为两类,一类是Object Adapter, 另一类是Class Adapter.由于Class Adapter的实现需要用到多继承,而Java不支持多继承,所以这里只关注Object Adapter. 在JDK1.5之前是没有 java.util.Iterator 接口的,java.util.Enumeration 接口起着 Iterator 的作用.那么如果我们需要维护一些年代比较久远的代码,可能就会面临着没

如何让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)

如何让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 概念相关 定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而 使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 简单点说: 两个彼此间没有太大关联的类,想进行交互完成某些事情,如果 直接去修改各自的接口,就显得有些繁琐了,可以加个中间类, 用它来协调两类之间的关系,完成相关业务.这种玩法就叫适配器模式! 两种适配器模式: 根据适配器类与适配者类的关系不同,适配器模式可分为 类适配器 和 对

设计模式之适配器模式(Adapter)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

二十四种设计模式:适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 示例有一个Message实体类,某个类对它的操作有Insert()和Get()方法.现在需要把这个类转到另一个接口,分别对应Add()和Select()方法. MessageModel using System; using System.Collections.Generic; using System.Text; name

JavaScript设计模式 Item9 --适配器模式Adapter

适配器模式(转换器面模式),一般是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况.适配器模式的作用是解决两个软件实体间的接口不兼容的问题. 一.定义 适配器模式(Adapter)是将一个类(对象)的接口(方法或属性)转化成客户希望的另外一个接口(方法或属性),适配器模式使得原本由于接口不兼容而不能一起工作的那些类(对象)可以一些工作.速成包装器(wrapper). 适配器的别名是包装器(wrapper),这是一个相对简单的模式.在程序开发中有许多这样的场景:当我们试图

Java设计模式之适配器模式(Adapter)

转载:<JAVA与模式>之适配器模式 这个总结的挺好的,为了加深印象,我自己再尝试总结一下 1.定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作.      (太官方了,不太好理解, 其实就是要用到两个不相关的类/接口,但是又没有源代码,或者不想修改源代码,而增加一个类来完成合并使用的目的) 2.实现这个目的有两个方法,继承或者组合 2.1.使用继承(就是所谓的类适配器模式) 2.2.使用组合(所谓的对象适配器模式)

设计模式之适配器模式 adapter 适配器模式分类概念角色详解 类适配器 对象适配器 接口适配器 双向适配器

现实世界中的适配器模型 先来看下来几个图片,截图自淘宝 上图为港版的插头与港版的插座 上图为插座适配器卖家的描述图 上图为适配后的结果 现实世界中适配器模式 角色分类 这就是适配器模式在电源插座上的应用 我们看下在插座适配器中的几个重要角色 可以看得出来,大陆和港版插座面板,都是作为电源的角色,他们的功能是相似的或者说相近的 插头要使用插座,进而接通电流 现实世界到代码的转换 电源插座代码示例 港版插座面板 package adapter; /**目标角色 Target 接口 * 香港地区使用的

【设计模式】—— 适配器模式Adapter

前言:[模式总览]——————————by xingoo 模式意图 如果已经有了一种类,而需要调用的接口却并不能通过这个类实现.因此,把这个现有的类,经过适配,转换成支持接口的类. 换句话说,就是把一种现有的接口编程另一种可用的接口. 模式结构 [类的适配器] Target 目标接口 Adaptee 现有的类 Adapter 中间转换的类,即实现了目标接口,又继承了现有的类. 1 package com.xingoo.test1; 2 interface Target{ 3 public voi

设计模式系列---适配器模式

写在前面 适配模式的定义如下: 将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配儿无法在一起工作的两个类能够在一起工作. 看下适配器模式的类图: spring中的适配器模式 在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能.Spring实现这一AOP功能的原理就使用代理模式(1.JDK动态代理.2.CGLib字节码生成技术代理.)对类进行方法级别的切面增强,即,生成被代理类的代理类, 并在代理类的方法前,设置拦截器,通过执行拦截器重的内容增强了代理方法