设计模式Adapter
- 格式:docx
- 大小:150.10 KB
- 文档页数:19
软件开发中的设计模式有哪些在软件开发的领域中,设计模式就像是一套经过实践检验的解决方案,帮助开发者更高效、更优雅地解决常见的问题。
它们是软件开发中的宝贵经验总结,为构建可维护、可扩展和灵活的软件系统提供了有力的支持。
接下来,让我们一起探索一下软件开发中常见的设计模式。
一、创建型设计模式1、单例模式(Singleton Pattern)单例模式确保一个类只有一个实例存在,并提供一个全局访问点来获取该实例。
这在某些情况下非常有用,比如一个系统中只需要一个数据库连接池或者一个日志记录器。
想象一下,如果多个线程同时创建多个数据库连接池实例,不仅会浪费资源,还可能导致混乱。
通过单例模式,我们可以保证只有一个实例存在,有效地管理资源。
2、工厂模式(Factory Pattern)当我们需要创建对象,但又不想让客户端直接与具体的类进行交互时,工厂模式就派上用场了。
它定义了一个用于创建对象的接口,让子类决定实例化哪一个类。
比如,在一个汽车生产厂中,有不同类型的汽车(轿车、SUV 等),我们可以通过一个工厂类根据需求来创建相应类型的汽车对象,而客户端只需要向工厂请求即可,无需关心具体的创建细节。
3、抽象工厂模式(Abstract Factory Pattern)抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
例如,一个家具厂可能生产多种风格的家具(现代风格、古典风格),每种风格都有配套的椅子、桌子和沙发。
通过抽象工厂模式,我们可以根据用户选择的风格创建一整套家具,保证了风格的一致性和协调性。
4、建造者模式(Builder Pattern)建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如构建一个电脑配置,我们可以有不同的 CPU、内存、硬盘等组件选择,通过建造者模式,可以清晰地定义构建的步骤和顺序,同时能够灵活地组合不同的组件来创建出各种不同配置的电脑。
adapter用法Adapter是一种常用的设计模式,用于将一个类的接口转换成另一个类所期望的接口。
它可以解决两个不兼容接口之间的兼容性问题。
在软件开发中,Adapter模式可以用于多种场景,下面我将从多个角度来介绍Adapter的用法。
1. 结构和工作原理:Adapter模式由三个主要组件组成,目标接口(Target)、适配器(Adapter)和被适配者(Adaptee)。
目标接口定义了客户端所期望的接口,适配器实现了目标接口,并持有一个被适配者的引用,通过适配器将客户端的请求转发给被适配者。
2. 类适配器和对象适配器:Adapter模式有两种常见的实现方式,类适配器和对象适配器。
类适配器使用继承来实现适配器,它继承了目标接口和被适配者,并在适配器中实现目标接口的方法。
对象适配器使用组合来实现适配器,它持有一个被适配者的引用,并在适配器中实现目标接口的方法。
3. 应用场景:Adapter模式可以应用于以下场景:在现有系统中使用第三方库或组件,但其接口与系统的接口不兼容时,可以使用适配器来进行接口转换。
在系统演化过程中,为了避免对现有代码的修改,可以使用适配器来兼容旧接口和新接口。
在系统需要与多个不同接口的类进行交互时,可以使用适配器统一接口,提供一致的访问方式。
4. 优点和缺点:Adapter模式的优点包括:提供了灵活的接口转换,使得原本不兼容的类可以协同工作。
可以使系统具有良好的扩展性和维护性,减少对现有代码的修改。
然而,Adapter模式也存在一些缺点:增加了系统的复杂性,引入了额外的类和对象。
在适配器过多的情况下,可能导致系统结构混乱。
总结:Adapter模式是一种常用的设计模式,用于解决不兼容接口之间的兼容性问题。
它可以通过类适配器或对象适配器的方式实现。
Adapter模式在软件开发中应用广泛,可以用于整合第三方库、兼容旧接口、统一多个接口等场景。
它具有灵活性和扩展性的优点,但也可能增加系统的复杂性。
C++设计模式之Adapter一、功能将一个类的接口转换成客户希望的另外一个接口,解决两个已有接口之间不匹配的问题。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
二、结构图(1)class adapter(2)object adapter三、实现和其他很多模式一样,学习设计模式的重点是学习每种模式的思想,而不应拘泥于它的某种具体结构图和实现。
因为模式是灵活的,其实现可以是千变万化的,只是所谓万变不离其宗。
在STL中大量运用了Adapter模式,象function adapter、iterator adpter,它们与这里说的adapter结构并不一样,但思想是一样的。
具体的介绍可到侯捷网站上找相关文章,他讲得非常好。
四、示例代码(1)class adapternamespace DesignPattern_Adapter{// class Adapteeclass Adaptee{public:v oi d SpecialRequest() {}} ;// class Targetclass Target{public:v irtual v oid R equest() = 0 ;} ;// class Adapterclass Adapter : public Target, pri v ate Adaptee{public:v irtual v oid R equest() { SpecialRequest() ; }} ;}客户端代码:{using names pac e DesignPattern_Adapter ;Target *p = new Adapter() ;p->Request() ; //实际上调用的是Adaptee::SpecialRequest() }(2)object adapter namespace D esignPattern_Adapter{// class Adapteeclass Adaptee{public:v oi d SpecialRequest() {}} ;// class Targetclass Target{public:v irtual v oid R equest() = 0 ;} ;// class Adapterclass Adapter : public Target{public:v irtual v oid R equest() { _adaptee.SpecialRequest() ; }priv ate:Adaptee _adaptee ;} ;}客户端代码:{using names pac e DesignPattern_Adapter ;Target *p = new Adapter() ;p->Request() ; //实际上调用的是Adaptee::SpecialRequest()}六、实例(1)STL中的Class AdapterSTL中的Adapter Class包括:a.stac k(对应的adaptee是deque)。
安卓常⽤的6种设计模式总结最近看到两篇博客,觉得很不错,记录⼀下由于项⽬变更的频繁性,作为⼀名程序员,我们需要掌握设计模式的必要性,就不⾔⽽喻~~,下⾯就是⼀些我⾃⼰学习的设计模式总结。
接下来,主要是针对⼏个⽐较常⽤模式进⾏讲解,主要是以下⼏种:观察者模式适配器模式代理模式⼯⼚模式单例模式命令模式1.观察者模式(Observer Pattern)释义:观察者模式定义了⼀种⼀对多的依赖关系,让多个观察者对象同时监听某⼀个主题对象,这个主题对象在状态上发⽣变化时,会通知所有观察者对象,使他们能够⾃动更新⾃⼰。
故事理解:观察者想知道公司所有MM的情况,只要加⼊公司的MM情报邮件组就⾏了,tom负责搜集情报,当发现新情报时,不⽤⼀个⼀个通知我们,直接发布给邮件组,我们作为订阅者(观察者)就可以及时收到情报啦。
常见实例:1.BaseAdapter.registerDataSetObserver和BaseAdapter.unregisterDataSetObserver两⽅法来向BaseAdater注册、注销⼀个DataSetObserver ; 2.使⽤ContentObserver去监听数据库变化。
适⽤场景:1.当对⼀个对象的改变需要同时改变其他对象,⽽不知道具体有多少对象有待改变;2.当⼀个对象必须通知其它对象,⽽它⼜不能假定其它对象是谁.观察者模式主要有观察者和被观察者2个对象,在该模式中,Observable表⽰被观察者,这个对象是⼀个抽象类,只能被继承。
Observer表⽰观察者,他是⼀个接⼝,所以观察者可以有多个,实现了该接⼝的类都是属于观察者。
这是⽹上⼀个⽣动细致的demo:被观察者:public class MyPerson extends Observable {private int age;private String name;private String sax;public int getAge() {return age;}public void setAge(int age) {this.age = age;setChanged();notifyObservers();}public String getName() {return name;}public void setName(String name) { = name;setChanged();notifyObservers();}public String getSax() {return sax;}public void setSax(String sax) {this.sax = sax;}@Overridepublic String toString() {return "MyPerson [age=" + age + ", name=" + name + ", sax=" + sax + "]";}}MyPerson是被观察者,类中调⽤了setChange()以及notifyObservers()两个⽅法,前者是告知数据改变,后者是发送信号通知观察者。
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.在适配器类中实现目标接口的方法,将调用具体方法的任务委托给源接口的方法。
1、适配器模式adapter#include <iostream>using namespace std;class Deque{public:void push_back(int x) { cout<<"Deque push_back"<<endl; } void push_front(int x) { cout<<"Deque push_front"<<endl; } void pop_back() { cout<<"Deque pop_back"<<endl; }void pop_front() { cout<<"Deque pop_front"<<endl; }};//顺序容器class Sequence{public:virtual void push(int x) = 0;virtual void pop() = 0;};//栈class Stack: public Sequence{public:void push(int x) { deque.push_back(x); }void pop() { deque.pop_back(); }private:Deque deque; //双端队列};//队列class Queue: public Sequence{public:void push(int x) { deque.push_back(x); }void pop() { deque.pop_front(); }private:Deque deque; //双端队列};int main(){Sequence *s1 = new Stack();Sequence *s2 = new Queue();s1->push(1); s1->pop();s2->push(1); s2->pop();delete s1; delete s2;return 0;}2、建造者模式building#include <iostream>using namespace std;class Builder{public:virtual void BuildHead() {}virtual void BuildBody() {}virtual void BuildLeftArm(){}virtual void BuildRightArm() {}virtual void BuildLeftLeg() {}virtual void BuildRightLeg() {}};//构造瘦人class ThinBuilder : public Builder{public:void BuildHead() { cout<<"build thin body"<<endl; }void BuildBody() { cout<<"build thin head"<<endl; }void BuildLeftArm() { cout<<"build thin leftarm"<<endl; }void BuildRightArm() { cout<<"build thin rightarm"<<endl; } void BuildLeftLeg() { cout<<"build thin leftleg"<<endl; }void BuildRightLeg() { cout<<"build thin rightleg"<<endl; } };//构造胖人class FatBuilder : public Builder{public:void BuildHead() { cout<<"build fat body"<<endl; }void BuildBody() { cout<<"build fat head"<<endl; }void BuildLeftArm() { cout<<"build fat leftarm"<<endl; }void BuildRightArm() { cout<<"build fat rightarm"<<endl; } void BuildLeftLeg() { cout<<"build fat leftleg"<<endl; }void BuildRightLeg() { cout<<"build fat rightleg"<<endl; } };//构造的指挥官class Director{private:Builder *m_pBuilder;public:Director(Builder *builder) { m_pBuilder = builder; }void Create(){m_pBuilder->BuildHead();m_pBuilder->BuildBody();m_pBuilder->BuildLeftArm();m_pBuilder->BuildRightArm();m_pBuilder->BuildLeftLeg();m_pBuilder->BuildRightLeg();}};int main(){FatBuilder thin;Director director(&thin);director.Create();return 0;}3、策略模式#include <iostream>using namespace std;class COperation{ public:int m_nFirst;int m_nSecond;virtual double GetResult(){double dResult=0;return dResult;}};//策略具体类—加法类class AddOperation : public COperation {public:AddOperation(int a,int b){m_nFirst=a;m_nSecond=b;}virtual double GetResult(){return m_nFirst+m_nSecond;}};class SubstrOperation : public COperation{public:SubstrOperation(int a,int b){m_nFirst=a;m_nSecond=b;}virtual double GetResult(){return m_nFirst-m_nSecond;}};class Context{private:COperation* op;public:Context(COperation* temp){op=temp;}double GetResult(){return op->GetResult();}};//客户端int main(){int a,b;char c;cin >> a >> b;cout<<"请输入运算符";cin>>c;switch(c){case '+':{Context *context1=new Context(new AddOperation(a,b));cout<< context1->GetResult() << endl;break;}case '-':{Context *context2=new Context(new SubstrOperation(a,b));cout<< context2->GetResult() << endl;break;}}return 0;}4、抽象模式#include <iostream>class Button{public:virtual void paint() = 0;};class WinButton : public Button{public:void paint (){std::cout << " Window Button \n";}};class MacButton : public Button{public:void paint (){std::cout << " Mac Button \n";}};class ScrollBar{public:virtual void paint() = 0;};class WinScrollBar : public ScrollBar{public:void paint (){std::cout << " Window ScrollBar \n";}};class MacScrollBar : public ScrollBar { public:void paint (){std::cout << " Mac ScrollBar \n";}};class GUIFactory{public:virtual Button* createButton () = 0;virtual ScrollBar* createScrollBar () = 0; };class WinFactory : public GUIFactory{public:Button* createButton (){return new WinButton;}ScrollBar* createScrollBar (){return new WinScrollBar;}};class MacFactory : public GUIFactory{public:Button* createButton (){return new MacButton;}ScrollBar* createScrollBar (){return new MacScrollBar;}};int main(){GUIFactory* guiFactory;Button *btn;ScrollBar *sb;guiFactory = new MacFactory;btn = guiFactory->createButton();btn -> paint();sb = guiFactory->createScrollBar();sb -> paint();guiFactory = new WinFactory;btn = guiFactory->createButton();btn -> paint();sb = guiFactory->createScrollBar();sb -> paint();return 0;}5、代理模式#include <iostream>#include <string>using namespace std;class BigImage{public:BigImage(string name): m_imageName(name) {} virtual ~BigImage() {}virtual void Show() {}protected:string m_imageName;};//真实类class RealBigImage: public BigImage{public:RealBigImage(string name):BigImage(name) {}~RealBigImage() {}void Show(){cout<<"Show big image : "<<m_imageName<<endl;}};//代理class Proxy: public BigImage{private:RealBigImage *m_bigImage;public:Proxy(string name):BigImage(name),m_bigImage(0){}~Proxy(){delete m_bigImage;}void Show(){if(m_bigImage == NULL){cout<<"please wait ..."<<endl;m_bigImage = new RealBigImage(m_imageName); //代理创建真实对象}m_bigImage->Show();}};int main(){BigImage *image = new Proxy("SomeBigPic.jpg"); //使用代理image->Show(); //代理的操作delete image;return 0;}6、非享元模式#include <iostream>#include <vector>#include <string>using namespace std;//棋子颜色enum PieceColor {BLACK, WHITE};//棋子位置struct PiecePos{int x;int y;PiecePos(int a, int b): x(a), y(b) {}};//棋子定义class Piece{protected:PieceColor m_color; //颜色PiecePos m_pos; //位置public:Piece(PieceColor color, PiecePos pos): m_color(color), m_pos(pos) {} ~Piece() {}virtual void Draw() {}};class BlackPiece: public Piece{public:BlackPiece(PieceColor color, PiecePos pos): Piece(color, pos) {}~BlackPiece() {}void Draw() { cout<<"绘制一颗黑棋"<<endl;}};class WhitePiece: public Piece{public:WhitePiece(PieceColor color, PiecePos pos): Piece(color, pos) {}~WhitePiece() {}void Draw() { cout<<"绘制一颗白棋"<<endl;}};class PieceBoard{private:vector<Piece*> m_vecPiece; //棋盘上已有的棋子string m_blackName; //黑方名称string m_whiteName; //白方名称public:PieceBoard(string black, string white): m_blackName(black), m_whiteName(white){} ~PieceBoard() { Clear(); }void SetPiece(PieceColor color, PiecePos pos) //一步棋,在棋盘上放一颗棋子{Piece * piece = NULL;if(color == BLACK) //黑方下的{piece = new BlackPiece(color, pos); //获取一颗黑棋cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";piece->Draw(); //在棋盘上绘制出棋子}else{piece = new WhitePiece(color, pos);cout << m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";piece->Draw();}m_vecPiece.push_back(piece); //加入容器中}void Clear() //释放内存{int size = m_vecPiece.size();for(int i = 0; i < size; i++)delete m_vecPiece[i];}};int main(){PieceBoard pieceBoard("A","B");pieceBoard.SetPiece(BLACK, PiecePos(4, 4));pieceBoard.SetPiece(WHITE, PiecePos(4, 16));pieceBoard.SetPiece(BLACK, PiecePos(16, 4));pieceBoard.SetPiece(WHITE, PiecePos(16, 16));return 0;}7、工厂方法#include <iostream>using namespace std;class Button{public:virtual void paint() = 0;};class OSXButton: public Button{public:void paint(){cout << "OSX button \n";}};class WindowsButton: public Button {public:void paint(){cout << "Windows button \n";}};class GUIFactory{public:virtual Button *createButton() = 0; };class Factory1: public GUIFactory{public:Button *createButton(){return new WindowsButton;}};class Factory2: public GUIFactory{public:Button *createButton(){return new OSXButton;}};int main(){GUIFactory* guiFactory1,* guiFactory2;Button *btn1,*btn2;guiFactory1 = new Factory1;btn1 = guiFactory1->createButton();btn1 -> paint();guiFactory2 = new Factory2;btn2 = guiFactory2->createButton();btn2 -> paint();return 0;}8、观察者模式#include <iostream>#include <list>#include <string>using namespace std;class Observer{public:Observer() {}virtual ~Observer() {}virtual void Update() {}};//博客class Blog{public:Blog() {}virtual ~Blog() {}void Attach(Observer *observer) { m_observers.push_back(observer); } //添加观察者void Remove(Observer *observer) { m_observers.remove(observer); } //移除观察者void Notify() //通知观察者{list<Observer*>::iterator iter = m_observers.begin();for(; iter != m_observers.end(); iter++)(*iter)->Update();}virtual void SetStatus(string s) { m_status = s; } //设置状态virtual string GetStatus() { return m_status; } //获得状态private:list<Observer* > m_observers; //观察者链表protected:string m_status; //状态};//具体博客类class BlogCSDN : public Blog{private:string m_name; //博主名称public:BlogCSDN(string name): m_name(name) {}~BlogCSDN() {}void SetStatus(string s) { m_status = "CSDN通知: " + m_name + s; } //具体设置状态信息string GetStatus() { return m_status; }};//具体观察者class ObserverBlog : public Observer{private:string m_name; //观察者名称Blog *m_blog; //观察的博客,当然以链表形式更好,就可以观察多个博客public:ObserverBlog(string name,Blog *blog): m_name(name), m_blog(blog) {}~ObserverBlog() {}void Update() //获得更新状态{string status = m_blog->GetStatus();cout<<m_name<<"-------"<<status<<endl;}};//测试案例int main(){Blog *blog = new BlogCSDN("wuzhekai1985");Observer *observer1 = new ObserverBlog("tutupig", blog);blog->Attach(observer1);blog->SetStatus("发表设计模式C++实现(15)——观察者模式");blog->Notify();delete blog; delete observer1;return 0;}9、命令模式#include <iostream>#include <vector>using namespace std;class Command{public:virtual void execute() = 0;};class NoCommand : public Command{public:void execute() {};};class Light{public:Light(string location);void on();void off();private:string m_sLocation;};class LightOffCommand : public Command{public:LightOffCommand(string location):m_Light(location) {}void execute();private:Light m_Light;};class LightOnCommand : public Command{public:LightOnCommand(string location):m_Light(location) {}void execute();private:Light m_Light;};class Stereo{public:Stereo(string location);void on();void off();void setCD();void setDVD();void setRadio();void setVolume(int volume);private:string m_sLocation;};class StereoOnWithCDCommand : public Command{ public:StereoOnWithCDCommand(string location):m_Stereo(location) {}void execute();private:Stereo m_Stereo;};class StereoOffCommand : public Command{ public:StereoOffCommand(string location):m_Stereo(location) {}void execute();private:Stereo m_Stereo;};class RemoteControl{ public:RemoteControl();~RemoteControl();void setCommand(int slot, Command* pOnCommand, Command* pOffCommand);void onButtonWasPushed(int slot);void offButtonWasPushed(int slot);private:vector<Command*> m_OnCommands;vector<Command*> m_OffCommands;};Light::Light(string location){m_sLocation = location;}void Light::on(){printf("%s light is on\n",m_sLocation.c_str());}void Light::off(){printf("%s light is off\n",m_sLocation.c_str());}void LightOffCommand::execute(){m_Light.off();}void LightOnCommand::execute(){m_Light.on();}Stereo::Stereo(string location){m_sLocation = location;}void Stereo::on(){printf("%s stereo is on\n",m_sLocation.c_str());}void Stereo::off(){ printf("%s stereo is off\n",m_sLocation.c_str());}void Stereo::setCD(){printf("%s stereo is set for CD input\n",m_sLocation.c_str());}void Stereo::setDVD(){printf("%s stereo is set for DVD input\n",m_sLocation.c_str());}void Stereo::setRadio(){printf("%s stereo is set for Radio\n",m_sLocation.c_str());}void Stereo::setVolume(int volume){printf("%s Stereo volume set to %d\n",m_sLocation.c_str(),volume); }void StereoOnWithCDCommand::execute(){m_Stereo.on();m_Stereo.setCD();m_Stereo.setVolume(11);}void StereoOffCommand::execute(){m_Stereo.off();}RemoteControl::RemoteControl(){for (int i = 0; i < 7; i++){Command* noCommandOn = new NoCommand();m_OnCommands.push_back(noCommandOn);Command* noCommandOff = new NoCommand();m_OffCommands.push_back(noCommandOff);}}RemoteControl::~RemoteControl(){for (int i = 0; i < 7; i++){delete m_OnCommands.at(i);delete m_OffCommands.at(i);}m_OnCommands.clear();m_OffCommands.clear();}void RemoteControl::setCommand(int slot, Command* pOnCommand, Command* pOffCommand){delete m_OnCommands.at(slot);m_OnCommands.at(slot) = pOnCommand;delete m_OffCommands.at(slot);m_OffCommands.at(slot) = pOffCommand;}void RemoteControl::onButtonWasPushed(int slot){m_OnCommands.at(slot)->execute();}void RemoteControl::offButtonWasPushed(int slot){m_OffCommands.at(slot)->execute();}int main(){RemoteControl remoteControl;LightOffCommand* pLivingRoomLightOff = new LightOffCommand("Living Room");LightOffCommand* pKitchenLightOff = new LightOffCommand("Kitchen");LightOnCommand* pLivingRoomLightOn = new LightOnCommand("Living Room");LightOnCommand* pKitchenLightOn = new LightOnCommand("Kitchen");StereoOnWithCDCommand* pStereoOnWithCD = new StereoOnWithCDCommand("Living Room");StereoOffCommand* pStereoOff = new StereoOffCommand("Living Room");remoteControl.setCommand(0,pLivingRoomLightOn,pLivingRoomLightOff);remoteControl.setCommand(1,pKitchenLightOn,pKitchenLightOff);remoteControl.setCommand(2,pStereoOnWithCD,pStereoOff);remoteControl.onButtonWasPushed(0);remoteControl.offButtonWasPushed(0);remoteControl.onButtonWasPushed(1);remoteControl.offButtonWasPushed(1);remoteControl.onButtonWasPushed(2);remoteControl.offButtonWasPushed(2);return 0;}10、桥接模式#include <iostream>using namespace std;class OS{public:virtual void InstallOS_Imp() {}};class WindowOS: public OS{public:void InstallOS_Imp() { cout<<"安装Window操作系统"<<endl; }};class LinuxOS: public OS{public:void InstallOS_Imp() { cout<<"安装Linux操作系统"<<endl; }};class UnixOS: public OS{public:void InstallOS_Imp() { cout<<"安装Unix操作系统"<<endl; } };//计算机class Computer{public:virtual void InstallOS(OS *os) {}};class DellComputer: public Computer{public:void InstallOS(OS *os) { os->InstallOS_Imp(); }};class AppleComputer: public Computer{public:void InstallOS(OS *os) { os->InstallOS_Imp(); }};class HPComputer: public Computer{public:void InstallOS(OS *os) { os->InstallOS_Imp(); }};int main(){OS *os1 = new WindowOS();OS *os2 = new LinuxOS();Computer *computer1 = new AppleComputer();computer1->InstallOS(os1);computer1->InstallOS(os2);}11、外观模式#include <iostream>using namespace std;class Scanner{public:void Scan() { cout<<"词法分析"<<endl; }};class Parser{public:void Parse() { cout<<"语法分析"<<endl; }};class GenMidCode{public:void GenCode() { cout<<"产生中间代码"<<endl; } };class GenMachineCode{public:void GenCode() { cout<<"产生机器码"<<endl;} };//高层接口class Compiler{public:void Run(){Scanner scanner;Parser parser;GenMidCode genMidCode;GenMachineCode genMacCode;scanner.Scan();parser.Parse();genMidCode.GenCode();genMacCode.GenCode();}};int main(){Compiler compiler;compiler.Run();return 0;}12、享元模式#include <vector>#include <iostream>#include <conio.h>#include <string>using namespace std;class Flyweight{public:Flyweight(){}virtual ~Flyweight(){}virtual void Operation(const string extrinsicState) = 0;//接受客户的外部状态};class ConcreteFlyweight : public Flyweight{public:char _intrinsicState;ConcreteFlyweight(char intrinsicState){this->_intrinsicState = intrinsicState;cout<<intrinsicState<<" is created!"<<endl;}~ConcreteFlyweight(){}char GetIntrinsicState(){return this->_intrinsicState;}//返回内部状态变量void Operation(const string extrinsicState){if (!extrinsicState.empty()){cout<<"<"<<extrinsicState<<"> "<<_intrinsicState<<endl;}elsecout<<"<Normal> "<<_intrinsicState<<endl;}};class FlyweightFactory{public://作为对象池,存贮共享的Flyweight对象,也可用hash表等其它结构vector <ConcreteFlyweight *>_flyVector;FlyweightFactory(){}~FlyweightFactory(){}Flyweight * GetFlyweight(char key){//引入迭代器实现按顺序访问池中的各Flyweight对象vector <ConcreteFlyweight *>:: iterator it = _flyVector.begin();ConcreteFlyweight * flyTemp;if (_flyVector.size() == 0)//当容器内无任何对象时,先push一个对象{flyTemp = new ConcreteFlyweight(key);_flyVector.push_back(flyTemp);return flyTemp;}for (; it != _flyVector.end(); it++)//遍历对象{if ((*it)->GetIntrinsicState() == key)//若存在{cout<<key<<" is already existed.."<<endl;return *it;}flyTemp = new ConcreteFlyweight(key);_flyVector.push_back(flyTemp);return flyTemp;}}};int main(){FlyweightFactory * fac1 = new FlyweightFactory();Flyweight *fly1 = fac1->GetFlyweight('a');Flyweight *fly2 = fac1->GetFlyweight('b');Flyweight *fly3 = fac1->GetFlyweight('a');fly1->Operation("BigSize");fly2->Operation("");fly3->Operation("Rotated");getch();/*等待按键继续*/return 0;}13、修饰模式#include <iostream>#include <string>using namespace std;class Person{public:Person(){}Person(string str):name(str){}string GetName(){return name;}virtual void Show(){cout << "装扮的" << GetName() << endl;}private:string name;};// 装饰类class PStyle : public Person{public:void Decorator(Person *conponent){this->person = conponent;}void Show(){if (person != NULL){person->Show();}}protected:Person *person; // 记住,动态的条用虚函数必须通过对象的指针或者引用};// 具体装饰class TShirt : public PStyle{public:void Show(){cout << " T恤";PStyle::Show();}};// 具体装饰class Throuse : public PStyle{public:void Show(){cout << " c长裤子";PStyle::Show();}};class Sweter : public PStyle{public:void Show(){cout << " 大毛衣";PStyle::Show();}};void main(){Person xiaocai("小菜");TShirt tx;Throuse th;Sweter sw;tx.Decorator(&xiaocai);th.Decorator(&tx);sw.Decorator(&th);sw.Show();}14、原型模式#include <iostream>using namespace std;class Resume{protected:char *name;public:Resume() {}virtual ~Resume() {}virtual Resume* Clone(){ return NULL; }virtual void Set(char *n) {}virtual void Show() {}};class ResumeA : public Resume{public:ResumeA(const char *str); //构造函数ResumeA(const ResumeA &r); //拷贝构造函数~ResumeA(); //析构函数Resume* Clone(); //克隆,关键所在void Show(); //显示内容};ResumeA::ResumeA(const char *str){if(str == NULL) {name = new char[1];name[0] = '\0';}else {name = new char[strlen(str)+1];strcpy(name, str);}}ResumeA::~ResumeA() { delete [] name;} ResumeA::ResumeA(const ResumeA &r) {name = new char[strlen()+1];strcpy(name, );}Resume* ResumeA::Clone() {return new ResumeA(*this);}void ResumeA::Show() {cout<<"ResumeA name : "<<name<<endl;}int main(){Resume *r1 = new ResumeA("A");// Resume *r2 = new ResumeB("B");Resume *r3 = r1->Clone();// Resume *r4 = r2->Clone();r1->Show();//r2->Show();//删除r1,r2delete r1;//delete r2;r1 = NULL;// r2 = NULL;//深拷贝所以对r3,r4无影响r3->Show();//r4->Show();delete r3;//delete r4;r3 = NULL;// r4 = NULL;return 0;}15、职责连模式#include <iostream>#include <string>using namespace std;class Manager{protected:Manager *m_manager;string m_name;public:Manager(Manager *manager, string name):m_manager(manager), m_name(name){}virtual void DealWithRequest(string name, int num) {}};//经理class CommonManager: public Manager{public:CommonManager(Manager *manager, string name):Manager(manager,name) {}void DealWithRequest(string name, int num){if(num < 500) //经理职权之内{cout<<"经理"<<m_name<<"批准"<<name<<"加薪"<<num<<"元"<<endl<<endl;}elsecout<<"经理"<<m_name<<"无法处理,交由总监处理"<<endl;m_manager->DealWithRequest(name, num);}}};//总监class Majordomo: public Manager{public:Majordomo(Manager *manager, string name):Manager(manager,name) {}void DealWithRequest(string name, int num){if(num < 1000) //总监职权之内{cout<<"总监"<<m_name<<"批准"<<name<<"加薪"<<num<<"元"<<endl<<endl;}else{cout<<"总监"<<m_name<<"无法处理,交由总经理处理"<<endl;m_manager->DealWithRequest(name, num);}}};//总经理class GeneralManager: public Manager{public:GeneralManager(Manager *manager, string name):Manager(manager,name) {}void DealWithRequest(string name, int num) //总经理可以处理所有请求{cout<<"总经理"<<m_name<<"批准"<<name<<"加薪"<<num<<"元"<<endl<<endl;}};int main(){Manager *general = new GeneralManager(NULL, "A"); //设置上级,总经理没有上级Manager *majordomo = new Majordomo(general, "B"); //设置上级Manager *common = new CommonManager(majordomo, "C"); //设置上级common->DealWithRequest("D",300); //员工D要求加薪common->DealWithRequest("E", 600);common->DealWithRequest("F", 1000);delete common; delete majordomo; delete general;}16、状态模式#include <iostream>using namespace std;/*一个状态接口,不同的状态从该接口中继承出来,想要增加新的状态时,只需从此接口中派生出新的类即可,适合于当判断较多(多个状态切换频繁)的场合这里引入一个程序员写工程程序的例子,程序员在一天的不同时间会处于不同的状态如果程序写不完还得加班,即程序员的状态会随着时间发生改变*/class Work;/*状态接口State*/class State{public:virtual void WriteProgram(Work *w) = 0;//写程序的行为(与Work相关的行为)};//工作类class Work{private:State *current;//当前状态double hour;bool taskFinish;public:Work(){taskFinish = false;}void SetTime(double hour){this->hour = hour;}double GetTime(){return this->hour;}//设置状态void SetState(State *s){current = s;}//设置工程是否完成void SetFinish(){taskFinish = true;}bool GetFinish(){return taskFinish;}void WriteProgram(){current->WriteProgram(this);}};//下班休息状态class RestState : public State{public:void WriteProgram(Work *w){cout<<"当前时间:"<<w->GetTime()<<"点工作完成,下班回家了"<<endl;}};//睡眠工作状态class SleepingState : public State{public:void WriteProgram(Work *w){cout<<"受不了了,"<<w->GetTime()<<"点了,先睡吧"<<endl;}};//晚上工作状态class EveningState : public State{public:void WriteProgram(Work *w){//任务完成了,可以休息了if(w->GetFinish()){w->SetState(new RestState());w->WriteProgram();}else{if(w->GetTime()<21){cout<<"当前时间:"<<w->GetTime()<<"点加班了,疲惫至极"<<endl;}else{//找过21点w->SetState(new SleepingState());w->WriteProgram();}}}};//下午工作状态class AfternoonState : public State{public:void WriteProgram(Work *w){if(w->GetTime()<17){cout<<"当前时间:"<<w->GetTime()<<"点状态还不错,继续努力"<<endl;}else{w->SetState(new EveningState());w->WriteProgram();}}};//中午工作状态class NoonState : public State{public:void WriteProgram(Work *w){if (w->GetTime()<13)cout<<"当前时间:"<<w->GetTime()<<"点饿了,午饭:犯困,午休"<<endl;else。
⼀天⼀个设计模式——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接⼝输出处来。
24种设计模式Factory Pattern(⼯⼚模式):1. 创建对象的接⼝,封装对象的创建;2. 使具体化类的⼯作延迟到⼦类中。
(维护⼀类对象)AbstractFactory Pattern(抽象⼯⼚模型):该模式将⼀组对象的创建封装到⼀个⽤于创建对象的类中。
(解决的问题:要创建⼀组或者相互依赖的对象)。
Singleton Pattern(单例模式):该模式在⾯向纯粹的⾯向对象的范式中⽤于创建唯⼀的实例,值得注意的是Singleton不能被实例化,因此将其构造函数声明为protected或private类型。
Singleton Pattern经常与Factory Pattern结合使⽤,因为Factory对象只能有⼀个。
Builder Pattern(创建者模式):将⼀个复杂的对象的构建与它的表⽰分离,使得同样的构建构成可以创建不同的表⽰。
如建筑师画图纸,⽽⼯⼈建造房屋。
Prototype Pattern(原型模式):提供⼀个通过已存在对象进⾏新对象创建的接⼝(clone)。
(浅拷贝和深拷贝)Bridge Pattern(桥梁模式):将抽象部分与实现部分分开实现,使他们都可以独⽴地变化,并使⽤组合的⽅式将多维度的抽象⽅法联系在⼀起。
⽐如咖啡分⼩杯、中杯、⼤杯以及加奶和不加奶,则抽象部分为:⼩杯、中杯、⼤杯,⾏为为:加奶和不加奶。
Adapter Pattern(适配器模式):适配就是由“源”到“⽬标”的适配,⽽当中链接两者的关系就是适配器。
它负责把“源”过度到“⽬标”。
将⼀个类的接⼝转换成客户希望的另外⼀个接⼝。
Adapter模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作。
适配器模式分为两种:①⾯向类的设计模式;②⾯向对象的设计模式。
①⾯向类的适配器:该模式使⽤继承和接⼝实现的⽅式复⽤需要适配器的类。
②⾯向对象的适配器:该模式使⽤组合的⽅式实现需要复⽤的类。
Decorator模式(装饰模式):动态地给⼀个对象添加⼀些额外的职责。
23种设计模式的经典运用介绍设计模式是解决软件设计中常见问题的可重复使用的解决方案。
本文将介绍23种经典的设计模式,并给出它们在实际开发中的应用示例。
通过学习这些设计模式,您将增加对软件设计的理解,并能够更好地解决问题。
创建型设计模式1.工厂方法模式(F a c t o r y M e t h o d)工厂方法模式通过定义一个创建对象的接口,但由子类决定实例化具体类。
这种方法可以延迟实例化过程,具有更高的灵活性和可扩展性。
应用场景:-在一个系统中,希望客户端与具体类的实例化解耦。
-希望通过增加具体类的扩展来增加系统的灵活性。
2.抽象工厂模式(A b s t r a c t F a c t o r y)抽象工厂模式提供一个接口,用于创建相关或依赖对象组。
这种模式将对象的实例化推迟到子类中,从而实现了解耦。
应用场景:-当一个系统独立于其产品的创建、组合和表示时。
-当需要一个系列的相互依赖的对象而无需指定其具体类时。
3.单例模式(S i n gl e t o n)单例模式确保一个类只有一个实例,并提供一个全局访问点。
这种模式常用于控制对资源的访问,例如数据库连接或日志文件。
应用场景:-当需要一个类的唯一实例,并且该实例需要被多个客户端共享时。
-当需要限制系统中特定类的实例数量时。
4.原型模式(P r o to t y p e)原型模式通过复制现有对象来创建新对象。
这种模式对于创建需要消耗大量资源的对象非常有用,可以通过克隆现有对象来提高性能。
应用场景:-当一个系统的某些对象的创建比较昂贵时。
-当需要避免构造函数调用,而直接通过复制现有对象来创建新对象时。
5.建造者模式(B ui l d e r)建造者模式将一个复杂对象的构建过程与其表现分离,使得相同的构建过程可以创建不同的表现。
应用场景:-当想要构建一些复杂对象时,如生成器。
-当需要创建对象的过程具有多个步骤,并且每个步骤都可以按需选择或省略时。
结构型设计模式6.适配器模式(A da p t e r)适配器模式将一个类的接口转换为客户端所期望的另一个接口。
A:<设计模式>一书中的描述"将一个类的接口转换成客户希望的另一个接口,Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作"简单的说,就是利用现有的接口去包装一个第三方的接口, 使其能象现有接口一样被程序调用,而不考虑实际使用类的差异举例:当前系统有一个绘图接口IDraw , 其中定义了display()方法,用来显示一个现在同事A,给我一套新的绘图类,但是这个类却使用了show()方法来显示一个图形我不能修改这个新接口,因为他被编译了,如果直接使用此接口,我不得不修改主程序以适应这个接口,这是一个繁重的工作但是,使用Adapter模式,可以根据IDraw接口来创建一个"适配器"class MyDraw implements IDraw{OtherDraw otherDraw = new OtherDraw();public void display(){otherDraw.show();}}现在我们可以调用MyDraw的display()方法来显示图形了,主程序不会意识到下端子系统的变化Adapter模式与Facade模式很相象他们都封装了原有的接口他们之间的区别在于Facade模式不按照某个接口设计Adapter模式必须按照某个类设计Facade一般不需要多态行为Adapter模式大多可能是为了现有的多态行为而使用的Facade是为了简化原有的复杂接口Adapter必须遵循一个已有的接口,不能简化任何东西,即使可能存在更简单的接口B:意图将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
(GoF)场景相信很多人都知道什么是显卡,也有很多人知道显卡的本名——图形适配器。
恩,是的,正好这回说说Apater模式,就拿显卡来例子来分析一下Adapter模式。
我们知道显示器(Client)是用来显示图形的,它是不能显示数据,它只能够接受来自图形发送设备Target的信号。
可是我们手头上只有CPU(Adaptee)这个产生各种描述图形的数据的数据发送器。
我们需要将这些数据让显示器进行显示,可是这两个部件却是不兼容的。
于是我们需要一个中间设备,它能够将CPU“适配”于显示器,这便是我们的显卡——图形适配器(Adapter)。
java 代码1.// 图形发送设备2.public class Target {3. /**4. * 传送图形信号5. */6. public String request() {7. return "Graphic sender";8. }9.}java 代码1.// 显示器2.public class Client {3.4. public static void main(String[] args) {5. Target target = new Targete();6. System.out.println(target.request());7. }8.}可是我们的CPU(Adaptee)只能输出0/1数据,他是个计算器,而不是图形发送设备(Target)。
java 代码1.// CPU2.public class Adaptee {3. /**4. * CPU输出的数据5. */6. public String getData() {7. return "CPU data";8. }9.}这个时候我们的显卡(Adapter)的作用便体现出来了,它负责对CPU进行适配,通过将CPU传过来的数据转换成图形信号,从而将CPU伪装成一个图形发送设备。
java 代码1.// 显卡,即我们的适配器2.public class Adapter extends Target {3.4. // 被代理的设备5. private Adaptee apt = null;6.7. /**8. * 装入被代理的设备9. */10. public Adapter(Adaptee apt) {11. this.apt = apt;12. }13.14. /**15. * 被代理的设备传过来的数据转换成为图形输出16. */17. public String request() {18. return apt.getData();19. }20.}这样,我们的电脑的显示流程就变成CPU-显卡-显示器:java 代码1.public class Client {2.3. public static void main(String[] args) {4. // CPU经过显卡的适配后“变”成了图形发送装置了5. Target target = new Adapter(new Adaptee());6. System.out.println(target.request());7. }8.9.}上面的这种依赖于对象组合的Adapter模式叫做对象适配器(Object Adapter)。
它的特征是继承/实现某一方的类(Target),如这里的图形发送器,同时内部包含一个被适配的类(Adaptee),如这里的CPU。
通过重写其父类的方法来进行适配。
另一种的Adapter实现对于Adapter模式,还有另外一种实现方式,这种适配方式叫做类适配器(Class Adapter)。
它与Object Adapter的不同之处在于它继承被适配的对象。
java 代码1.public class Adapter extends Targer, Adaptee {2. ......3.}这样的代码在C++中是合法的,但是在Java中规定最多只能继承一个父类,而可以实现多个接口。
所以我们需要建立一个IAdaptee的接口,然后将我们的Adapter继承Target同时实现IAdaptee。
java 代码1.// IAdaptee接口2.public interface IAdaptee {3.4. String getData();5.}java 代码1.// Adaptee 实现IAdaptee2.public class Adaptee implements IAdaptee {3. ......4.}java 代码1.public class Adapter extends Target implements IAdaptee {2.3. private IAdaptee apt = null;4.5. public Adapter(IAdaptee apt) {6. this.apt = apt;7. }8.9. public String request() {10. return apt.getData();11. }12.13. public String getData() {14. return apt.getData();15. }16.}对于我们的显示器(Client)方面,Class Adapter跟Object Adapter一样,所以不需要进行修改。
对于Class Adapter,大家也看见了,在Adapter中因为是实现了IAdaptee接口,因此需要实现getData()的接口。
一旦Target和IAdaptee拥有相同的方法时,会出现麻烦的。
所以尽量优先使用Object Adapter的模式C:工作一年多了,纸上的笔记写了不少,但一直没有机会整理。
现在离职了,就用这段时间整理一下自己的笔记,也顺便丰富一下自己的博客吧,要不也真的对不起在这里潜水两年的时间。
适配器:基于现有类所提供的服务,向客户提供接口,以满足客户的期望《Java设计模式》类适配器客户的开发人员定义了一个接口,期望用这个接口来完成整数的求和操作,接口定义如下:Java代码1.public interface Operation{2. public int add(int a,int b);3.}开发人员在了解这个接口的定义后,发现一个第三方类,里面有一个方法能实现他们期望的功能,其代码如下:Java代码1.public class OtherOperation{2. public int otherAdd(int a,int b){3. return a + b;4. }5.}以上第三方类OtherOperation的方法public int otherAdd(int a,int b)所提供的功能,完全能符合客户的期望,所以只需要想办法把OtherOperation的otherAdd(int a,int b)和客户的Operation接口联系起来,让这个第三方类来为客户提供他们期望的服务就行了,这样就避免了开发人员再度去研究类似OtherOperation的otherAdd(int a,int b)方法的实现(利用已有的轮子,避免重复发明),这方法之一,就是用适配器模式:Java代码1.public class AdapterOperation extends OtherOperation implementsOperation{2. public int add(int a,int b){3. return otherAdd(a,b);4. }5.}以上就是适配器的实现方法之一,类适配器,在以上实现中存在着三中角色分别是:1:适配目标角色:Operation。
2:适配类(原)角色:OtherOperation。
3:适配器角色:AdapterOperation。
其中适配器角色是适配器模式的核心。
适配器的主要工作就是通过封装现有的功能,使他满足需要的接口。
对象适配器我们再来看看另一种情况:假如客户接口期望的功能不止一个,而是多个:Java代码1.public interface Operation{2. public int add(int a,int b);3. public int minus(int a,int b);4. public int multiplied(int a,int b);5.}而能提供这些实现的原可能不止一个:Java代码1.public class OtherAdd{2. public int otherAdd(int a,int b){3. return a + b;4. }5.}6.7.public class OtherMinus{8. public int minus(int a,int b){9. return a - b;10. }11.}12.13.public class OtherMultiplied{14. public int multiplied(int a,int b){15. return a * b;16. }17.}由于java是不能实现多继承的,所以我们不能通过构建一个适配器,让他来继承所有原以完成我们的期望,这时候怎么办呢?只能用适配器的另一种实现--对象适配器:Java代码1.public class AdapterOperation implements Operation{2. private OtherAdd add;3. private OtherMinus minus;4. private OtherMultiplied multiplied;5.6. public void setAdd(OtherAdd add){7. this.add = add;8. }9.10. public void setMinus(OtherMinus minus){11. this.minus = minus;12. }13.14. public void setMultiplied(OtherMultiplied multiplied){15. this.multiplied = multiplied;16. }17.18. //适配加法运算19. public int add(int a,int b){20. return add.otherAdd(a,b);21. }22.23. //适配减法运算24. public int minus(int a,int b){25. return minus.minus(a,b);26. }27.28. //适配乘法运算29. public int multiplied(int a,int b){30. return multiplied.multiplied(a,b);31. }32.}上面代码很明显,适配器并不是通过继承来获取适配类(原)的功能的,而是通过适配类的对象来获取的,这就解决了java不能多继承所带来的不便了。