深入理解Java设计模式之适配器模式

 更新时间:2021年11月05日 10:00:36   作者:一指流砂~  
这篇文章主要介绍了JAVA设计模式之适配器模式的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解

一、什么是适配器模式

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

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

二、适配器模式的结构

Adaptee:初始角色,实现了我们想要使用的功能,但是接口不匹配

Target:目标角色,定义了客户端期望的接口

Adapter:适配器角色,实现了目标接口。实现目标接口的方法是:内部包含一个Adaptee的对象,通过这个对象调用Adaptee的原有方法实现目标接口。(注:这里说的是对象适配器)

三、适配器模式的使用场景

当前打开我这篇文章的笔记本电脑,电源的另一边不正连着一块适配器吗?你平时想将三口插座插进二口插座里面,不也需要一个适配器吗?整天插在插座上的手机充电头,不也是一个适配器吗?

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

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

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

四、适配器模式的优缺点

优点:

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

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

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

缺点:

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

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

五、适配器模式的实现

1.类适配器模式

namespace 设计模式之适配器模式
{
    /// <summary>
    /// 这里手机充电器为例,我们的家的插座是两相电的,但是手机的插座接头是三相电的
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
            //好了,现在可以充电了
            ITwoHoleTarget change = new ThreeToTwoAdapter();
            change.Request();
            Console.ReadLine();
        }
    }
    /// <summary>
    /// 我家只有2个孔的插座,也就是适配器模式中的目标角色(Target),这里只能是接口,也是类适配器的限制
    /// </summary>
    public interface ITwoHoleTarget
    {
        void Request();
    }
    /// <summary>
    /// 3个孔的插头,源角色——需要适配的类(Adaptee)
    /// </summary>
    public abstract class ThreeHoleAdaptee
    {
        public void SpecificRequest()
        {
            Console.WriteLine("我是三个孔的插头");
        }
    }
    /// <summary>
    /// 适配器类,接口要放在类的后面,在此无法适配更多的对象,这是类适配器的不足
    /// </summary>
    public class ThreeToTwoAdapter:ThreeHoleAdaptee,ITwoHoleTarget
    {
        /// <summary>
        /// 实现2个孔插头接口方法
        /// </summary>
        public void Request()
        {
            // 调用3个孔插头方法
            this.SpecificRequest();
        }
    }
}

2.对象适配器模式

namespace 对象的适配器模式
{
    ///<summary>
    ///家里只有两个孔的插座,也懒得买插线板了,还要花钱,但是我的手机是一个有3个小柱子的插头,明显直接搞不定,那就适配吧
    ///</summary>
    class Client
    {
        static void Main(string[] args)
        {
            //好了,现在就可以给手机充电了
            TwoHoleTarget homeTwoHole = new ThreeToTwoAdapter();
            homeTwoHole.Request();
            Console.ReadLine();
        }
    }
    /// <summary>
    /// 我家只有2个孔的插座,也就是适配器模式中的目标(Target)角色,这里可以写成抽象类或者接口
    /// </summary>
    public class TwoHoleTarget
    {
        // 客户端需要的方法
        public virtual void Request()
        {
            Console.WriteLine("两孔的充电器可以使用");
        }
    }
    /// <summary>
    /// 手机充电器是有3个柱子的插头,源角色——需要适配的类(Adaptee)
    /// </summary>
    public class ThreeHoleAdaptee
    {
        public void SpecificRequest()
        {
            Console.WriteLine("我是3个孔的插头也可以使用了");
        }
    }
    /// <summary>
    /// 适配器类,TwoHole这个对象写成接口或者抽象类更好,面向接口编程嘛
    /// </summary>
    public class ThreeToTwoAdapter : TwoHoleTarget
    {
        // 引用两个孔插头的实例,从而将客户端与TwoHole联系起来
        private ThreeHoleAdaptee threeHoleAdaptee = new ThreeHoleAdaptee();
        //这里可以继续增加适配的对象。。
        /// <summary>
        /// 实现2个孔插头接口方法
        /// </summary>
        public override void Request()
        {
            //可以做具体的转换工作
            threeHoleAdaptee.SpecificRequest();
            //可以做具体的转换工作
        }
    }
}

六、适配器模式的.NET应用

在.NET中有一个类库已经实现且非常重要的适配器,那就是DataAdapter。DataAdapter用作DataSet和数据源之间的适配器以便检索和保存数据,DataAdapter通过映射Fill(这更改了DataSet中的数据以便与数据源中的数据相匹配)和Update(这更改了数据源中的数据以便与DataSet中的数据相匹配)来提供这一适配器。

由于数据源可能来自于SQL Server,可能来自于Oracel,也可能来自于DB2、MySql,这些数据在组织上可能有不同之处,但我们希望得到统一的DataSet(实质是XML数据),此时用DataAdapter就是非常好的手段,我们不必关注不同数据库的数据细节,就可以灵活的使用数据。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • eclipse 联想功能设置技巧

    eclipse 联想功能设置技巧

    本文主要介绍了eclipse 联想功能设置技巧的相关内容,还是比较不错的,需要的朋友可以参考。
    2017-10-10
  • Java适配器模式定义与用法示例

    Java适配器模式定义与用法示例

    这篇文章主要介绍了Java适配器模式定义与用法,结合具体实例形式分析了java适配器模式的功能、组成、定义、使用方法及适配程度等,需要的朋友可以参考下
    2017-06-06
  • Java实现在线SQL编程最新完整版

    Java实现在线SQL编程最新完整版

    这篇文章主要介绍了Java实现在线SQL编程,在使用JDBC来进行数据库的操作,在使用时由于对其方法并不是全部了解,所以需要边看源码边改善功能,感兴趣的朋友跟随小编一起看看吧
    2022-06-06
  • 如何使用hutool做本地缓存的工具类

    如何使用hutool做本地缓存的工具类

    这篇文章主要介绍了如何使用hutool做本地缓存的工具类,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Java线程并发中常见的锁机制详细介绍

    Java线程并发中常见的锁机制详细介绍

    越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题。接下来通过本文给大家介绍Java线程并发中常见的锁机制,感兴趣的朋友一起看看吧
    2016-05-05
  • Google Guava 缓存工具使用详解

    Google Guava 缓存工具使用详解

    这篇文章主要介绍了Guava自加载缓存LoadingCache使用指南,通过这些内容介绍,了解了LoadingCache的基本原理和用法,包括如何创建和配置缓存,以及如何结合Java 8的特性来优化代码,需要的朋友可以参考下
    2023-12-12
  • 如何使用Reactor完成类似Flink的操作

    如何使用Reactor完成类似Flink的操作

    这篇文章主要介绍了如何使用Reactor完成类似Flink的操作,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • 关于@JsonProperty,@NotNull,@JsonIgnore的具体使用

    关于@JsonProperty,@NotNull,@JsonIgnore的具体使用

    这篇文章主要介绍了关于@JsonProperty,@NotNull,@JsonIgnore的具体使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 如何使用Java生成PDF文档详解

    如何使用Java生成PDF文档详解

    这篇文章主要给大家介绍了关于如何使用Java生成PDF文档的相关资料,PDF是可移植文档格式,是一种电子文件格式,具有许多其他电子文档格式无法相比的优点,需要的朋友可以参考下
    2023-07-07
  • java发送短信的实现步骤

    java发送短信的实现步骤

    下面小编就为大家带来一篇java发送短信的实现步骤。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09

最新评论