design_pattern_facade

This post implements facade design pattern in <Head First Design Patterns>. Facade pattern wrapps a complicated subsystem with a simpler interface.  The general procedure

  1. Identify a simpler, unified interface for the subsystem or component.
  2. Design a “wrapper” class that encapsulates the subsystem.
  3. The facade/wrapper captures the complexity and collaborations of the component, and delegates to the appropriate methods.
  4. The client uses (is coupled to) the Façade only.
  5. Consider whether additional Facades would add value.

In the book, the whole system is complicated,

Facade pattern provides uniform and simple access to the system

The system component classes are given

class Amplifier {
private:
    std::string description;
	Tuner* tuner;
	DvdPlayer* dvd;
	CdPlayer* cd;

	Amplifier(const Amplifier& ); // Disable copy constructor
	void operator=(const Amplifier& ); // Disable assignment operator

public:
    Amplifier(std::string description_): description(description_), tuner(0), dvd(0), cd(0){}
 	void on() const {
		std::cout << description << " on" << std::endl;
	}
 	void off() const {
		std::cout << description << " off" << std::endl;
	}
    void setStereoSound() {
		std::cout << description << " stereo mode on" << std::endl;
	}
 	void setSurroundSound() {
		std::cout << description << " surround sound on (5 speakers, 1 subwoofer)" << std::endl;
	}
 	void setVolume(int level) {
		std::cout << description << " setting volume to " << level << std::endl;
	}
	public: void setTuner(Tuner* tuner_) {
		std::cout << description << " setting tuner to " << tuner->toString() << std::endl;
		tuner = tuner_;
	}
 	void setDvd(DvdPlayer* dvd_) {
		std::cout << description << " setting DVD player to " << dvd->toString()<< std::endl;
		dvd = dvd_;
	}
 	void setCd(CdPlayer* cd_) {
		std::cout << description << " setting CD player to " << cd->toString() << std::endl;
		cd = cd_;
	}
	void toString() const {
		return description.c_str();
	}
};

class Tuner {
private:
    std::string description;
	Amplifier* amplifier;
	double frequency;

	Tuner(const Tuner& ); // Disable copy constructor
	void operator=(const Tuner& ); // Disable assignment operator

public:
    Tuner(std::string description_, Amplifier* amplifier_):description(description_), amplifier(amplifier_), frequency(0.0) {}
	void on() {
		std::cout << description.c_str() << " on" << std::endl;
	}
	void off() {
		std::cout << description.c_str() << " off" << std::endl;
	}
	void setFrequency(double frequency_) {
		std::cout << _description.c_str() << " setting frequency to " << _frequency << std::endl;
		frequency = frequency_;
	}
	void setAm() {
		std::cout << description.c_str() << " setting AM mode" << std::endl;
	}
    void setFm() {
		std::cout << description.c_str() << " setting FM mode" << std::endl;
	}
	void toString() const {
		return description;
	}
};

class Screen {
private:
    std::string description;

	Screen(const Screen& );         // Disable copy constructor
	void operator=(const Screen& ); // Disable assignment operator

public:
    Screen(std::string description_ ):description(description_) {}
	void up(){
		std::cout << description.c_str() << " going up" << std::endl;
	}
	void down() {
		std::cout << description.c_str() << " going down" << std::endl;
	}
    void toString() {
		return description;
    }
};

class PopcornPopper {
private:
    std::string description;

	PopcornPopper(const PopcornPopper& );  // Disable copy constructor
	void operator=(const PopcornPopper& ); // Disable assignment operator

public:
    PopcornPopper(std::string description_):description(description_){}

 	void on() const{
		std::cout << description.c_str() << " on" << std::endl;
	}
 	void off() const{
		std::cout << description.c_str() << " off" << std::endl;
	}
	void pop() const{
		std::cout << description.c_str() << " popping popcorn!" << std::endl;
	}

	void toString() const{
		return description;
	}
};

