外观模式应该是我们再实际项目中常常使用的一种设计模式。或者说其实在使用的时候自己都不感觉在使用一种设计模式在编程。它其实就是直接体现了在系统中增加一个中间件将使代码逻辑更加简洁清晰这样一种思想。比如我们需要编写一个媒体播放器。一般外面的调用者就只能看到一个Player类了而不用去关心内部的实现细节。当需要播放一个内容时就直接 Player.play(url)
就完成了我们关心的媒体播放业务。而至于底层如何获取数据,解码数据,显示数据就根本不用关心了。具体代码如下。
原本我们有三个子系统。Extractor, Decoder, Renderer。现在为了客户调用代码更加简单,并且屏蔽掉内部实现细节。我们引入一个Player类,客户端代码与Player类交互,Player类与三个子系统交互。
class Player{
private Extractor extractor;
private Decoder decoder;
private Renderer renderer;
public Player() {
this.extractor = new Extractor();
this.decoder = new Decoder();
this.renderer = new Renderer();
}
public void play(String url) {
extractor.setUrl(url);
renderer.rendering(decoder.decode(extractor.getPacket()));
}
}
class Packet{
}
class Frame{
}
class Extractor{
private String url;
public void setUrl( String url) {
this.url = url;
}
public Packet getPacket() {
Packet packet = new Packet();
//logic of getting packet;
System.out.println("get packet from " + this.url);
return packet;
}
}
class Decoder{
public Frame decode(Packet packet) {
Frame frame = new Frame();
//logic of decoding packet
System.out.println("decode packet");
return frame;
}
}
class Renderer{
public void rendering(Frame frame) {
//logic of renderring
System.out.println("render frame");
}
}
public class facadePattern {
public static void main(String[] args) {
Player player = new Player();
player.play("file://demo.mp4");
}
}
输出结果:
get packet from file://demo.mp4
decode packet
render frame
下面是C++实现:
class Extractor{
public:
void getPacket(){
cout<< "extractor get packet \n";
}
};
class Decoder{
public:
void getFrame(){
cout << "decoder get frame\n";
}
};
class Renderer{
public:
void renderFrame(){
cout << "renderer render frame \n";
}
};
class Player{
public:
Player(){
extractor = new Extractor();
decoder = new Decoder();
renderer = new Renderer();
}
~Player(){
delete extractor;
delete decoder;
delete renderer;
}
void play(){
extractor->getPacket();
decoder->getFrame();
renderer->renderFrame();
}
private:
Extractor *extractor;
Decoder *decoder;
Renderer *renderer;
};
int main(int argc, const char * argv[]) {
Player *player = new Player();
player->play();
delete player;
return 0;
}
然后我们再来看一下C语言实现吧:
typedef struct _Extractor{
void (*getPacket)(struct _Extractor*);
}Extractor;
void getPacket(struct _Extractor* ext){
printf("extractor get packet\n");
}
Extractor *newExtractor(){
Extractor *ext = (Extractor *)malloc(sizeof(Extractor));
ext->getPacket= getPacket;
return ext;
}
typedef struct _Decoder{
void (*getFrame)(struct _Decoder*);
}Decoder;
void getFrame(struct _Decoder* dec){
printf("Decoder get frame\n");
}
Decoder *newDecoder(){
Decoder *dec = (Decoder *)malloc(sizeof(Decoder));
dec->getFrame = getFrame;
return dec;
}
typedef struct _Renderer{
void (*renderFrame)(struct _Renderer*);
}Renderer;
void renderFrame(struct _Renderer* render){
printf("renderer render frame\n");
}
Renderer *newRenderer() {
Renderer *render = (Renderer*)malloc(sizeof(Renderer));
render->renderFrame = renderFrame;
return render;
}
typedef struct _Player{
Extractor * extractor;
Decoder *decoder;
Renderer *renderer;
void (*play)(struct _Player *);
}Player;
void play(struct _Player * player){
player->extractor->getPacket(player->extractor);
player->decoder->getFrame(player->decoder);
player->renderer->renderFrame(player->renderer);
}
Player *newPlayer(){
Player *player = (Player *)malloc(sizeof(Player));
player->extractor = newExtractor();
player->decoder = newDecoder();
player->renderer = newRenderer();
player->play = play;
return player;
}
int main(int argc, char** argv){
Player *player = newPlayer();
player->play(player);
return 0;
}
其实在我们实际的工作中,我们完全不用拿着一个设计模式去套我们的代码,只要按照面向对象的原则去编码,理解其思想。像外观模式这种代码是可以很随意的写出来的。也许在我们的代码中充斥者很多这样的设计。