只與最接近的朋友交談
(深入淺出設計模式 2nd (p.267)
這些方針告訴我們,如果我們呼叫其他的方法而收到一個物件,不要直接對著那個物件呼叫它的方法
(深入淺出設計模式 2nd (p.268)
在一個完整的家庭劇院系統中,通常會有多個組件如放大器(Amplifier)、調諧器(Tuner)、串流播放器(StreamingPlayer)、投影機(Projector)、燈光(TheaterLights)、螢幕(Screen)、光碟機 (Popper)...等。這些組件各自有不同的操作和設定,對一般使用者 (Client)來說,可能會感到操作複雜和不便。因此,我們可以使用 Facade Pattern 來簡化這一系列複雜的操作
// 放大器
class Amplifier {
public:
void on() { std::cout << "Amplifier is ON.\n"; }
void off() { std::cout << "Amplifier is OFF.\n"; }
};
// 調諧器
class Tuner {
public:
void setFrequency(double f) { std::cout << "Tuner set to frequency " << f << ".\n"; }
};
// 串流播放器
class StreamingPlayer {
public:
void play(std::string movie) { std::cout << "StreamingPlayer playing " << movie << ".\n"; }
void stop() { std::cout << "StreamingPlayer stopped.\n"; }
};
// 投影機
class Projector {
public:
void on() { std::cout << "Projector is ON.\n"; }
void off() { std::cout << "Projector is OFF.\n"; }
};
// 劇院燈光
class TheaterLights {
public:
void dim() { std::cout << "Theater lights are dimming.\n"; }
};
// 屏幕
class Screen {
public:
void down() { std::cout << "Screen is down.\n"; }
void up() { std::cout << "Screen is up.\n"; }
};
// 光碟機
class Popper {
public:
void on() { std::cout << "Popper is ON.\n"; }
void off() { std::cout << "Popper is OFF.\n"; }
};
// Home Theater Facade (簡化給使用者操作的介面)
class HomeTheaterFacade {
private:
Amplifier amp;
Tuner tuner;
StreamingPlayer player;
Projector projector;
TheaterLights lights;
Screen screen;
Popper popper;
public:
void watchMovie(std::string movie) {
std::cout << "Preparing to watch movie...\n";
popper.on();
lights.dim();
screen.down();
amp.on();
tuner.setFrequency(101.9);
projector.on();
player.play(movie);
}
void endMovie() {
std::cout << "Shutting down theater...\n";
player.stop();
projector.off();
screen.up();
lights.dim();
amp.off();
popper.off();
}
};
// 使用者看電影範例
int main() {
HomeTheaterFacade homeTheater;
homeTheater.watchMovie("The Matrix");
homeTheater.endMovie();
}
[1]. https://refactoring.guru/design-patterns/facade
[2]. https://ithelp.ithome.com.tw/articles/10227186