zoukankan      html  css  js  c++  java
  • IOS设计模式浅析之外观模式(Facade)

    引言  

      在项目开发中,有时候会遇到这样的一种情景:已有系统的各个子系统之间,随着业务需求的发展,有了比较紧凑的耦合关系。现在需要利用这些子系统的功能,为移动端提供业务处理。我们该怎么应对这样的业务需求呢?这就是本章外观模式所要解决的问题。

      进入正式讲解前,我们先来分析一下两种应对如上业务需求的方式:

      方式一:移动端直接调用各个子系统的功能,和各个子系统之间形成紧耦合的关系,如下图所示:

     

      方式二:提供一个高层接口,该高层接口负责和子系统进行交互,并向移动端提供需要使用的接口,如下图所示:

     

      从上面两种方式的图式结构可以看到,对移动端来说,方式二比方式一要好用很多,因为在方式二中,移动端不需要知道各个子系统的逻辑,只需要和高层接口交互就可以了。实际上方式二,就是我们这里要说的外观模式了。

    定义

      “为子系统中的一组接口提供一个统一的接口。外观模式定义了一个更高层次的接口,这个接口使得这一子系统更加容易使用。”

      最初的定义出现于《设计模式》(Addison-Wesley,1994)。

      这个定义,通过上面引言的图示讲解,应该很好理解了,这里再分析一下定义中的两个重要角色:

      外观角色:就是引言图示中的“高层接口”,客户端可以调用这个角色的方法;另外,该角色知道相关的子系统的功能和责任。

      子系统角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被外观角色调用。

    结构图

     

    示例

      生活中,应用外观模式的例子很多,比如去饭馆吃饭,我们不需要关注菜的选料、烹调等过程,只需要和服务员进行交互:服务员给我们菜谱(相当于就是外观模式的高级接口),我们选菜(调用接口),就可以享受美食。

      这里,我们用另一个生活中的例子来进行解说。不知道大家有没有通过旅行社报团出去旅游的经历?这是一个很好的外观模式的应用。我们选择好景点之后,旅行社会帮我们联系大巴、旅馆、饭店、景点门票以及景点服务等事情,这些事情我们都不需要亲自去安排,这就是外观模式的便利之处:可以使得客户端的接口更简单。

      下面列出应用外观模式实现旅行社报团旅游的结构图:

     

      如果不应用外观模式,我们(上图中的Client),就得自己去联系交通工具、预定旅馆、饭馆、景点门票等,相信这样的旅程,大家会感觉很累。有了外观角色(上图中的Facade),它会帮我们去处理这些事情。完整代码大家可以下载查看,这里只贴出部分源码。

      Facade.m(部分源码):

     1 - (id)init
     2 {
     3     self = [super init];
     4     if (self != nil)
     5     {
     6         _transportation = [[Transportation alloc] init];
     7         _hotel = [[Hotel alloc] init];
     8         _restaurant = [[Restaurant alloc] init];
     9         _attractions = [[Attractions alloc] init];
    10     }
    11     return self;
    12 }
    13 
    14 - (void)travel
    15 {
    16     [_transportation selTransportation];
    17     [_hotel selHotel];
    18     [_restaurant selRestaurant];
    19     [_attractions selAttractions];
    20 }
    21 
    22 - (void)dealloc
    23 {
    24     [_transportation release];
    25     [_hotel release];
    26     [_restaurant release];
    27     [_attractions release];
    28     
    29     [super dealloc];
    30 }

      从源码可以看到,外观类调用了交通工具类、旅馆类、饭馆类、景点类。下面看看客户端调用代码:

    1 Facade *facade = [[Facade alloc] init];
    2 [facade travel];
    3 [facade release];

      客户端代码只需要和外观类进行交互。

      下载源码

    小结

      通过上面的讲解,我们来分析一下外观模式的特点:

    • Facade设计模式注重从架构的层次去看整个系统,而不是单个类的层次。很多时候,它是一种架构设计模式,比如我们常用的三层架构。
    • Facade模式简化了整个系统的接口,同时对于系统内部(子系统)与外部程序(Client)来说,也达到了一种“解耦”的效果。

      根据外观模式的特点,我们可以在以下情况中使用Facade模式:

    • 不需要使用一个复杂系统的所有功能,只需要使用系统的部分功能时,那么应用Façade模式提供一个高层接口将比直接调用原系统的接口简单得多。
    • 希望封装或者隐藏原系统的接口时,可以考虑使用外观模式。
    • 希望使用原系统的部分功能,而且还希望增加一些新的功能。
    • 构建一个具有层次结构的子系统时,使用Facade模式定义子系统中每层的高级接口。如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。

      返回目录

  • 相关阅读:
    jmeter循环发送http请求
    判断字符串是否为日期格式
    正则表达式的部分替换 $1~$99
    js验证上传文件大小
    mongodb主从备份 和 手动主从切换
    openproject安装与使用
    软件项目开发常见错误
    使用selenium的WebDriver和ChromeDriver实现UI自动化
    shell ssh远程执行命令
    Flask入门
  • 原文地址:https://www.cnblogs.com/eagle927183/p/3511876.html
Copyright © 2011-2022 走看看