首页 Java java教程 Java设计模式中适配器模式的图解

Java设计模式中适配器模式的图解

Oct 18, 2017 am 09:36 AM
java 设计模式 适配器

这篇文章主要为大家详细介绍了java设计模式之适配器模式笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

适配器(Adapter)模式:

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

生活中的场景:

1、笔记本电源适配器,可以将220v转化为适合笔记本使用的电压。

2、给笔记本电脑的usb接口插入台式机的ps/2接口的键盘,需要一个usb和ps/2的接口转接器,此时usb和ps/2的接口转接器就充当了适配器的角色。

usb和ps/2的接口转接器

通用类图:

通用类图

  在上面的通用类图中,Cient 类最终面对的是 Target 接口(或抽象类),它只能够使用符合这一目标标准的子类;而 Adaptee 类则是被适配的对象(也称 源角色),因为它包含specific (特殊的)操作、功能等,所以我们想要在自己的系统中使用它,将其转换成符合我们标准的类,使得 Client 类可以在透明的情况下任意选择使用 ConcreteTarget 类或是具有特殊功能的 Adaptee 类。

适配器模式中的角色:

目标接口(Target):客户所期待得到的接口。目标可以是具体的或抽象的类,也可以是接口。
需要适配的类(Adaptee):需要适配的接口或适配类。
适配器(Adapter):适配器类是本模式的核心。适配器通过包装一个需要适配的对象,把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。

适配器模式的结构:

适配器模式有类的适配器模式和对象的适配器模式两种不同的形式。

类的适配器模式把适配的类的API转换成为目标类的API。

对象的适配器模式与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。

类的适配器模式

1、创建一个被适配的类:


/**
 * 被适配的类
 * 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
 * (相当于例子中的,PS/2键盘)
 * @author ChuanChen
 * 
 */
public class Adaptee {

  public void specificRequest(){
    System.out.println("可以完成客户请求的需要的功能!");
  }
}
登录后复制
登录后复制

2、创建一个目标接口,能处理一些特殊请求


/**
 * 目标接口,或称为标准接口
 * @author ChuanChen
 *
 */
public interface Target {
  void handleReq();
}
登录后复制
登录后复制

3、创建一个适配器 (类适配器方式)


/**
 * 适配器 (类适配器方式)
 * (相当于usb和ps/2的转接器)
 * @author ChuanChen
 *
 */
public class Adapter extends Adaptee implements Target {


  @Override
  public void handleReq() {
    super.specificRequest();
  }
}
登录后复制

4、创建一个客户端


/**
 * 客户端类
 * (相当于例子中的笔记本,只有USB接口)
 * @author ChuanChen
 *
 */
public class Client {

  public void test(Target t){
    t.handleReq();
  }

  public static void main(String[] args) {
    Client c = new Client();
    Adaptee a = new Adaptee();
    Target t = new Adapter();
    c.test(t); 
  }  
}
登录后复制

  上面这种实现的适配器称为类适配器,因为 Adapter 类既继承了 Adaptee (被适配类),也实现了 Target 接口(因为 Java 不支持多继承,所以这样来实现),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。

对象的适配器模式

1、创建一个被适配的类:


/**
 * 被适配的类
 * 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
 * (相当于例子中的,PS/2键盘)
 * @author ChuanChen
 * 
 */
public class Adaptee {

  public void specificRequest(){
    System.out.println("可以完成客户请求的需要的功能!");
  }
}
登录后复制
登录后复制

2、创建一个目标接口,能处理一些特殊请求


/**
 * 目标接口,或称为标准接口
 * @author ChuanChen
 *
 */
public interface Target {
  void handleReq();
}
登录后复制
登录后复制

3、创建一个适配器 (对象适配器方式,使用了组合的方式跟被适配对象整合)


/**
 * 适配器 (对象适配器方式,使用了组合的方式跟被适配对象整合)
 * (相当于usb和ps/2的转接器)
 * @author ChuanChen
 *
 */

public class Adapter implements Target{

private Adaptee adaptee;

  @Override
  public void handleReq() {
    adaptee.specificRequest();
  }

  public Adapter(Adaptee adaptee) {
    super();
    this.adaptee = adaptee;
  }

}
登录后复制

4、创建一个客户端


/**
 * 客户端类
 * (相当于例子中的笔记本,只有USB接口)
 * @author ChuanChen
 *
 */
public class Client {

  public void test(Target t){
    t.handleReq();
  }

  public static void main(String[] args) {
    Client c = new Client();
    Adaptee a = new Adaptee();
    Target t = new Adapter(a);
    c.test(t);
  }  
}
登录后复制

  我们只需要修改 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。

类适配器和对象适配器的权衡:

  • 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。

  • 对于类适配器,由于适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一起工作,因为继承是静态的关系,当适配器继承了Adaptee后,就不可能再去处理 Adaptee的子类了。

  • 对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。

  • 对于类适配器,适配器可以重定义Adaptee的部分行为,相当于子类覆盖父类的部分实现方法。

  • 对于对象适配器,要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。

  • 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。

  • 对于对象适配器,需要额外的引用来间接得到Adaptee。

建议尽量使用对象适配器的实现方式,多用合成/聚合、少用继承。当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的。

适配器模式的优点:

更好的复用性:

系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。  

更好的扩展性:

在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
适配器模式的缺点

过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

适配器模式在工作中的场景:

1、已经存在的类的接口不符合我们的需求;
2、创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;
3、在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类。

适配器模式经常用于旧系统改造和升级。如果我们的系统开发之后再也不需要维护,那么很多模式都是没有必要的。但是不幸的是,事实上维护一个系统的代价往往是开发一个系统的数倍。

以上是Java设计模式中适配器模式的图解的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

Java 中的随机数生成器 Java 中的随机数生成器 Aug 30, 2024 pm 04:27 PM

Java 随机数生成器指南。在这里,我们通过示例讨论 Java 中的函数,并通过示例讨论两个不同的生成器。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

Java 中的时间戳至今 Java 中的时间戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的时间戳到日期指南。这里我们还结合示例讨论了介绍以及如何在java中将时间戳转换为日期。

Java程序查找胶囊的体积 Java程序查找胶囊的体积 Feb 07, 2025 am 11:37 AM

胶囊是一种三维几何图形,由一个圆柱体和两端各一个半球体组成。胶囊的体积可以通过将圆柱体的体积和两端半球体的体积相加来计算。本教程将讨论如何使用不同的方法在Java中计算给定胶囊的体积。 胶囊体积公式 胶囊体积的公式如下: 胶囊体积 = 圆柱体体积 两个半球体体积 其中, r: 半球体的半径。 h: 圆柱体的高度(不包括半球体)。 例子 1 输入 半径 = 5 单位 高度 = 10 单位 输出 体积 = 1570.8 立方单位 解释 使用公式计算体积: 体积 = π × r2 × h (4

See all articles