《headfirst设计模式》读书笔记7-适配器模式和外观模式

本文探讨了适配器模式(对象与类适配)的应用,包括如何通过组合与继承实现接口转换,以及外观模式如何提供统一接口简化子系统。介绍了DuckAdapter和WildTurkeyAdapter示例,以及HomeTheaterFacade作为外观模式的实践应用。
摘要由CSDN通过智能技术生成

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.适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;而外观将一群对象“包装”起来以简化其接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗吧!骚年!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值