IOS设计模式浅析之外观模式(Facade)
引言
在项目开发中,有时候会遇到这样的一种情景:已有系统的各个子系统之间,随着业务需求的发展,有了比较紧凑的耦合关系。现在需要利用这些子系统的功能,为移动端提供业务处理。我们该怎么应对这样的业务需求呢?这就是本章外观模式所要解决的问题。
进入正式讲解前,我们先来分析一下两种应对如上业务需求的方式:
方式一:移动端直接调用各个子系统的功能,和各个子系统之间形成紧耦合的关系,如下图所示:
方式二:提供一个高层接口,该高层接口负责和子系统进行交互,并向移动端提供需要使用的接口,如下图所示:
从上面两种方式的图式结构可以看到,对移动端来说,方式二比方式一要好用很多,因为在方式二中,移动端不需要知道各个子系统的逻辑,只需要和高层接口交互就可以了。实际上方式二,就是我们这里要说的外观模式了。
定义
“为子系统中的一组接口提供一个统一的接口。外观模式定义了一个更高层次的接口,这个接口使得这一子系统更加容易使用。”
最初的定义出现于《设计模式》(Addison-Wesley,1994)。
这个定义,通过上面引言的图示讲解,应该很好理解了,这里再分析一下定义中的两个重要角色:
外观角色:就是引言图示中的“高层接口”,客户端可以调用这个角色的方法;另外,该角色知道相关的子系统的功能和责任。
子系统角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被外观角色调用。
结构图
示例
生活中,应用外观模式的例子很多,比如去饭馆吃饭,我们不需要关注菜的选料、烹调等过程,只需要和服务员进行交互:服务员给我们菜谱(相当于就是外观模式的高级接口),我们选菜(调用接口),就可以享受美食。
这里,我们用另一个生活中的例子来进行解说。不知道大家有没有通过旅行社报团出去旅游的经历?这是一个很好的外观模式的应用。我们选择好景点之后,旅行社会帮我们联系大巴、旅馆、饭店、景点门票以及景点服务等事情,这些事情我们都不需要亲自去安排,这就是外观模式的便利之处:可以使得客户端的接口更简单。
下面列出应用外观模式实现旅行社报团旅游的结构图:
如果不应用外观模式,我们(上图中的Client),就得自己去联系交通工具、预定旅馆、饭馆、景点门票等,相信这样的旅程,大家会感觉很累。有了外观角色(上图中的Facade),它会帮我们去处理这些事情。完整代码大家可以下载查看,这里只贴出部分源码。
Facade.m(部分源码):
- (id)init
{
self = [super init];
if (self != nil)
{
_transportation = [[Transportation alloc] init];
_hotel = [[Hotel alloc] init];
_restaurant = [[Restaurant alloc] init];
_attractions = [[Attractions alloc] init];
}
return self;
} - (void)travel
{
[_transportation selTransportation];
[_hotel selHotel];
[_restaurant selRestaurant];
[_attractions selAttractions];
} - (void)dealloc
{
[_transportation release];
[_hotel release];
[_restaurant release];
[_attractions release]; [super dealloc];
}
从源码可以看到,外观类调用了交通工具类、旅馆类、饭馆类、景点类。下面看看客户端调用代码:
Facade *facade = [[Facade alloc] init];
[facade travel];
[facade release];
客户端代码只需要和外观类进行交互。
小结
通过上面的讲解,我们来分析一下外观模式的特点:
- Facade设计模式注重从架构的层次去看整个系统,而不是单个类的层次。很多时候,它是一种架构设计模式,比如我们常用的三层架构。
- Facade模式简化了整个系统的接口,同时对于系统内部(子系统)与外部程序(Client)来说,也达到了一种“解耦”的效果。
根据外观模式的特点,我们可以在以下情况中使用Facade模式:
- 不需要使用一个复杂系统的所有功能,只需要使用系统的部分功能时,那么应用Façade模式提供一个高层接口将比直接调用原系统的接口简单得多。
- 希望封装或者隐藏原系统的接口时,可以考虑使用外观模式。
- 希望使用原系统的部分功能,而且还希望增加一些新的功能。
- 构建一个具有层次结构的子系统时,使用Facade模式定义子系统中每层的高级接口。如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。
IOS设计模式浅析之外观模式(Facade)的更多相关文章
- 设计模式系列之外观模式(Facade Pattern)——提供统一的入口
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 设计模式学习心得<外观模式 Facade>
外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 这种模式涉及 ...
- 设计模式之八:外观模式(Facade)
外观模式: 为子系统中的一系列接口提供了一个统一的界面.外观模式定义了一个高层次的接口以使子系统更加easy使用. Provide a unified interface to a set of in ...
- IOS设计模式浅析之原型模式(Prototype)
原型模式的定义 “使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象”.最初的定义出现于<设计模式>(Addison-Wesley,1994). 简单来理解就是根据这个原型创建 ...
- 《JAVA设计模式》之外观模式(Facade)
在阎宏博士的<JAVA与模式>一书中开头是这样描述门面(Facade)模式的: 门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行.门面模式提供一个高层次的接口 ...
- IOS设计模式浅析之建造者模式(Builder)
定义 "将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现". 最初的定义出现于<设计模式>(Addison-Wesley,1994). 看这个概 ...
- IOS设计模式浅析之桥接模式(Bridge)
引言 在项目开发中,我们会遇到这样的一种场景:某些类型由于自身的逻辑,往往具有两个或多个维度的变化,比如说大话设计模式书中所说的手机,它有两个变化的维度:一是手机的品牌,可能有三星.苹果等:二是手机上 ...
- 【转】设计模式(九)外观模式Facade(结构型)
设计模式--外观模式Facade(结构型): 1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性. ...
- 设计模式(九)外观模式Facade(结构型)
设计模式(九)外观模式Facade(结构型) 1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性. ...
随机推荐
- HTTP协议下保证登录密码不被获取最健壮方式
原文:http://www.cnblogs.com/intsmaze/p/6009648.html HTTP协议下保证登录密码不被获取最健壮方式 说到在http协议下用户登录如何保证密码安全这个问 ...
- How to rebuild RPM database on a Red Hat Enterprise Linux system?
本文是笔者最近遇到的一个故障的处理过程,解决方案是Rebuild RPM 的DB,后面内容其实是REDHAT官方的solutions,不过我遇到的现象和解决方案都与官方有点出入,故一直帖出来: 我遇到 ...
- Linux命令--mysqld_safe和mysqld区别
Linux命令--mysqld_safe和mysqld区别 学习了:https://blog.csdn.net/Aaroun/article/details/78143832 mysqld_safe ...
- Linux下SVN服务器搭建(CentOS+Subversion)--转
svn(subversion)是近年来崛起的版本管理工具,是CVS的接班人.目前,绝大多数开源软件都使用svn作为代码版本管理软件.svn 服务器有2种运行方式:独立服务器和借助apache等web服 ...
- Linux学习笔记 (四)归档和压缩
一.zip压缩命令: 1.压缩文件: 格式:zip 压缩文件 源文件 例:zip abc.zip abc //将abc文件压缩到abc.zip文件内. 2.压缩目录: 格式:zip –r 压缩目录 ...
- U盘制作linux centos6.5
2015年8月4日 1.下载ULTIso软件,注册 2.DVD1的那个拖进去 3.[一定要双击那个进去]才“写入硬盘镜像”,否则只“写入‘,还是一个iso文件,不是提取出来的文件. 4.覆盖相应的文件 ...
- C语言循环中降低推断——————【Badboy】
为了让编译器更好地优化循环,应该尽量让循环中降低推断,方法之中的一个是将推断语句整合进表达式.还是这个样例: for (int i = 0; i < 1000*10; i++) { sum += ...
- 【DB2】NICKNAME报错:SQL0206N "A0.CST_NM" 在使用它的上下文中无效。 SQLSTATE=42703
1.环境展示: 2.操作描述 现在修改数据库A中CUST_INFO物理表的表结构,新增一个字段为desc varchar(100) ALTER TABLE CUST_INFO DROP COLUMN ...
- flask 框架 前端和后端请求超时问题
部署模式 flask + Gunicorn + nginx 为什么要用Gunicorn + nginx ? 请看知乎大神们的回答:https://www.zhihu.com/question/3852 ...
- 《深入理解Nginx:模块开发与架构解析》(一)
第1章 研究 Nginx 前的准备工作 1.1 Nginx 是什么 Web 服务器的基本功能:基于 REST 架构风格,以统一资源描述符(URI)或者统一资源定位符(URL),作为沟通依据,通过 HT ...