zoukankan      html  css  js  c++  java
  • 设计模式---外观模式 (举例:看电影)

     

    外观模式

    外观模式(Facade Pattern)定义:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。其实就是为了方便客户的使用,把一群操作,封装成一个方法。

    外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。

    外观模式又称为门面模式,它是一种对象结构型模式。外观模式是迪米特法则的一种具体实现,通过引入一个新的外观角色可以降低原有系统的复杂度,同时降低客户类与子系统的耦合度。

    外观模式包含如下两个角色:

    Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。

    SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。

    外观模式的目的不是给予子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散耦合,从而让外部能够更简单地使用子系统。

    外观模式的本质是:封装交互,简化调用

    外观模式,一般用在子系统与访问之间,用于对访问屏蔽复杂的子系统调用,采用耳目一新的外观类提供的简单的调用方法,具体的实现由外观类去子系统调用。

    外观模式任然是一种中间件类型的模式,使用外观模式之后子系统的方法调用并非完全屏蔽,只是为访问者提供了一种更佳的访问方式,如果你不嫌麻烦,任然可以直接进行子系统方法调用。

    甚至于在子系统与子系统之间进行调用时也可以通过各自的外观类来进行调用,这样代码方便管理。

     

    举个例子:我比较喜欢看电影,于是买了投影仪、电脑、音响、设计了房间的灯光、买了爆米花机,然后我想看电影的时候,我需要:

    1、打开爆米花机

    2、制作爆米花

    3、将灯光调暗

    4、打开投影仪

    5、放下投影仪投影区

    6、打开电脑

    7、打开播放器

    8、将播放器音调设为环绕立体声

    ...

    尼玛,花了一笔钱,看电影还要这么多的步骤,太累了,而且看完还要一个一个关掉。

    所有,我们使用外观模式解决这些复杂的步骤,轻松享受电影:

     1 public class HomeTheaterFacade
     2 {
     3     private Computer computer;
     4     private Player player;
     5     private Light light;
     6     private Projector projector;
     7     private PopcornPopper popper;
     8  
     9     public HomeTheaterFacade(Computer computer, Player player, Light light, Projector projector, PopcornPopper popper)
    10     {
    11         this.computer = computer;
    12         this.player = player;
    13         this.light = light;
    14         this.projector = projector;
    15         this.popper = popper;
    16     }
    17  
    18     public void watchMovie()
    19     {
    20         /**
    21          *  1、打开爆米花机
    22             2、制作爆米花
    23             3、将灯光调暗
    24             4、打开投影仪
    25             5、放下投影仪投影区
    26             6、打开电脑
    27             7、打开播放器
    28             8、将播放器音调设为环绕立体声
    29          */
    30         popper.on();
    31         popper.makePopcorn();
    32         light.down();
    33         projector.on();
    34         projector.open();
    35         computer.on();
    36         player.on();
    37         player.make3DListener();
    38     }
    39     
    40     public void stopMovie()
    41     {
    42         popper.off();
    43         popper.stopMakePopcorn();
    44         light.up();
    45         projector.close();
    46         projector.off();
    47         player.off();
    48         computer.off();
    49     }
    50 }

     


    可以看到,我们定义了一个类,然后可以让我一键享受看电影了,看完,一键关闭,享受多了。

     

    外观模式:一般用于需要简化一个很大的接口,或者一群复杂的接口的时候。

     

    这个模式比较容易理解,就不多说了,最后附上类图:

     

     

    参考自:

    《head first设计模式》一书

    http://blog.csdn.net/lmj623565791/article/details/25837275

    https://www.jianshu.com/p/7aa1e2ccb661

  • 相关阅读:
    ionic的start-y属性初始化页面
    AngularJS时间轴指令
    [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys
    常用CSS样式
    angularjs ng-click
    不是SELECTed表达式
    跨域资源共享(CORS)问题解决方案
    AngularJS身份验证:Cookies VS Tokens
    Javascript跨域
    Vmware虚拟机centos7命令登录模式与成桌面模式切换
  • 原文地址:https://www.cnblogs.com/vegetableDD/p/12304544.html
Copyright © 2011-2022 走看看