C++设计模式7--外观模式--The Client don't want to know

大家有做项目的时候,有没有这样的经历,

①我们项目本来很精简,但是随着项目的不断完善,扩充,功能越来越复杂,类体系也越来越复杂。很多时候工作,一个很简单的事情,我们需要调研那个很多到工序才能完成。这样维护起来代码,无论是谁都会感到很累。但其实这时候那些内部逻辑我们都没必要了解了,一个简单的接口反而更加适合我们的操作更加这时候外观模式就派上用途了。

②或者说我们在开发的时候要用到一个第三方库,这些库操作很底层,我们每次要调用,都需要调用很多类,例如我们在用ffmpegsdl库进行嵌入式视频库的开发的时候,每次都要加锁,,读取包,解码,等等,我们就可以用外观模式将这些接口封装起来,这样我们每次调用,只需要调用我们封装好的接口。

对比现实中的例子,

①比如说,我们喝茶,如果是自己泡茶需要自行准备茶叶、茶具和开水,但是我们其实部需要了解这些,我们只需要一个结果,就是那个泡好的茶,于是我们去了茶馆,我们只需要跟茶馆服务员说想要一杯什么样的茶,是铁观音、碧螺春还是西湖龙井?正因为茶馆有服务员,顾客无须直接和茶叶、茶具、开水等交互,整个泡茶过程由服务员来完成,顾客只需与服务员交互即可,整个过程非常简单省事,这时候,茶馆或者说服务员就像一个外观模式,将所有我们不关心的,或者无需了解的操作封装(隐藏)起来,只给了我们一个结果。

②再例如说我们去邮局寄信,我们并不关心信是怎么寄的,我们(客户端)只需要调用一个叫做邮寄的方法,邮局的邮递员就自行把邮件给我们邮寄出去了,这时候就相当于,邮递员这个外观,将邮寄信的方法都给我们封装隐藏起来,我们使用起来也方便不少。

③比如说我们使用编译器,编译我们的代码,其实我们需要,经过预处理,词法,语法,语义,中间代码生成,汇编,链接,但是我们不需要了解这个,We don’t want to konw it,,因此出现了IDE,例如VisualCodeBlocksDevCppEclipce等,我们只需要一个Build,好了一切都完成了。

 

说了这么多这就是外观模式,它有几个好处(摘自DP一书),

1)它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。

2)它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。

3)如果应用需要,它并不限制它们使用子系统类。

 

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5.   
  6. // 词法分析  
  7. class Lexicaler  
  8. {  
  9. public :  
  10.     void Lexical( )  
  11.     {  
  12.         std::cout <<"正在对源文件进行词法分析" <<std::endl;  
  13.     }  
  14. };  
  15.   
  16. // 语法分析  
  17. class Parser  
  18. {  
  19. public :  
  20.     void Parse( )  
  21.     {  
  22.         std::cout <<"正在对源文件进行语法分析" <<std::endl;  
  23.     }  
  24. };  
  25.   
  26. // 语义分析  
  27. class Semantier  
  28. {  
  29. public :  
  30.     void Semantic( )  
  31.     {  
  32.         std::cout <<"正在对源文件进行语义分析" <<std::endl;  
  33.     }  
  34. };  
  35.   
  36.   
  37. // 生成中间代码  
  38. class Gener  
  39. {  
  40. public :  
  41.     void Gen( )  
  42.     {  
  43.         std::cout <<"正在生成目标代码" <<std::endl;  
  44.     }  
  45. };  
  46.   
  47.   
  48. // 生成中间代码  
  49. class Asmer  
  50. {  
  51. public :  
  52.     void Asm( )  
  53.     {  
  54.         std::cout <<"正在生成目标代码" <<std::endl;  
  55.     }  
  56. };  
  57.   
  58. // 连接  
  59. class Linker  
  60. {  
  61. public :  
  62.     void Link( )  
  63.     {  
  64.         std::cout <<"正在生成链接" <<std::endl;  
  65.     }  
  66. };  
  67.   
  68.   
  69. class Complier  
  70. {  
  71. public :  
  72.     void Comple( )  
  73.     {  
  74.         Lexicaler lexicaler;  
  75.         Parser parser;  
  76.         Semantier semantier;  
  77.         Gener   gener;  
  78.         Asmer   asmer;  
  79.         Linker  linker;  
  80.   
  81.         lexicaler.Lexical( );  
  82.         parser.Parse( );  
  83.         semantier.Semantic( );  
  84.         gener.Gen( );  
  85.         asmer.Asm( );  
  86.         linker.Link( );  
  87.     }  
  88. };  
  89.   
  90.   
  91. int main(void)  
  92. {  
  93.     // 这是不用外观模式的代码  
  94.     // 但是其实我们并不关心编译的过程,  
  95.     // 我们需要的只是编译的结果,  
  96.     // 那个可执行程序才是我们想要的  
  97.     Lexicaler lexicaler;  
  98.     Parser parser;  
  99.     Semantier semantier;  
  100.     Gener   gener;  
  101.     Asmer   asmer;  
  102.     Linker  linker;  
  103.   
  104.     lexicaler.Lexical( );  
  105.     parser.Parse( );  
  106.     semantier.Semantic( );  
  107.     gener.Gen( );  
  108.     asmer.Asm( );  
  109.     linker.Link( );  
  110.   
  111.     // 使用外观模式  
  112.     Complier complier;  
  113.     complier.Comple( );  
  114. }  
#include <iostream>

using namespace std;


// 词法分析
class Lexicaler
{
public :
    void Lexical( )
    {
        std::cout <<"正在对源文件进行词法分析" <<std::endl;
    }
};

// 语法分析
class Parser
{
public :
    void Parse( )
    {
        std::cout <<"正在对源文件进行语法分析" <<std::endl;
    }
};

// 语义分析
class Semantier
{
public :
    void Semantic( )
    {
        std::cout <<"正在对源文件进行语义分析" <<std::endl;
    }
};


// 生成中间代码
class Gener
{
public :
    void Gen( )
    {
        std::cout <<"正在生成目标代码" <<std::endl;
    }
};


// 生成中间代码
class Asmer
{
public :
    void Asm( )
    {
        std::cout <<"正在生成目标代码" <<std::endl;
    }
};

// 连接
class Linker
{
public :
    void Link( )
    {
        std::cout <<"正在生成链接" <<std::endl;
    }
};


class Complier
{
public :
    void Comple( )
    {
        Lexicaler lexicaler;
        Parser parser;
        Semantier semantier;
        Gener   gener;
        Asmer   asmer;
        Linker  linker;

        lexicaler.Lexical( );
        parser.Parse( );
        semantier.Semantic( );
        gener.Gen( );
        asmer.Asm( );
        linker.Link( );
    }
};


int main(void)
{
    // 这是不用外观模式的代码
    // 但是其实我们并不关心编译的过程,
    // 我们需要的只是编译的结果,
    // 那个可执行程序才是我们想要的
    Lexicaler lexicaler;
    Parser parser;
    Semantier semantier;
    Gener   gener;
    Asmer   asmer;
    Linker  linker;

    lexicaler.Lexical( );
    parser.Parse( );
    semantier.Semantic( );
    gener.Gen( );
    asmer.Asm( );
    linker.Link( );

    // 使用外观模式
    Complier complier;
    complier.Comple( );
}

好了外观模式,就是将那些Client don’t want to konw的事情封装起来,对客户端隐蔽。


转载:http://blog.csdn.net/gatieme/article/details/17993075

上一篇:设计模式之十(外观模式)


下一篇:【HeadFirst 设计模式学习笔记】7 适配器模式和外观模式