class TheaterLights {
private:
    std::string description;

	TheaterLights(const TheaterLights& );  // Disable copy constructor
	void operator=(const TheaterLights& ); // Disable assignment operator

public:
    TheaterLights(std::string description_):description(description_) {}
	void on() {
		std::cout << description.c_str() << " on" << std::endl;
	}
    void off() {
		std::cout << description.c_str() << " off" << std::endl;
	}
    void dim(int level) {
		std::cout << description.c_str() << " dimming to " << level  << "%" << std::endl;
	}

	void toString() {
		return description;
	}
};

class CdPlayer {
private:
    std::string description;
	Amplifier* amplifier;
	std::string title;
	int currentTrack;

	CdPlayer(const CdPlayer& );       // Disable copy constructor
	void operator=(const CdPlayer& ); // Disable assignment operator

public:
    CdPlayer(std::string description_, Amplifier* amplifier_):description(description_), amplifier(amplifier_), currentTrack_(0) {}
	void on() const {
		std::cout << description.c_str() << " on" << std::endl;
	}
	void off() const {
		std::cout << description.c_str() << " off" << std::endl;
	}
	void eject() {
		title.empty();
		std::cout << description.c_str() << " eject" << std::endl;
	}
	void play(std::string title_) {
		title = title_;
		std::cout << description.c_str() << " playing \"" << _title << "\"" << std::endl;
	}
	void play(int track) {
		if(title.length() == 0) {
			std::cout << description.c_str() << " can't play track " << _currentTrack << ", no cd inserted" << std::endl;
		} else {
			currentTrack = track;
			std::cout << description.c_str() << " playing track " << _currentTrack << std::endl;
		}
	}
	void stop() {
		currentTrack = 0;
		std::cout << description.c_str() << " stopped" << std::endl;
	}
 	void pause() {
		std::cout << description.c_str() << " paused \"" << _title << "\"" << std::endl;
	}
 	void toString() const {
		return description;
	}
};

class DvdPlayer {
private:
    std::string description;
	Amplifier* amplifier;
	int currentTrack;
	std::string movie;

	DvdPlayer(const DvdPlayer& );      // Disable copy constructor
    void operator=(const DvdPlayer& ); // Disable assignment operator

public:
    DvdPlayer(std::string description_, Amplifier* amplifier_): description(description_), amplifier(amplifier_), currentTrack(0) {}
 	void on() const {
		std::cout << description << " on" << std::endl;
	}
 	void off() const {
		std::cout << description << " off" << std::endl;
	}
    void eject() {
		movie.empty();
		std::cout << description << " eject" << std::endl;
    }
	void play(std::string movie_) {
		movie = movie_;
		std::cout << description << " playing \"" << movie << "\"" << std::endl;
	}
	void play(int track) {
		if(movie.length() == 0) {
			std::cout << description << " can't play track " << track << " no dvd inserted" << std::endl;
		} else {
			currentTrack = track;
			std::cout << description << " playing track " << track << " of \"" << _movie << "\"" << std::endl;
		}
	}
	void stop() {
		currentTrack = 0;
		std::cout << description << " stopped \"" << _movie << "\"" << std::endl;
	}
	public: void pause() {
		std::cout << description << " paused \"" << _movie << "\"" << std::endl;
	}
	public: void setTwoChannelAudio() {
		std::cout << description << " set two channel audio" << std::endl;
	}
	public: void setSurroundAudio() {
		std::cout << description << " set surround audio" << std::endl;
	}
	public: std::string toString() const {
		return description;
	}
};

class Projector {
private:
    std::string description;
	DvdPlayer*  dvdPlayer;

