• 概述

  什么是适配器?在我们生活中的适配器比如插头转换器(中标转美标)、USB接口转换器(type-c转苹果),电脑电源适配器(交流电转低电压直流)等。像这种将两者有差异的东西通过适配器使他们成为相互适合的东西。在程序世界中,经常存在现有的程序无法直接使用,需要做适当的变换后才能使用的情况,这种用于填补“现有程序”和“所需程序”之间差异的设计模式就是适配器(Adapter)模式。适配器模式有类适配器模式和对象适配器模式两种,前者使用继承,后者使用组合,所以后者比较灵活,推荐使用。下面通过实例对这两种模式的学习做一个笔记。

  • 实例

  类适配器模式

  Banner类:代表现在的实际情况

/**
* 注意:两种实现方式都是用的这个Banner类
* 推荐使用对象适配器方式
*/
public class Banner {
private String string; public Banner(String string) {
this.string = string;
} /**
* 用括号将字符串括起来
*/
public void showWithParen(){
System.out.println("("+string+")");
} /**
* 用星号将字符串括起来
*/
public void showWithAster(){
System.out.println("*"+string+"*");
}
}

  PrintForClass接口:代表是“需求”的接口

public interface PrintForClass {
public abstract void printWeak();
public abstract void printStrong();
}

  PrintBannerForClass类:扮演适配的角色。

  实现目标接口(PrintForClass)达到适配目的,而继承被适配者类(Banner)达到通过调用被适配者里的方法来实现目标接口的功能。

public class PrintBannerForClass extends  Banner implements PrintForClass{

    public PrintBannerForClass(String string) {
super(string);
} //实现PrintForClass中的方法
@Override
public void printWeak() {
super.showWithParen();
} @Override
public void printStrong() {
super.showWithAster();
}
}

  Main类:通过扮演适配器角色的PrintBannerForClass类来显示字符串。

  注意:这里我们将PrintBannerForClass类的实例保存在了PrintForClass类型的变量中。在这个类中,我们是使用PrintForClass接口来进行编程的。对Main类来说,Banner类、showWithParen()、showWithAster()方法被完全隐藏起来了。这就好像电脑电源适配器(交流电转低电压直流),电脑使用的是直流电,而它并不关心这个直流电是怎么来的。

public class Main {
public static void main(String[] args) {
//使用类适配器模式(继承)
PrintForClass p = new PrintBannerForClass("Hello World!");
p.printWeak();
p.printStrong();
}
}

  对象适配器模式(推荐)

  对象适配器模式就是采用一种“委托”的方式将某个方法中的实际处理交给其它实例来处理。在下面的例子中就是当PrintBannerForObject类中的printWeak()方法被调用的时候,并不是PrintBannerForObject类自己进行处理,而是将处理交给了Banner类的实例的showWithParen()方法。

  Banner类:和上面的Banner类一样

  PrintForObject类:不同于使用类适配器模式,这里使用的类,而类适配模式是使用的接口。

public abstract  class PrintForObject {
public abstract void printWeak();
public abstract void printStrong();
}

  PrintBannerForObject类:这个类中的banner字段保存了Banner的实例。然后printWeak()方法和printStrong()方法通过这个实例对象调用Banner类中的方法实现具体的功能。

public class PrintBannerForObject extends PrintForObject {
private Banner banner; public PrintBannerForObject(String string) {
this.banner = new Banner(string);
} //实现PrintForObject中的方法
@Override
public void printWeak() {
banner.showWithParen();
} @Override
public void printStrong() {
banner.showWithAster();
}
}
  • 完整代码

  请移步:https://github.com/yyc007/DesignPatterns/

  • 小结

  适配器模式就是将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容。

  从用户的角度看不到被适配者,是解耦的;

  用户调用适配器转化出来的目标接口方法;

  适配器再调用被适配者的相关接口方法;

  用户收到反馈结果,感觉只是和目标接口交互。

