设计模式——适配器(Adapter)模式
- 概述
什么是适配器?在我们生活中的适配器比如插头转换器(中标转美标)、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)模式的更多相关文章
- 设计模式--适配器(Adapter)模式
今天学习另一个设计模式,适配器(Adapter)模式,这是一个共同方向,但有特殊要求,就应用到此设计模式.写到这里,想起很久以前,有写过一篇<ASP.NET的适配器设计模式(Adapter)&g ...
- 2、适配器 adapter 模式 加个"适配器" 以便于复用 结构型设计模式
1.什么是适配器模式? 适配器如同一个常见的变压器,也如同电脑的变压器和插线板之间的电源连接线,他们虽然都是3相的,但是电脑后面的插孔却不能直接插到插线板上. 如果想让额定工作电压是直流12伏特的笔记 ...
- 【原】模式之-适配器Adapter模式
适配器Adapter模式 适配器模式(Adapter Pattern)把一个类的接口变换成客户端所期待的的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 模式所涉及的角色有 ...
- 设计模式C++描述----06.适配器(Adapter)模式
一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...
- 设计模式之Adapter模式
说起Adapter,STL里的stack和queue都是adapter,底层是deque,隐藏了deque的一些接口,使得其可以达到FIFO是queue,LIFO是stack. The STL sta ...
- Objective-C设计模式——适配器Adapter(接口适配)
适配器模式 适配器模式通俗来讲,其实就是对客户端添加新的类但却不修改客户端和新的类的接口.此时我们需要自己来实现适配,在适配器模式中有Target对象,即客户端所需要的接口对象,Adaptee对象,即 ...
- java演示适配器(adapter)模式
为什么要使用模式: 模式是一种做事的一种方法,也即实现某个目标的途径,或者技术. adapter模式的宗旨就是,保留现有类所提供的服务,向客户提供接口,以满足客户的需求. 类适配器:客户端定义了接口并 ...
- Java 实现适配器(Adapter)模式
平时我们会常常碰到这种情况,有了两个现成的类,它们之间没有什么联系.可是我们如今既想用当中一个类的方法.同一时候也想用另外一个类的方法.有一个解决方法是.改动它们各自的接口.可是这是我们最不愿意看到的 ...
- 适配器(Adapter)模式
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的一些其他名称:变压器模式.转换器模式.包装(Wrapper)模式.适 ...
- 漫谈设计模式(一):代理(Proxy)模式与适配器(Adapter)模式对比
1.前言 为什么要将代理模式与适配器模式放在一起来说呢?因为它们有许多的共同点,当然也有一些不同的地方.首先两者都是属于结构型模式.结构型模型是这样定义的: 结构型模式涉及到如何组合类和类以获得更大的 ...
随机推荐
- centos7 启动docker失败--selinux-enabled=false
centos7,执行完安装命令: yum install docker 执行启动命令: systemctl start docker ,报下面错误: Error starting daemon: ...
- okhttp发送post请求
String url = "http://www.xxx.com/api/test"; OkHttpClient httpClient = new OkHttpClient(); ...
- 用Recover来实现更健壮的go程序
缘起:线上的go service 挂了,无法启动. 原因:采用的第三方库有个bug, 在go携程里面执行task的时候会产生out of range 的panic, 而我又把任务队列每次加载的时候重做 ...
- int文档
文档 class int(object): """ int(x=0) -> integer int(x, base=10) -> integer ------ ...
- 配置MDM的描述文件
配置描述文件 首先需要一个 MDM 配置描述文件,此文件用于安装到设备上,使其向 MDM 服务器注册为受管理的设备. 1.凭证 用iphone配置使用工具,新建一个配置描述文件,在“凭证”栏,创建新凭 ...
- Flask系列(十)自定义Form组件
一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._ ...
- Push h.264 rawdata to rtmp server
Push h.264 rawdata to rtmp server /* The MIT License (MIT) Copyright (c) 2013-2015 SRS(ossrs) Permis ...
- Ubuntu 16.04 源码编译安装PHP7+swoole
备注: Ubuntu 16.04 Server 版安装过程图文详解 Ubuntu16镜像地址: 链接:https://pan.baidu.com/s/1XTVS6BdwPPmSsF-cYF6B7Q 密 ...
- lnmp1.4环境下thinkphp3.2配置pathinfo模式
1.打开php.ini 通常该文件在 /usr/local/php/etc/php.ini vi /usr/local/php/etc/php.ini 找到 cgi.fix_pathinfo,默认为0 ...
- pytorch rnn 2
import torch import torch.nn as nn import numpy as np import torch.optim as optim class RNN(nn.Modul ...