Adapter(适配器模式)

合集下载

适配器(Adaptor)模式PPT教学课件

适配器(Adaptor)模式PPT教学课件
public double getMass(){ } public double getThrust(){ } public void setSimTime(double time){this.time=time;} }
2020/12/10
7
类适配器简单例子
public interface Print { public abstract void printWeak(); public abstract void printStrong();
} }
2020/12/10
9
对象适配器
Client
RequiredClass ______________ requiredMethod()
ExistingClass __________ usefulMethod()
} ============================ public class Main {
public static void main(String[] args) { Print p = new PrintBanner("Hello"); p.printWeak(); p.printStrong();
2020/12/10
4
Adapter模式
Struct
class adapter
object adapter
2020/12/10
5
例子
《interface》
RocketSim getMass():double getThrust():double setSimTime(t:double)
PhysicalRocket
} -------------------------public class Banner {

尚硅谷设计模式笔记-适配器模式

尚硅谷设计模式笔记-适配器模式

尚硅⾕设计模式笔记-适配器模式Table of Contents generated with⼀、⽣活中的适配器每个国家使⽤的插座标准不同,⽐如泰国⽤的是两孔的(欧标),中国⽤的是三孔的。

我们到泰国旅游时,如果只带了三孔插头,则可以买个多功能转换插头【适配器】,这样就可以使⽤泰国的两孔插座了。

⼆、程序中的适配器模式2.1 基本介绍1. 适配器模式(Adapter Pattern)将某个类的接⼝转换成客户端期望的另⼀个接⼝表⽰,主的⽬的是兼容性,让原本因接⼝不匹配不能⼀起⼯作的两个类可以协同⼯作。

其别名为包装器(Wrapper)2. 适配器模式属于结构型模式【并没有产⽣新的对象】3. 主要分为三类:类适配器模式、对象适配器模式、接⼝适配器模式2.2 ⼯作原理1. 适配器模式:将⼀个类的接⼝转换成另⼀种接⼝。

让原本接⼝不兼容的类可以兼容2. 从⽤户的⾓度看不到被适配者,是解耦的3. ⽤户调⽤适配器转化出来的⽬标接⼝⽅法,适配器再调⽤被适配者的相关接⼝⽅法4. ⽤户收到反馈结果,感觉只是和⽬标接⼝交互,如图三、类适配器模式基本介绍:Adapter类,通过继承src类,实现dst类接⼝,完成src->dst的适配。

3.1 应⽤实例以⽣活中充电器的例⼦来讲解适配器,充电器本⾝相当于Adapter, 220V交流电相当于src (即被适配者),我们的dst(即⽬标)是5V直流电3.2 类图我们⼿机需要5v的直流电,则调⽤5v直流电的接⼝,然后使⽤适配器VoltageAdapter将220v的电压转为5v即可3.3 java实现1. ⾸先实现220v电压//被适配类Sourcepublic class Voltage220v {public int output220v(){int src = 220;System.out.println("输出"+src+"伏特");return src;}}2. 然后创建5v直流电接⼝//适配接⼝public interface Voltage5v {int output5v();}3. 创建适配器类,继承voltage220v,实现voltage5v//适配器public class VoltageAdapter extends Voltage220v implements Voltage5v{@Overridepublic int output5v() {int source = output220v();int target = source / 44;return target;}}4. ⼿机类public class Phone{public void chargiing(Voltage5v voltage5v){if(voltage5v.output5v()==5){System.out.println("电压为5v,可以充电");}else{System.out.println("电压不合适,不可以充电");}}}5. 调⽤:public class Client {public static void main(String[] args) {System.out.println("===========类适配器模式===========");Phone phone = new Phone();//VoltageAdapter相当于充电器phone.chargiing(new VoltageAdapter());}}输出为:=类适配器模式=输出220伏特电压为5v,可以充电3.4 总结类适配器模式注意事项和细节Java是单继承机制,所以类适配器需要继承src类这⼀点算是⼀个缺点,因为这要求dst必须是接⼝,有⼀定局限性;src类的⽅法在Adapter中都会暴露出来,也增加了使⽤的成本。

php教程 php设计模式介绍之适配器模式

php教程 php设计模式介绍之适配器模式

php教程php设计模式介绍之适配器模式接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题。

程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相关库的发展和进化。

我孩子的无数玩具中有一个简要地描述了这个两难局面:你无法合理安排一个不得其所的人。

问题你如何避免因外部库的API改变而带来的不便?假如你写了一个库,你能否提供一种方法允许你软件的现有用户进行完美地升级,即使你已经改变了你的API?为了更好地适宜于你的需要,你应该如何改变一个对象的接口?解决方案适配器(Adapter)模式为对象提供了一种完全不同的接口。

你可以运用适配器(Adapter)来实现一个不同的类的常见接口,同时避免了因升级和拆解客户代码所引起的纠纷。

考虑一下当(不是假设!)一个第三方库的API改变将会发生什么。

过去你只能是咬紧牙关修改所有的客户代码,而情况往往还不那么简单。

你可能正从事一项新的项目,它要用到新版本的库所带来的特性,但你已经拥有许多旧的应用程序,并且它们与以前旧版本的库交互运行地很好。

你将无法证明这些新特性的利用价值,如果这次升级意味着将要涉及到其它应用程序的客户代码。

注:控制体模式适配器(Adapter)模式是控制体模式的最新范例。

一个适配器(Adapter)的结构类似于代理服务器(Proxy)和修饰器(Decorator),而它们的不同之处在于,适配器(Adapter)的目的是改变封装类的接口,代理服务器(Proxy)和修饰器(Decorator)则是保持接口不变。

样本代码让我们看看当API改变时,如何保护应用程序不受影响。

假设你费尽心思寻找合适的库,最后终于找到了HwLib,一个(假设的)被设计用来发送信息的代码集。

下面是HwLib类的源代码:// PHP4/*** the HwLib helps programmers everywhere write their first program* @package HelloWorld* @version 1*/class HwLib {/*** Say “Hello”* @deprec this function is going away in the future* @return string*/function hello() {return …Hello …;}/*** target audience* @return string*/function world() {return …World!‟;}}下面是库运行的范例:$hw =& new HwLib;echo $hw->hello(), $hw->world();HwLib有完备的说明文档。

adapter 概念

adapter 概念

adapter 概念
Adapter(适配器)是一种软件设计模式,它将一个类或对象的接口转换为另一个接口,以使它们能够协同工作。

这种模式通常用于解决不兼容的类或对象之间的交互问题。

在Adapter 模式中,存在三个主要角色:
1. 目标(Target)对象:这是需要适配的对象或类,它具有特定的接口。

2. 源(Adaptee)对象:这是需要被适配的对象或类,它的接口与目标对象不兼容。

3. Adapter 类:这个类负责将源对象的接口转换为目标对象的接口。

Adapter 类通过实现目标对象的接口,并在内部使用源对象的方法来实现转换。

这样,源对象就可以在不修改其代码的情况下与目标对象进行交互。

使用Adapter 模式的好处包括:提高代码的可复用性、减少代码的耦合度、使不兼容的类能够协同工作等。

Adapter 模式是一种非常有用的设计模式,它可以帮助我们解决许多实际的编程问题。

8.Adapter适配器模式

8.Adapter适配器模式

适配器模式,使用之处比较特殊,不属于常规设计模式,主要用于不同系统之间的处理。

是将一个类的接口转换成客户希望的另外一个接口。

Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

也是一个比较简单的模式,直接上代码了。

看代码:8.1.解释main(),主程序IUserInfo,本系统内接口CUserInfo,本系统内实现类IOuterUser,外系统接口COuterUser,外系统实现类COuterUserInfo,本系统内适配类说明:COuterUserInfo实现IUserInfo接口,将外部系统实现类COuterUser转换成本系统内的接口I UserInfo。

使用外部数据跟使用本系统内部数据一样。

注意:COuterUserInfo继承了IUserInfo,如果同时继承了COuterUser则是类适配器。

如果COuter UserInfo只是使用了COuterUser则是对象适配器。

//IUserInfo.h//系统内部的实体接口#pragma once#include <iostream>using std::string;class IUserInfo{public:IUserInfo(void){}virtual ~IUserInfo(void){}virtual string GetUserName() = 0;virtual string GetHomeAddress() = 0;virtual string GetMobileNumber() = 0;virtual string GetOfficeTelNumber() = 0;virtual string GetJobPosition() = 0;virtual string GetHomeTelNumber() = 0; };//UserInfo.h//系统内部实体类#pragma once#include "iuserinfo.h"#include <iostream>using std::string;class CUserInfo :public IUserInfo{public:CUserInfo(void);~CUserInfo(void);string GetUserName();string GetHomeAddress();string GetMobileNumber();string GetOfficeTelNumber();string GetJobPosition();string GetHomeTelNumber();};//UserInfo.cpp#include "StdAfx.h"#include "UserInfo.h"#include <iostream>using std::cout;using std::endl;using std::string;CUserInfo::CUserInfo(void){}CUserInfo::~CUserInfo(void){}string CUserInfo::GetUserName(){cout << "姓名叫做..." << endl;return "0";}string CUserInfo::GetHomeAddress(){cout << "这里是员工的家庭地址..." << endl;return "0";}string CUserInfo::GetMobileNumber(){cout << "这个人的手机号码是0000..." << endl;return "0";}string CUserInfo::GetOfficeTelNumber(){cout << "办公室电话是..." << endl;return "0";}string CUserInfo::GetJobPosition(){cout << "这个人的职位是BOSS..." << endl;return "0";}string CUserInfo::GetHomeTelNumber(){cout << "员工的家庭电话是..." << endl;return "0";}//IOuterUser.h//外部系统实体接口#pragma once#include "OuterUserBaseInfo.h"#include "OuterUserHomeInfo.h"#include "OuterUserOfficeInfo.h"class IOuterUser{public:IOuterUser(void){}~IOuterUser(void){}COuterUserBaseInfo * GetUserBaseInfo();COuterUserHomeInfo * GetUserHomeInfo();COuterUserOfficeInfo * GetUserOfficeInfo(); };//OuterUser.h//外部系统实体类#pragma once#include "OuterUserBaseInfo.h"#include "OuterUserHomeInfo.h"#include "OuterUserOfficeInfo.h"class COuterUser{public:COuterUser(void){}~COuterUser(void){}COuterUserBaseInfo * GetUserBaseInfo();COuterUserHomeInfo * GetUserHomeInfo();COuterUserOfficeInfo * GetUserOfficeInfo(); };//OuterUser.cpp#include "StdAfx.h"#include "OuterUser.h"#include "OuterUserBaseInfo.h"#include "OuterUserHomeInfo.h"#include "OuterUserOfficeInfo.h"COuterUser::COuterUser(void){}COuterUser::~COuterUser(void){}COuterUserBaseInfo * COuterUser::GetUserBaseInfo() {return new COuterUserBaseInfo();}COuterUserHomeInfo * COuterUser::GetUserHomeInfo() {return new COuterUserHomeInfo();}COuterUserOfficeInfo * COuterUser::GetUserOfficeInfo() {return new COuterUserOfficeInfo();}//OuterUserBaseInfo.h#pragma once#include <iostream>using std::endl;using std::string;class COuterUserBaseInfo{public:COuterUserBaseInfo(void){}~COuterUserBaseInfo(void){}string GetUserName(){cout << "姓名叫做..." << endl;return "0";}string GetMobileNumber(){cout << "这个人的手机号码是0001..." << endl;return "0";}};//OuterUserHomeInfo.h#pragma once#include <iostream>using std::cout;using std::string;class COuterUserHomeInfo{public:COuterUserHomeInfo(void){}~COuterUserHomeInfo(void){}string GetHomeAddress(){cout << "这里是员工的家庭地址..." << endl;return "0";}string GetHomeTelNumber(){cout << "员工的家庭电话是..." << endl;return "0";}};//OuterUserOfficeInfo.h#pragma once#include <iostream>using std::cout;using std::endl;class COuterUserOfficeInfo{public:COuterUserOfficeInfo(void){}~COuterUserOfficeInfo(void){}string GetOfficeTelNumber(){cout << "办公室电话是..." << endl;return "0";}string GetJobPosition(){cout << "这个人的职位是BOSS..." << endl;return "0";}};//OuterUserInfo.h//由IUserInfo接口派生的实体类,并引入外部系统实体的实例#pragma once#include "iuserinfo.h"#include "OuterUser.h"#include <iostream>using std::string;class COuterUserInfo :public IUserInfo{public:COuterUserInfo(void);~COuterUserInfo(void);string GetUserName();string GetHomeAddress();string GetMobileNumber();string GetOfficeTelNumber();string GetJobPosition();string GetHomeTelNumber(); private:COuterUser *m_pOuterUser;};//OuterUserInfo.cpp#include "StdAfx.h"#include "OuterUserInfo.h"#include "OuterUserBaseInfo.h"#include "OuterUserHomeInfo.h"#include "OuterUserOfficeInfo.h"#include <iostream>using std::cout;using std::endl;using std::string; COuterUserInfo::COuterUserInfo(void) {m_pOuterUser = new COuterUser();COuterUserInfo::~COuterUserInfo(void){delete m_pOuterUser;}string COuterUserInfo::GetUserName(){COuterUserBaseInfo *pBaseInfo = m_pOuterUser->GetUserBaseInfo();pBaseInfo->GetUserName();delete pBaseInfo;pBaseInfo = NULL;return "0";}string COuterUserInfo::GetHomeAddress(){COuterUserHomeInfo *pHomeInfo = m_pOuterUser->GetUserHomeInfo();pHomeInfo->GetHomeAddress();delete pHomeInfo;pHomeInfo = NULL;return "0";}string COuterUserInfo::GetMobileNumber(){COuterUserBaseInfo *pBaseInfo = m_pOuterUser->GetUserBaseInfo();pBaseInfo->GetMobileNumber();delete pBaseInfo;pBaseInfo = NULL;return "0";string COuterUserInfo::GetOfficeTelNumber(){COuterUserOfficeInfo *pOfficeInfo = m_pOuterUser->GetUserOfficeInfo();pOfficeInfo->GetOfficeTelNumber();delete pOfficeInfo;pOfficeInfo = NULL;return "0";}string COuterUserInfo::GetJobPosition(){COuterUserOfficeInfo *pOfficeInfo = m_pOuterUser->GetUserOfficeInfo();pOfficeInfo->GetJobPosition();delete pOfficeInfo;pOfficeInfo = NULL;return "0";}string COuterUserInfo::GetHomeTelNumber(){COuterUserHomeInfo *pHomeInfo = m_pOuterUser->GetUserHomeInfo();pHomeInfo->GetHomeTelNumber();delete pHomeInfo;pHomeInfo = NULL;return "0";}//Adapter.cpp//使用方法#include "stdafx.h"#include "IOuterUser.h"#include "IUserInfo.h"#include "UserInfo.h"#include "OuterUserInfo.h"void DoIt(){IUserInfo *pYourGirl = new CUserInfo();for(int i = 0; i < 101; i += 20){pYourGirl->GetMobileNumber();}delete pYourGirl;}void NowDoIt(){IUserInfo *pYourGirl = new COuterUserInfo();for(int i = 0; i < 101; i += 20){pYourGirl->GetMobileNumber();}delete pYourGirl;}int _tmain(int argc, _TCHAR* argv[]){DoIt();NowDoIt();_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);_CrtDumpMemoryLeaks();return 0;}适配器模式属于结构型模式,当出现数据接口不一致的情况下,才会使用到。

adapter方法

adapter方法

adapter方法适配器模式适配器模式(Adapter Pattern)是一种结构型设计模式,使得不兼容的接口可以一起工作。

适配器模式允许对象以不同的接口表现,使得原本因接口不一致而无法在一起工作的类可以协同工作。

适配器方法适配器方法是适配器模式的一种具体实现方式。

它通过在原有接口和目标接口之间增加一个适配器来实现接口的转换。

类适配器类适配器使用继承关系来实现接口转换。

适配器类继承自原有类,并实现目标接口,从而使得原有类的方法可以通过目标接口调用。

类适配器的实现步骤:1.创建目标接口,即适配后期望的接口。

2.创建源接口,即需要适配的接口。

3.创建适配器类,继承源接口并实现目标接口,在适配器类中实现方法映射关系。

4.在适配器类中重写目标接口的方法,将调用具体方法的任务委托给源接口的方法。

示例代码:public interface Target {void request();}public class Adaptee {public void specificRequest() {// 具体请求的逻辑实现}}public class Adapter extends Adaptee implements Target { @Overridepublic void request() {specificRequest();}}public class Client {public static void main(String[] args) {Target target = new Adapter();();}}对象适配器对象适配器使用组合关系来实现接口转换。

适配器类持有源类的实例,并实现目标接口,从而使得源类的方法可以通过目标接口调用。

对象适配器的实现步骤:1.创建目标接口,即适配后期望的接口。

2.创建源接口,即需要适配的接口。

3.创建适配器类,持有源接口的实例并实现目标接口。

4.在适配器类中实现目标接口的方法,将调用具体方法的任务委托给源接口的方法。

一文彻底弄懂适配器模式(Adapter)

一文彻底弄懂适配器模式(Adapter)

⼀⽂彻底弄懂适配器模式(Adapter)⽂章已收录我的仓库:设计意图适配器模式(Adapter Pattern)是作为两个不兼容的接⼝之间的桥梁。

这种类型的设计模式属于结构型模式,它结合了两个独⽴接⼝的功能。

在某些时候,客户期望获得某种功能接⼝但现有的接⼝⽆法满⾜客户的需求,例如美国的正常供电电压为110V,⼀个中国⼈带了⼀款中国制造电器去美国,这个电器必须要在220V电压下才能充电使⽤。

这种情况下,客户(中国⼈)的期望接⼝是有⼀个220V的电压为电器充电,但实际的接⼝是仅有⼀个110V的电压供电器充电,这种情况下就需要采⽤⼀根电压转换器(适配器)使得110V的电压能够转换为220V的电压,供客户使⽤。

将⼀个类的接⼝转换成客户希望的另外⼀个接⼝,这就是适配器需要做的事情,适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作。

适⽤条件系统需要使⽤现有的类,⽽此类的接⼝不符合系统的需要(核⼼需求)。

想要建⽴⼀个可以重复使⽤的适配器类,⽤于与⼀些彼此之间没有太⼤关联的⼀些类,包括⼀些可能在将来引进的类⼀起⼯作,这些源类不⼀定有⼀致的接⼝,但通过适配器使得它们都具有⼀致的接⼝。

通过接⼝转换,将⼀个类插⼊另⼀个类系中。

(⽐如⽼虎和飞禽,现在多了⼀个飞虎,在不增加实体的需求下,增加⼀个适配器,在⾥⾯包容⼀个虎对象,实现飞的接⼝。

)设计通常有两种⽅式实现适配器模式,⼀种是类适配器,类适配器⽬前已不太使⽤,另⼀种实现⽅式是对象适配器,通常情况下采⽤对象适配器会使得代码更易扩展与维护。

不管采⽤何种⽅式,其基本的实现思想都是:对现有接⼝的实现类进⾏扩展,使其实现客户期望的⽬标接⼝。

类适配器通过继承现有接⼝类并实现⽬标接⼝,这样的话会使得现有接⼝类完全对适配器暴露,使得适配器具有现有接⼝类的全部功能,破坏了封装性。

此外从逻辑上来说,这也是不符合常理的,适配器要做的是扩展现有接⼝类的功能⽽不是替代,类适配器只有在特定条件下会被使⽤。

一天一个设计模式——Adapter适配器模式(Wrapper模式)

一天一个设计模式——Adapter适配器模式(Wrapper模式)

⼀天⼀个设计模式——Adapter适配器模式(Wrapper模式)⼀、模式说明 在现实⽣活中,当需要将两种设备连接起来,但是两个设备的接⼝规范⼜不⼀致(⽐如电脑上只有Type-C接⼝,但是你的显⽰器是HDMI接⼝),这时候就需要⼀个适配器,适配器⼀端连接电脑,⼀端连接屏幕。

有了这个适配器,我们不需要重新买HDMI接⼝电脑的电脑,就可以达到我们连接外置显⽰器的⽬的。

在程序设计领域,很多时候我们的⼯作是在现有类的基础上继续开发的,如果这个类已经实现了我们要的功能且该类经过充分测试(修改它可能会引⼊bug),但是接⼝不符合当前程序环境规范,需要适当转换,这时就⽤到了Adapter模式的设计思想,创建⼀个Adapter适配器(Wrapper包装器),使原有的类能适应新的程序环境。

⼆、模式分类Adapter模式有以下两种:类适配器模式(使⽤继承的适配器)对象适配器模式(使⽤委托的适配器)三、适配器模式中的⾓⾊Target对象:负责定义所需要的⽅法,具体的业务需求(如上⾯例⼦中的HDMI视频接⼝);Client请求者:负责使⽤Target⾓⾊定义的⽅法做具体处理(如上⾯例⼦中的显⽰器,使⽤Target提供的HDMI接⼝来显⽰图像);Adaptee被适配:⼀个持有既定⽅法的⾓⾊(如⾯例⼦中的笔记本电脑,持有Type-C接⼝输出);Adapter适配器:Adapter模式的主⼈公,使⽤Adaptee的⽅法来满⾜Target的需求;四、代码⽰例使⽤继承的类适配器:TypeCVideo类(Adaptee):package .adapterpattern;public class TypeCVideo {private String videoContent;public TypeCVideo(String videoContent){this.videoContent = videoContent;}public void typecOut(){System.out.println(videoContent);}}View CodeShowHdmiVideo类(Target对象):package .adapterpattern;public interface ShowHdmiVideo {public abstract void HdmiOut();}View CodeTypeCToHdmiCable类(Adapter类):package .adapterpattern;/*** <p>TypeCToHdmiCable TypeC转HDMI线适配器类</p>*/public class TypeCToHdmiCable extends TypeCVideo implements ShowHdmiVideo {//TypeC转HDMI线 TypeCToHdmiCable类继承了TypeCVideo类public TypeCToHdmiCable(String videoContent){super(videoContent);//设置⽗类的视频内容videoContent字段}@Overridepublic void HdmiOut() {typecOut();}}View Code测试运⾏结果:上⾯的例⼦,通过继承TypeCVideo的⽅式创建新的类,并实现新业务需要的HDMI接⼝,从⽽将TypeC中视频流(Video Streaming字符串)从HDMI接⼝输出处来。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

• 客户端(Client)
– 协同对象符合Adapter适配器
2010年12月21日
第4页
• 有两种类型的适配器模式
– 类适配器(采取继承的方式) – 对象适配器(采取对象组合的方式)推荐
2010年12月21日
第5页
• 对象需要利用现存的并且接口不兼容的类 。 • 需要创建可重用的类以协调其他接口可能 不兼容的类。
北京圣思园科技有限公司
• 在软件系统中,由于应用环境的变化,常 常需要将“一些现存的对象”放在新的环 境中应用,但是新环境要求的接口是这些 现存对象所不满足的。那么如何应对这种 “迁移的变化”?如何既能利用现有对象 的良好实现,同时又能满足新的应用环境 所要求的接口?这就是本文要说的Adapter 模式。
• 将一个类的接口转换成客户希望的另外一 个接口。Adapter模式使得原本由于接口不 兼容而不能一起工作的那些类可以一起工 作
• 目标抽象角色(Target)
– 定义客户要用的特定领域的接口
• 适配器(Adapter)
– 调用另一个接口,作为一个转换器
• 适配器(Adaptee)
– 定义一个接口,Adapter需要接入
2010年12月21日
第6页
相关文档
最新文档