设计模式——适配器(Adapter)模式的更多相关文章

  1. 设计模式--适配器(Adapter)模式

    今天学习另一个设计模式,适配器(Adapter)模式,这是一个共同方向,但有特殊要求,就应用到此设计模式.写到这里,想起很久以前,有写过一篇<ASP.NET的适配器设计模式(Adapter)&g ...

  2. 2、适配器 adapter 模式 加个"适配器" 以便于复用 结构型设计模式

    1.什么是适配器模式? 适配器如同一个常见的变压器,也如同电脑的变压器和插线板之间的电源连接线,他们虽然都是3相的,但是电脑后面的插孔却不能直接插到插线板上. 如果想让额定工作电压是直流12伏特的笔记 ...

  3. 【原】模式之-适配器Adapter模式

    适配器Adapter模式 适配器模式(Adapter Pattern)把一个类的接口变换成客户端所期待的的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 模式所涉及的角色有 ...

  4. 设计模式C++描述----06.适配器(Adapter)模式

    一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...

  5. 设计模式之Adapter模式

    说起Adapter,STL里的stack和queue都是adapter,底层是deque,隐藏了deque的一些接口,使得其可以达到FIFO是queue,LIFO是stack. The STL sta ...

  6. Objective-C设计模式——适配器Adapter(接口适配)

    适配器模式 适配器模式通俗来讲,其实就是对客户端添加新的类但却不修改客户端和新的类的接口.此时我们需要自己来实现适配,在适配器模式中有Target对象,即客户端所需要的接口对象,Adaptee对象,即 ...

  7. java演示适配器(adapter)模式

    为什么要使用模式: 模式是一种做事的一种方法,也即实现某个目标的途径,或者技术. adapter模式的宗旨就是,保留现有类所提供的服务,向客户提供接口,以满足客户的需求. 类适配器:客户端定义了接口并 ...

  8. Java 实现适配器(Adapter)模式

    平时我们会常常碰到这种情况,有了两个现成的类,它们之间没有什么联系.可是我们如今既想用当中一个类的方法.同一时候也想用另外一个类的方法.有一个解决方法是.改动它们各自的接口.可是这是我们最不愿意看到的 ...

  9. 适配器(Adapter)模式

    适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的一些其他名称:变压器模式.转换器模式.包装(Wrapper)模式.适 ...

  10. 漫谈设计模式(一):代理(Proxy)模式与适配器(Adapter)模式对比

    1.前言 为什么要将代理模式与适配器模式放在一起来说呢?因为它们有许多的共同点,当然也有一些不同的地方.首先两者都是属于结构型模式.结构型模型是这样定义的: 结构型模式涉及到如何组合类和类以获得更大的 ...

随机推荐

  1. git 删除所有提交下的某个文件

    git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch upload/*' --prune-empty - ...

  2. Using virtual lists

    Download demo project - 15.7 Kb Contents Introduction Virtual list Creating a virtual list Add items ...

  3. android推送,极光推送

    android中简单易用的消息推送方式之中的一个 -------> 极光推送 首先来介绍一下极光推送. 极光推送:英文简称 JPush,是一个面向普通开发人员免费.开放的第三方消息推送服务,我们 ...

  4. MySQL中的表级锁

    数据的锁主要用来保证数据的一致性,数据库的锁从锁定的粒度上可以分为表级锁,行级锁和页级锁. MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制,比如MyISAM和MEMORY存 ...

  5. 【IPC进程间通讯之中的一个】邮槽MailSlot

    IPC进程间通信+邮槽MailSlot                IPC(Inter-Process Communication.进程间通信).        现代计算机採用虚拟内存机制,为进程提 ...

  6. Spark的集群管理器

    上篇文章谈到Driver节点和Executor节点,但是如果想要运行Driver节点和Executor节点,就不能不说spark的集群管理器.spark的集群管理器大致有三种,一种是自带的standa ...

  7. 如何获知PHP程序占用多少内存(复制)

    想要知道编写的 PHP 脚本需要占用多少内存么?很简单,直接使用 PHP 查看当前分配给 PHP 脚本的内存的函数 memory_get_usage() 就可以了 下面是使用示例: 复制代码 代码如下 ...

  8. Django:学习笔记(9)——用户身份认证

    Django:学习笔记(9)——用户身份认证 User

  9. Flask博客开发——自定义头像

    Flask Web开发一书中,使用了与个人邮箱绑定的Gravatar图形作为用户头像.Gravatar提供的头像比较简陋,而且可能由于网络问题无法生成头像.多数社交网站和博客提供用户自定义头像功能,因 ...

  10. 4-es6的模块化编程

    诞生背景其他都是第三方库,只有es才是官方正宗的,如果es早就制定的话,也不至于现在的这么百花齐放(混乱)的局面了 核心规范一个文件就是一个模块export是暴露出模块的公开方法import是导入 实 ...