外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口来隐藏系统的复杂性 这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用
上面介绍了半天定义没明白对吧?下面简单来说 外观模式通过引入一个外观角色来简化客户端和子系统之间的交互,为复杂的子系统调用提供一个统一的接口,降低子系统和客户端的耦合度,而客户端调用非常方便
举个例子说明吧 不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶、茶具和开水,如图所示,而去茶馆喝茶,最简单的方式就是跟茶馆服务员说想要一杯什么样的茶,是铁观音、碧螺春还是西湖龙井?正因为茶馆有服务员,顾客无须直接和茶叶、茶具、开水等交互,整个泡茶过程由服务员来完成,顾客只需与服务员交互即可,整个过程非常简单省事,如图所示。
模式结构和说明
Facade:定义子系统的多个模块对外的高层接口.通常需要调用内部多个模块,从而把客户的请求代理给适当的子系统对象 模块:接受Facade对象的委派,真正实现功能,各个模块之间可能有交互.但是请注意,Facade对象知道各个模块,但是各个模块不应该知道Facade对象。
示例代码
- 定义各个模块的接口,对外提供各自的功能方法,下面我定义了三个模块AModule,BModule,CModule
@implementation AModule
- (void)testA
{
NSLog(@"test A ");
}
@end
复制代码
@implementation BModule
- (void)testB
{
NSLog(@"test B ");
}
@end
复制代码
@implementation CModule
- (void)testC
{
NSLog(@"test C ");
}
@end
复制代码
- 定义外观对象,代码如下
@implementation Facade
- (void)test
{
AModule *a = [AModule new];
[a testA];
BModule *b = [BModule new];
[b testB];
CModule *c = [CModule new];
[c testC];
}
@end
复制代码
- 客户端使用
Facade *facade = [Facade new];
[facade test];
复制代码
- 结果
模式讲解
目的
外观模式的目的不是给子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散耦合,从而让外部能够更简单的使用子系统。
使用外观跟不使用相比有何变化
看了上面的示例,很多人会有疑惑,Facade模式不就把客户端的代码移到Facade了吗?相当于再封装了一下,没什么变化啊?
没错,表面上看就是把客户端的代码搬到Facade里面了,但实质是发生了变化的,请思考:Facade到底位于何处呢?是位于客户端还是在由A、B、C模块组成的系统这边呢?
答案肯定是在系统这边,这有什么不一样吗?
当然有了,如果Facade在系统这边,那么它就相当于屏蔽了外部客户端和系统内部模块的交互,从而把A、B、C模块组合成为一个整体对外,不但方便了客户端的调用,而且封装了系统内部的细节功能,也就是说Facade与各个模块交互的过程已经是内部实现了。这样一来,如果今后调用模块的算法发生了变化,比如变化成要先调用B,然后调用A,那么只需要修改Facade的实现就可以了。
另外一个好处,Facade的功能可以被很多个客户端调用,也就是说Facade可以实现功能的共享,也就是实现复用。同样的调用代码就只用在Facade里面写一次就好了,而不用在多个调用的地方重复写。
优点
- 降低了客户类与子系统类的耦合度,实现了子系统与客户之间的松耦合关系
- 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类
- 减少了与子系统的关联对象,实现了子系统与客户之间 的松耦合关系,松耦合使得子系统的组件变化不会影响到它的客户。
- 外观模式对客户屏蔽了子系统组件,从而简化了接口,减少了客户处理的对象数目并使子系统的使用更加简单
- 引入外观角色之后,用户只需要与外观角色交互;
- 用户与子系统之间的复杂逻辑关系由外观角色来实现
- 降低原有系统的复杂度和系统中的编译依赖性,并简化了系统在不同平台之间的移植过程
因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
缺点
- 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了"开闭原则"
- 不能很好的限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性