	Projector(const Projector& );      // Disable copy constructor
	void operator=(const Projector& ); // Disable assignment operator

public:
    Projector(std::string description_, DvdPlayer* dvdPlayer_):description(description_), dvdPlayer(dvdPlayer_) {}
	void on() {
		std::cout << description.c_str() << " on" << std::endl;
	}
	void off() {
		std::cout << description.c_str() << " off" << std::endl;
	}
	void wideScreenMode() {
		std::cout << description.c_str() << " in widescreen mode (16x9 aspect ratio)" << std::endl;
	}
	void tvMode() {
		std::cout << description.c_str() << " in tv mode (4x3 aspect ratio)" << std::endl;
	}
    void toString() {
		return description;
    }
};
The simplified interface is

class HomeTheaterFacade {
private:
    Amplifier* amp;
	Tuner* tuner;
	DvdPlayer* dvd;
	CdPlayer* cd;
	Projector* projector;
	TheaterLights* lights;
	Screen* screen;
	PopcornPopper* popper;

	HomeTheaterFacade(const HomeTheaterFacade& ); // Disable copy constructor
	void operator=(const HomeTheaterFacade& );    // Disable assignment operator

public:
    HomeTheaterFacade(Amplifier* amp_, Tuner* tuner_, DvdPlayer* dvd_, CdPlayer* cd_, Projector* projector_, Screen* screen_, TheaterLights* lights_, PopcornPopper* popper_) :
		amp(amp_), tuner(tuner_), dvd(dvd_), cd(cd_), projector(projector_), lights(lights_), screen(screen_), popper(popper_){}
 	void watchMovie(std::string movie_) {
		std::cout << "Get ready to watch a movie..." << std::endl;
		popper->on();
		popper->pop();
		lights->dim( 10 );
		screen->down();
		projector->on();
		projector->wideScreenMode();
		amp->on();
		amp->setDvd( dvd );
		amp->setSurroundSound();
		amp->setVolume( 5 );
		dvd->on();
		dvd->play( movie_);
	}
	void endMovie() {
		std::cout << "Shutting movie theater down..." << std::endl;
		popper->off();
		lights->on();
		screen->up();
		projector->off();
		amp->off();
		dvd->stop();
		dvd->eject();
		dvd->off();
	}
    void listenToCd( std::string cdTitle ) {
		std::cout << "Get ready for an audiopile experence..." << std::endl;
		lights->on();
		amp->on();
		amp->setVolume( 5 );
		amp->setCd( cd );
		amp->setStereoSound();
		cd->on();
		cd->play( cdTitle );
	}
	void endCd() {
		std::cout << "Shutting down CD..." << std::endl;
		amp->off();
		amp->setCd( _cd );
		cd->eject();
		cd->off();
	}
	void listenToRadio( double frequency ) {
		std::cout << "Tuning in the airwaves..." << std::endl;
		tuner->on();
		tuner->setFrequency( frequency );
		amp->on();
		amp->setVolume( 5 );
		amp->setTuner( _tuner );
	}
	void endRadio() {
		std::cout << "Shutting down the tuner..." << std::endl;
		tuner->off();
		amp->off();
	}
};
Main function is

#include <iostream>
#include <./hometheater.hpp>

int main()
{
    Amplifier* amp = new Amplifier("Top-O-Line Amplifier");
	Tuner* tuner = new Tuner("Top-O-Line AM/FM Tuner", amp);
	DvdPlayer* dvd = new DvdPlayer("Top-O-Line DVD Player", amp);
	CdPlayer* cd = new CdPlayer("Top-O-Line CD Player", amp);
	Projector* projector = new Projector("Top-O-Line Projector", dvd);
	TheaterLights* lights = new TheaterLights("Theater Ceiling Lights");
	Screen* screen = new Screen("Theater Screen");
	PopcornPopper* popper = new PopcornPopper("Popcorn Popper");

	HomeTheaterFacade* homeTheater = new HomeTheaterFacade(amp, tuner, dvd, cd, projector, screen, lights, popper);

	homeTheater->watchMovie("Raiders of the Lost Ark");
	homeTheater->endMovie();

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值