第8章 适配器模式
- 格式:ppt
- 大小:599.00 KB
- 文档页数:51
适配器模式和组合模式的比较适配器模式和组合模式都是常用的设计模式,它们在实际开发中经常被用到。
虽然这两种模式看起来很像,但它们的作用和实现方式有很大的区别。
在本文中,我们将介绍适配器模式和组合模式的比较。
一、适配器模式适配器模式是一种结构性设计模式,它能够将不兼容的接口转换成另一种接口,使得不同类之间能够相互协作。
适配器模式的核心思想是将一个类的接口,转换成客户端所期望的另一种接口,从而使得原本不兼容的类能够协同工作。
适配器模式的实现方式通常有两种:类适配器和对象适配器。
其中,类适配器使用继承机制对源接口进行扩展,而对象适配器则是使用组合机制来实现接口转换。
适配器模式的应用场景比较广泛,例如在使用第三方库时,可能会遇到接口不兼容的情况,此时就可以使用适配器模式来解决这个问题。
二、组合模式组合模式是一种结构性设计模式,它将对象组合成树形结构,使得用户无需区分单个对象和组合对象,从而可以统一地处理所有对象。
组合模式的核心思想是将对象组合成树形结构,从而将复杂的对象模型简化为单一的对象结构。
组合模式的实现方式通常有两种:透明组合模式和安全组合模式。
其中,透明组合模式是将叶子对象和组合对象都看做一种对象,从而对外具体透明,而安全组合模式则是将叶子对象和组合对象分开处理,从而增强了类型安全。
组合模式的应用场景比较广泛,例如在操作文件系统时,可能会遇到需要同时操作文件和目录的情况,此时就可以使用组合模式来解决这个问题。
三、适配器模式和组合模式的比较适配器模式和组合模式都是常用的设计模式,它们在实际开发中经常被用到。
虽然这两种模式看起来很像,但它们的作用和实现方式有很大的区别。
首先,适配器模式的主要作用是将不兼容的接口转换成另一种接口,从而使得不同类之间能够相互协作。
而组合模式的主要作用是将对象组合成树形结构,从而可以统一地处理所有对象。
其次,适配器模式通常使用继承或组合机制来实现接口转换,而组合模式则是使用组合机制来实现对象的组合。
适配器模式实现方式详解适配器模式是一种非常重要的设计模式,主要用于解决不兼容的问题。
适配器模式的核心思想是将一个类的接口转换成另一个客户希望的接口。
在本文中,我们将详细介绍适配器模式的实现方式,包括类适配器、对象适配器和接口适配器。
一、类适配器类适配器是最常用的适配器实现方式之一。
它使用多重继承的方式对目标接口和源接口进行适配。
在类适配器中,适配器类同时继承了目标接口和源接口。
适配器类从源接口继承了需要适配的方法,并在实现目标接口时,将这些方法进行适当的转换。
下面是一个简单的类适配器实现示例:```c++// 源接口class Adaptee {public:virtual void adapteeMethod() {// TODO: 实现需要适配的方法}};// 目标接口class Target {public:virtual void targetMethod() = 0;};// 适配器类class Adapter : public Target, private Adaptee { public:virtual void targetMethod() {adapteeMethod(); // 调用需要适配的方法 // TODO: 实现对目标接口的转换}};上述代码中,适配器类同时继承了目标接口(Target)和源接口(Adaptee),并在实现目标接口时将需要适配的方法适当地转换了一下。
二、对象适配器对象适配器也是一种常用的适配器实现方式。
与类适配器不同的是,对象适配器使用组合的方式进行适配,而不是继承。
在对象适配器中,适配器类持有一个源接口的实例,并使用该实例将目标接口适配成源接口。
下面是一个简单的对象适配器实现示例:```c++// 源接口class Adaptee {public:virtual void adapteeMethod() {// TODO: 实现需要适配的方法};// 目标接口class Target {public:virtual void targetMethod() = 0;};// 适配器类class Adapter : public Target {public:Adapter(Adaptee* adaptee) : m_adaptee(adaptee) {}virtual void targetMethod() {m_adaptee->adapteeMethod(); // 调用需要适配的方法 // TODO: 实现对目标接口的转换}private:Adaptee* m_adaptee;};```上述代码中,适配器类持有一个源接口的实例,当调用目标接口时,适配器将调用源接口实例的适配方法,并在转换后实现目标接口的方法。
java设计模式之适配器模式
结构型模式之适配器模式
将⼀个类的接⼝转换成客户希望的另外⼀个接⼝,使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类能⼀起⼯作。
适配器模式分为:类适配器模式和对象适配器模式。
类适配器模式通过继承和实现⽅式来实现,对象适配器模式通过聚合和组合关系来实现,前者类之间的耦合度⽐后者⾼,且要求程序员了解现有组件库中的相关组件的内部结构,所以应⽤相对较少些。
适配器模式的结构:
适配器模式(Adapter)包含以下主要⾓⾊:
⽬标接⼝(Target):当前系统业务所期待的接⼝,它可以是抽象类或接⼝。
适配者类(Adaptee):它是被访问和适配的现存组件库中的组件接⼝。
适配器类(Adapter):它是⼀个转换器,通过继承或引⽤适配者的对象,把适配者接⼝转换成⽬标接⼝,让客户按⽬标接⼝的格式访问适配者。
类适配器模式:
实现⽅式:定义⼀个适配器类来实现当前系统的业务接⼝,同时⼜继承现有组件库中已经存在的组件。
类适配器模式违背了合成服⽤原则。
类适配器是客户类有⼀个接⼝规范的情况下可⽤,反之不可⽤。
对象适配器模式:
实现⽅式:对象适配器模式可采⽤将现有组件库中已经实现的组件引⼊适配器类中,该类同时实现当前系统的业务接⼝。
注意:还有⼀个适配器模式是接⼝适配器模式,当不希望实现⼀个接⼝中所有的⽅法是,可以创建⼀个抽象类Adapter,实现所有⽅法。
⽽此时我们只需要继承该抽象类即可。
应⽤场景:
以前开发的系统存在满⾜新系统功能需求的类,但其接⼝同新系统的接⼝不⼀致。
使⽤第三⽅提供的组件时,但组件接⼝定义和⾃⼰要求的接⼝定义不同。
C语⾔和设计模式(适配器模式)⽂章⽬录⼀句话理解1、将⼀个类的接⼝转换成客户希望的另外⼀个接⼝2、使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作3、尽可能保持已有的类不变的前提下,适应当前的系统适配器模式实现步骤类适配器1、确定⽬标接⼝2、确定被适配者3、创建适配器(继承⾃被适配者,实现⽬标接⼝)对象适配器1、确定⽬标接⼝2、确定被适配者3、创建适配器(拥有被适配者的对象,实现⽬标接⼝)举例 现在的⽣活当中,我们离不开各种电⼦⼯具。
什么笔记本电脑、⼿机、mp4啊,都离不开充电。
既然是充电,那么就需要⽤到充电器。
其实从根本上来说,充电器就是⼀个个普通的适配器。
什么叫适配器呢,就是把220v、50hz的交流电压编程5~12v的直流电压。
充电器就⼲了这么⼀件事情。
那么,这样的⼀个充电适配器,我们应该怎么⽤c++描述呢?class voltage_12v{public:voltage_12v() {}virtual ~voltage_12v() {}virtual void request() {}};class v220_to_v12{public:v220_to_v12() {}~v220_to_v12() {}void voltage_transform_process() {}};class adapter: public voltage_12v{v220_to_v12* pAdaptee;public:adapter() {}~adapter() {}void request(){pAdaptee->voltage_transform_process();}}; 通过上⾯的代码,我们其实可以这样理解。
类voltage_12v表⽰我们的最终⽬的就是为了获得⼀个12v的直流电压。
当然获得12v可以有很多的⽅法,利⽤适配器转换仅仅是其中的⼀个⽅法。
adapter表⽰适配器,它⾃⼰不能实现220v到12v的转换⼯作,所以需要调⽤类v220_to_v12的转换函数。
适配器模式,使用之处比较特殊,不属于常规设计模式,主要用于不同系统之间的处理。
是将一个类的接口转换成客户希望的另外一个接口。
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模式使⽤的原本由于接⼝不兼容⽽不能茉莉花物那些可以⼀起⼯作。
⼆、解决的问题1、使⽤第三⽅组件,⽽这个组件的接⼝与⽬前系统接⼝不兼容(如⽅法与系统⽅法不⼀致等),可以使⽤适配器模式解决接⼝不兼容问题。
2、使⽤早前项⽬⼀些有⽤的类,可以⽤适配器模式解决现有接⼝与原有对象接⼝不兼容问题。
三、⽣活中的例⼦适配器模式允许将⼀个类的接⼝转换成客户期望的另⼀个接⼝,使⽤原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。
扳⼿提供了⼀个适配器的例⼦。
⼀个孔套在棘齿上,棘齿的每个边的尺⼨是相同的。
在美国典型的连长为1/2和1/4。
显然,如果不使⽤⼀个适配器的话,1/2的棘齿不能适合1/4的孔。
⼀个1/2到1/4的适配器具有⼀个1/2的阴槽来套上⼀个1/2的齿,同时有⼀个1/4的阳槽来卡⼊1/4的扳⼿。
四、适配器分析1.适配器模式结构2.代码1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;67namespace适配器模式8 {9///<summary>10///客户期待的接⼝或者抽象类Target11///</summary>12public abstract class Target13 {14public abstract void Request();15 }16 }客户期待的接⼝或者抽象类Target1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;67namespace适配器模式8 {9///<summary>10///要适配的类Adaptee,也就是与期望调⽤接⼝不相符的类11///</summary>12public class Adaptee13 {14public void SpecificReques() {15 Console.WriteLine("执⾏要适配类的特殊请求⽅法");16 }17 }18 }要适配的类Adaptee,也就是与期望调⽤接⼝不相符的类1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;67namespace适配器模式8 {9public class Adapter:Target10 {11private Adaptee adaptee;12public override void Request()13 {14if (adaptee == null) {15 adaptee = new Adaptee();16 }17 adaptee.SpecificReques();18 }19 }20 }适配器类Adapter,把源接⼝转换成⽬标接⼝,包⾏变量adaptee1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;67namespace适配器模式8 {9///<summary>10///适配器模式,将⼀个类装换成客户期望的另外⼀个接⼝。
⼀⽂彻底弄懂适配器模式(Adapter)⽂章已收录我的仓库:设计意图适配器模式(Adapter Pattern)是作为两个不兼容的接⼝之间的桥梁。
这种类型的设计模式属于结构型模式,它结合了两个独⽴接⼝的功能。
在某些时候,客户期望获得某种功能接⼝但现有的接⼝⽆法满⾜客户的需求,例如美国的正常供电电压为110V,⼀个中国⼈带了⼀款中国制造电器去美国,这个电器必须要在220V电压下才能充电使⽤。
这种情况下,客户(中国⼈)的期望接⼝是有⼀个220V的电压为电器充电,但实际的接⼝是仅有⼀个110V的电压供电器充电,这种情况下就需要采⽤⼀根电压转换器(适配器)使得110V的电压能够转换为220V的电压,供客户使⽤。
将⼀个类的接⼝转换成客户希望的另外⼀个接⼝,这就是适配器需要做的事情,适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作。
适⽤条件系统需要使⽤现有的类,⽽此类的接⼝不符合系统的需要(核⼼需求)。
想要建⽴⼀个可以重复使⽤的适配器类,⽤于与⼀些彼此之间没有太⼤关联的⼀些类,包括⼀些可能在将来引进的类⼀起⼯作,这些源类不⼀定有⼀致的接⼝,但通过适配器使得它们都具有⼀致的接⼝。
通过接⼝转换,将⼀个类插⼊另⼀个类系中。
(⽐如⽼虎和飞禽,现在多了⼀个飞虎,在不增加实体的需求下,增加⼀个适配器,在⾥⾯包容⼀个虎对象,实现飞的接⼝。
)设计通常有两种⽅式实现适配器模式,⼀种是类适配器,类适配器⽬前已不太使⽤,另⼀种实现⽅式是对象适配器,通常情况下采⽤对象适配器会使得代码更易扩展与维护。
不管采⽤何种⽅式,其基本的实现思想都是:对现有接⼝的实现类进⾏扩展,使其实现客户期望的⽬标接⼝。
类适配器通过继承现有接⼝类并实现⽬标接⼝,这样的话会使得现有接⼝类完全对适配器暴露,使得适配器具有现有接⼝类的全部功能,破坏了封装性。
此外从逻辑上来说,这也是不符合常理的,适配器要做的是扩展现有接⼝类的功能⽽不是替代,类适配器只有在特定条件下会被使⽤。
适配器模式的使用流程1. 什么是适配器模式?适配器模式(Adapter Pattern)是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一个接口。
适配器模式可以让原本由于接口不兼容而不能一起工作的类能够合作无间。
2. 为什么要使用适配器模式?在软件开发中,经常会遇到以下情况:•已有的类不能满足新的接口要求。
•要使用的类与已有的其他类无法协同工作。
•想要创建一个可复用的类,可以与多个不兼容的类协同工作。
适配器模式提供了一种解决方案,通过适配器,将不兼容的类进行适配,使其能够协同工作。
3. 适配器模式的基本结构适配器模式包含以下几个基本元素:•目标接口(Target):定义客户端所期望的接口。
•适配者类(Adaptee):需要被适配的类。
•适配器类(Adapter):将适配者类转换成目标接口的类。
4. 如何使用适配器模式?使用适配器模式的基本流程如下:1.定义目标接口(Target)。
2.创建适配者类(Adaptee),该类包含一些需要被适配的方法。
3.创建适配器类(Adapter),实现目标接口,并在内部维护一个适配者对象。
4.在适配器类中实现目标接口的方法,通过调用适配者对象的方法来完成适配。
5.在客户端代码中,通过使用适配器类来调用目标接口的方法,实现对适配者类的使用。
5. 适配器模式的实例假设我们正在开发一个音乐播放器,需要支持多种格式的音频文件,包括MP3、WAV和FLAC。
现在我们已经有了一个已经实现了MP3播放的类MP3Player,但是我们的播放器需要支持所有三种格式的音频文件。
首先,我们定义目标接口AudioPlayer:•play(file: string): void:播放音频文件。
接下来,创建适配者类MP3Player:class MP3Player {playMP3(file: string): void {console.log(`播放MP3音频文件 ${file}`);}}然后,创建适配器类AudioPlayerAdapter,实现目标接口,并在内部维护一个MP3Player对象:class AudioPlayerAdapter implements AudioPlayer {private mp3Player: MP3Player;constructor() {this.mp3Player = new MP3Player();}play(file: string): void {this.mp3Player.playMP3(file);}}最后,在我们的音乐播放器中使用适配器模式:```typescript const audioPlayerAdapter = new AudioPlayerAdapter(); audioPlayerAdapter.play(。
C#设计模式(适配器模式)众所周知,在中国通用的电压时220V,而美国电压则是110V,如果有经常在美国和中国之间跑的IT 人,而其笔记本都是随身携带的,那么它的笔记本的电压问题如何解决呢?(因为在美国和中国电压不同,所以一般的电器会不通用的)而适配器在这个问题上体现得淋漓尽致。
现在的笔记本都有一个电源适配器,而正是这个电源适配器来解决上面提到的适配器问题,比如,一款索尼笔记本,其输入电流为交流100V~240V,而输出则是统一的直流19.5V,在电源适配器的一端输入交流电流,然后通过电源适配器把电源变成需要的电压,也就是适配器的作用是使得一个东西适合另外一个东西。
下面来给出适配器模式的定义:适配器模式将一个接口转换成另外一个接口,以符合客户的期望。
主要用于以下情况:1.比如现在有一个旧的软件系统,其中有一个组件已经过时了,更新需用到第三方的组件(新组件),但是旧组件的接口和新组件的接口不同,同时,您又不想去改变现有的代码,此时可使用适配器模式。
您可以通过适配器模式将新组件的一些接口转换成为你所期望的接口,这样就无需要改变原来的代码,轻松实现从旧组件更新到新组件了。
2.比如一个WINE 的工具,它允许用户在Linux 环境下运行Windows 程序,这也是一种适配器。
可以这样来理解适配器模式的,适配器模式就是将一些对象包装起来,然后让它们的接口看起来是别的接口。
还有需要提及的是,适配器模式分为类适配器模式和对象适配器模式,但是类适配器模式要以多重继承为前提,而C# 不支持多重继承,所以在这里只介绍对象适配器,如果有对类适配器模式感兴趣的话,可以使用C++ 来实现一下。
对象适配器的结构图举个例子说明一下:被适配的类A daptee(A daptee 中的接口由于不能被客户端识别,所以需要被适配):可以看出,上面的适配器就是一个中介人,它把本来客户端的请求转换成了A daptee 所代表的接口所能理解的请求。
Java设计模式之《适配器模式》及应⽤场景出处地址 适配器就是⼀种适配中间件,它存在于不匹配的⼆者之间,⽤于连接⼆者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。
适配器模式有两种:类适配器、对象适配器、接⼝适配器 前⼆者在实现上有些许区别,作⽤⼀样,第三个接⼝适配器差别较⼤。
1、类适配器模式: 原理:通过继承来实现适配器功能。
当我们要访问的接⼝A中没有我们想要的⽅法,却在另⼀个接⼝B中发现了合适的⽅法,我们⼜不能改变访问接⼝A,在这种情况下,我们可以定义⼀个适配器p来进⾏中转,这个适配器p要实现我们访问的接⼝A,这样我们就能继续访问当前接⼝A中的⽅法(虽然它⽬前不是我们的菜),然后再继承接⼝B的实现类BB,这样我们可以在适配器P中访问接⼝B的⽅法了,这时我们在适配器P中的接⼝A⽅法中直接引⽤BB中的合适⽅法,这样就完成了⼀个简单的类适配器。
详见下⽅实例:我们以ps2与usb的转接为例ps2接⼝:Ps21 public interface Ps2 {2 void isPs2();3 }USB接⼝:Usb1 public interface Usb {2 void isUsb();3 }USB接⼝实现类:Usber1 public class Usber implements Usb {23 @Override4 public void isUsb() {5 System.out.println("USB⼝");6 }78 }适配器:Adapter1 public class Adapter extends Usber implements Ps2 {23 @Override4 public void isPs2() {5 isUsb();6 }78 }测试⽅法:Clienter1 public class Clienter {23 public static void main(String[] args) {4 Ps2 p = new Adapter();5 p.isPs2();6 }78 }显⽰结果:USB⼝实例讲解: 我⼿中有个ps2插头的设备,但是主机上只有usb插头的插⼝,怎么办呢?弄个转换器,将ps2插头转换成为USB插头就可以使⽤了。
设计模式之适配器模式案例详解基本介绍适配器模式将某个类的接⼝转换成客户端期望的另⼀个接⼝表⽰,主要⽬的是兼容性,让原本因接⼝不匹配不能⼀起⼯作的两个类可以协同⼯作。
适配器模式属于结构性模式,主要分为三类:类适配器模式、对象适配器模式、接⼝适配器模式。
类适配器模式什么是类适配器模式类适配器模式介绍:Adapter类,通过集成src类,实现dst类接⼝,完成src>dst的适配。
应⽤实例案例以⽣活中充电器的例⼦来讲解适配器,充电器本⾝相当于Adapter,220V交流电相当于src(即被适配者),我们的dst(即⽬标)是5V 直流电。
思路分析代码实现1//被适配的类2public class Voltage220V {3//输出220V的电压4public int output220V(){5int s rc=220;6S ystem.out.println("电源电压="+src+"伏");7return s rc;8}9}1//适配接⼝2public interface IVoltage5V {3int output5V();4}1public class VoltageAdapter extends Voltage220V implements IVoltage5V {2@Override3public int output5V(){4int s rcV =o utput220V();//获取220V的电压5int d stV =s rcV /44;//进⾏处理6return d stV;7}8}1public class Phone {2//充电3public void charging(IVoltage5V i Voltage5V){4if(iVoltage5V.output5V()==5){5S ystem.out.println("现在电压为5V,可以充电");6}else if(iVoltage5V.output5V()>5){7S ystem.out.println("现在电压⼤于5V,可以充电");8}9}10}1public class Client {2public static void main(String[] a rgs){3P hone p hone =new P hone();4p hone.charging(new V oltageAdapter());5}6}类适配器模式注意事项和细节Java是单继承机制,所以类适配器需要继承src类这⼀点算是⼀个缺点,因为这要求dst必须是接⼝,有⼀定局限性。
[原创]适配器模式(java版)什么是适配器模式?将⼀个类的接⼝转换成客户希望的另外⼀个接⼝,使原来由于不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。
什么场景下使⽤适配器模式?⽐如我们要复⽤早期的⼀些代码或者第三⽅库或者别⼈维护的代码的时候,但这些代码提供的接⼝和我们此时的使⽤环境不兼容,我们⼜不能去修改这些代码,于是就需要使⽤适配器去适配这些接⼝以⽅便使⽤。
使⽤⼀个已经存在的类,但如果它的⽅法和你的要求不相同时,就应该考虑⽤适配器模式。
注意:适配器模式在详细设计阶段(开发阶段)不要考虑它,这个是维护或者扩展已有功能系统才需要考虑使⽤的。
适配器模式主要包括两种类型:类适配器模式和对象适配器模式。
类适配器模式:类适配器是通过继承被适配接⼝的实现类和实现⽬标接⼝来创建的。
这样可以把该适配器作为⼀个⽬标接⼝的实现类,⼜可以在该实现类中调⽤被适配接⼝的⽅法。
从⽽达到适配的⽬的。
例⼦://⽬标⾓⾊public interface Target{public void request();}//源⾓⾊public class Adaptee{//原有的业务public void doSomething(){System.out.println("a b c ");}}//适配器⾓⾊public class Adapter extends Adaptee implements Target{public void request(){super.doSomething();}}对象适配器模式:通过在适配器类的内部包装⼀个被适配的类对象,从⽽把源接⼝转换成⽬标接⼝,其中适配器类时⽬标类的⼦类或者实现。
例⼦://⽬标⾓⾊public interface Target{public void request();}//源⾓⾊public class Adaptee{//原有的业务public void doSomething(){System.out.println("a b c ");}}//适配器⾓⾊public class Adapter implements Target{private Adaptee adaptee = new Adaptee();public void request(){adaptee.doSomething();}}对象适配器和类适配器的区别:类适配器是类间继承,但由于java中不允许多继承,因此当需要适配多个类的时候,我们使⽤对象适配器,对象适配器是对象的合成关系或者说是类的关联关系,这是⼆者的根本区别。
Python中的适配器模式适配器模式是一种软件设计模式,用于将不兼容的接口转换为兼容的接口,从而使得不同组件之间能够互相协作的标准化交互。
在Python中,适配器模式的应用相对来说比较灵活,可以应用于各种场景中,比如将已有的类适配为某个接口,或者将两个不同的接口适配为兼容的接口等。
一、适配器模式的简介适配器模式是一种结构型设计模式,旨在将不兼容的接口转换为兼容的接口,从而满足不同组件之间的标准化交互,同时又不影响已有的系统结构。
适配器模式涉及到三个角色:适配器(Adapter)、适配者(Adaptee)和目标(Target)。
适配器是将适配者的接口转换为目标的接口的中间件,适配者是需要被适配的对象,而目标是适配器期望得到的接口。
二、适配器模式的应用场景在实际开发过程中,适配器模式的应用场景非常广泛,比如:1.将已有的类适配为某个接口通常情况下,我们会使用继承的方式来实现类的复用,但是如果需要将现有的类适配为某个接口,这种方式就不是很合适。
此时,适配器模式就可以派上用场,它能够将已有的类适配为目标接口,从而使得现有的类也能够满足新的需求,不需要对现有的类进行修改。
2.将两个不同的接口适配为兼容的接口在不同系统间进行数据交换时,往往由于数据格式不同、协议不同或者接口不同等原因,导致无法正常交互。
此时,适配器模式就可以将两个不同的接口适配为兼容的接口,从而使得这两个系统能够正常交互。
三、适配器模式的实现方法1.类适配器模式类适配器模式是一种通过多重继承的方式实现适配器模式的方法。
在类适配器模式中,适配器类继承了适配者类,并实现了目标接口,从而达到将适配者类适配为目标接口的目的。
示例代码如下:```class Adaptee:def specific_request(self):return "specific request"class Target:def request(self):return "default request"class Adapter(Target, Adaptee):def request(self):return self.specific_request()if __name__ == "__main__":adapter = Adapter()assert adapter.request() == "specific request" ```2.对象适配器模式对象适配器模式是一种通过组合的方式实现适配器模式的方法。
设计模式之适配器模式模式动机
适配器模式的作用就是解决两个软件实体间接口不兼容状况.
通常状况下,用法者可以通过目标类的接口拜访它所提供的服务。
开头时候没有什么问题, 但是一但后续别的接口(如第三方接口)有变动或者后续扩展需求, 此时用法原有接口已经不行以提供服务, 那么我们就需要把现有接口转化为用法者需要的接口.适配器模式就是用来完成这样的转化.
在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类。
模式定义
适配器模式(Adapter Pattern) :将一个接口转换成用法者希翼的
第1页共17页。