目录
1. 定义适配器模式
适配器模式:将一个类的接口,转换成客户期望的另外一个接口。适配器让原本接口不兼容的类可以合作无间
对象适配器就是使用组合,类适配器就是使用多重继承
1.1 对象适配器
1.1.1 DuckAdapter.h
#include "Turkey.h"
#include "Duck.h"
class DuckAdapter:public Turkey{
public:
DuckAdapter(Duck *duck);
virtual void gobble()override final;
virtual void fly()override final;
virtual ~DuckAdapter();
private:
Duck *duck;
};
1.1.2 DuckAdapter.cpp
#include "DuckAdapter.h"
#include <random>
DuckAdapter::DuckAdapter(Duck *duck)
{
this->duck=duck;
}
void DuckAdapter::gobble()
{
duck->quack();
}
void DuckAdapter::fly()
{
int randomi=rand()%2;
if(randomi)duck->fly();
}
DuckAdapter::~DuckAdapter()
{
delete duck;
}
1.2 类适配器
1.2.1 WildTurkeyAdapter.h
#include "Duck.h"
#include "WildTurkey.h"
class WildTurkeyAdapter:public Duck,public WildTurkey{
public:
WildTurkeyAdapter();
virtual void fly()override final;
virtual void quack()override final;
virtual ~WildTurkeyAdapter();
};
1.2.2 WildTurkeyAdapter.cpp
#include "WildTurkeyAdapter.h"
WildTurkeyAdapter::WildTurkeyAdapter():Duck(),WildTurkey()
{
}
void WildTurkeyAdapter::fly()
{
WildTurkey::fly();
}
void WildTurkeyAdapter::quack()
{
WildTurkey::gobble();
}
WildTurkeyAdapter::~WildTurkeyAdapter()
{
}
1.3 类适配器和对象适配器的区别
1、对象适配器通过委派与adaptee衔接,即持有adaptee对象,是动态的方式;类适配器通过集成与adaptee衔接,也就是说类适配器继承adaptee,并且实现target方法,是静态的方式。
2、由于对象适配器采用动态的方式与adaptee衔接,使得它可以对不同的适配源及其子类进行适配
3、类适配器可以重定义实现行为,而对象适配器重定义适配的行为比较困难,但是添加行为较方便。
尽量使用对象适配器的实现方式,多用合成/聚合、少用继承。
最主要的区别:类适配器只能适配具体类,对象适配器可以适配抽象类(通过组合抽象类来适配所有的具体类)
2. 定义外观模式
外观模式:提供一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
2.1 部分源码
2.1.1 HomeTheaterFacade.h
#include <string>
#include <iostream>
#include "Amplifier.h"
#include "Tuner.h"
#include "StreamingPlayer.h"
#include "CdPlayer.h"
#include "Projector.h"
#include "TheaterLights.h"
#include "Screen.h"
#include "PopcornPopper.h"
using std::cout;
using std::endl;
using std::string;
class HomeTheaterFacade{
public:
HomeTheaterFacade( Amplifier *amp,
Tuner *tuner,
StreamingPlayer *player,
Projector *projector,
TheaterLights *lights,
Screen *screen,
PopcornPopper *popper);
void watchMovie(string movie);
void endMovie();
void listenToRadio(double frequency);
void endRadio();
private:
Amplifier *amp;
Tuner *tuner;
StreamingPlayer *player;
CdPlayer *cd;
Projector *projector;
TheaterLights *lights;
Screen *screen;
PopcornPopper *popper;
};
2.1.2 HomeTheaterFacade.cpp
#include "HomeTheaterFacade.h"
HomeTheaterFacade::HomeTheaterFacade(Amplifier *amp, Tuner *tuner, StreamingPlayer *player, Projector *projector, TheaterLights *lights, Screen *screen, PopcornPopper *popper)
{
this->amp=amp;
this->tuner=tuner;
this->player=player;
this->projector=projector;
this->screen=screen;
this->lights=lights;
this->popper=popper;
}
void HomeTheaterFacade::watchMovie(std::string movie)
{
cout<<"Get ready to watch a movie..."<<endl;
popper->on();
popper->pop();
lights->dim(10);
screen->down();
projector->on();
projector->wideScreenMode();
amp->on();
amp->setStreamingPlayer(player);
amp->setSurroundSound();
amp->setVolume(5);
player->on();
player->play(movie);
}
void HomeTheaterFacade::endMovie()
{
cout<<"Shutting movie theater down..."<<endl;
popper->off();
lights->on();
screen->up();
projector->off();
amp->off();
player->stop();
player->off();
}
void HomeTheaterFacade::listenToRadio(double frequency)
{
cout<<"Tuning in the airwaves..."<<endl;
tuner->on();
tuner->setFrequency(frequency);
amp->on();
amp->setVolume(5);
amp->setTuner(tuner);
}
void HomeTheaterFacade::endRadio()
{
cout<<"Shutting down the tuner..."<<endl;
tuner->off();
amp->off();
}
3. 总结
1.当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。
2.当需要简化并统一一个很大的接口或者 一群复杂的接口时,使用外观。
3.适配器模式有两种形式:对象适配器和类适配器。类适配器需要用到多重继承。
4.适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;而外观将一群对象“包装”起来以简化其接口。