设计模式入门之外观模式

所谓设计模式:在软件开发中,经过验证的,用于解决在特定环境下,重复出现的,特定问题解决方案.
对设计模式的理解:

  • 设计模式是解决某些问题的办法.
  • 设计模式不是凭空想象出来的,是经验的累积和总结.
  • 结构型模式:描述如何组织类和对象,以获得更大的结构.
  • 行为型模式:描述算法和对象间职责的分配.

学习设计模式第一步:准确理解每一个设计模式的功能,结构,标准实现,了解适合使用它的场景以及使用效果.
第二步:在实际开发中,尝试使用这些设计模式,并反复思考总结使用是否得当,是否需要做一些变化.


外观模式

1.场景问题

比如组装电脑,通常有两种方案:
方案1:自己去电子市场,把所需要的配件全部买回来,完后自己DIY(Do it yourself )组装.这个方案很好,但是要求你对所有的配件都比较熟悉.
在这里插入图片描述
方案2:去电子市场,找一个装机公司,告诉他所有你的要求,然后等着收电脑就行了.
在这里插入图片描述
这里的装机公司,就相当于本章的主角------外观模式.
把上面的问题抽象一下:把电子市场看成是一个系统,各种配件看成是系统中的一个个模块,就出现了下面这种问题:客户端为了完成某个功能,需要去调用系统的多个模块,把它们称为A模块,B模块,C模块.对于客户端而言,就需要知道各个模块的功能,还需要知道如何组装多个模块的功能来实现自己的功能.
要是有一个简单的方式能让客户端去实现相同的功能,这样客户端又不需要去跟多个模块交互,也不需要知道那么多模块的功能了,实现这个功能的就是Facade.


2.外观模式:

2.1定义

定义:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这一接口使得这一子系统更加容易使用.

对上面的两个词进行说明:
界面:这里的界面,主要指从一个组件的外面来看这个组件,能够看到什么,就是这个组件的界面,也就是所谓的外观.比如:从一个类的外面来看这个类,这个类的public方法就是这个类的外观,因为你从类的外部看这个类,就能看到这些.再比如:你从一个模块外看这个模块,那么这个模块对外提供的接口,就是这个模块的外观.因为你只能看到这些接口,其他模块内部实现的部分是被封装隔离了的.

接口:这里的接口并不是java中的接口interface.这里的接口,主要指的是外部和内部进行交互的一个通道,通常指定是一些方法,可以是类的方法,也可以是interface的方法.也就是说,这里所说的接口并不等价于interface,也可能是一个类.

2.2 用外观模式解决问题的思路

仔细分析上面的问题,客户端想要操作更简单一点,那么就根据客户端的要求给客户端提供一个简单的接口,让客户端来调用这个接口,其他的就不用客户端来管了.当然,这里所说的接口,指得是客户端与被访问系统的一个通道,并不一定指Java中的interface.它在外观模式里,通常指的是一个类,这个类被称为"外观".
外观模式就是通过引入这么一个外观类,在这个类里面定义客户端想要的简单的方法,然后在这些方法的实现里面,由外观类来调用内部的多个模块来实现功能,从而让客户端变得简单.客户端只需要和外观类来交互就行了.
外观模式结构如图:
在这里插入图片描述

2.3认识外观模式

外观模式的目的 :外观模式的目的不是为了给子系统增加新的功能接口,而是为了减少外部与多个子系统模块的交互,松散耦合,从而让外部系统能够更简单的使用子系统.
注意,因为外观是为了当做子系统的对外接口出现的,虽然可以定义新的功能接口,但是不建议这么做.外观应该是包含已有的功能,主要任务是结合已有功能来实现客户需求,而不是添加新的实现.

使用外观和不使用外观有什么区别?
你可能会疑问:外观模式不就是把原来客户端的代码移到了Facade里面了吗?没有什么大变化啊?
表面上看,确实如此.但是实质上是发生了的变化.请问:外观是位于客户端还是由A,B,C模块组成的系统?答案是位于系统这边.这有何不同?
不同点:

  • Facade位于系统这边,那么它就相当于屏蔽了外部客户端和内部系统模块的交互,从而把A,B,C模块组成一个整体对外,不但方便了客户端的调用,也封装了系统内部功能.以后如果所调用的系统算法发生改变,只需要修改Facade实现就可以了.
  • Facade的功能可能被多个客户端调用,也就是说Facade实现功能共享,即实现复用.同样的调用代码,只要在Facade实现一次就可以了,而不用在多个调用地方重复写.
  • 3.还一个潜在好处,对于使用Facade的人来说,Facade节约了他们的学习成本,他们只需要了解Facade类就可以了,而不需要深入了解子系统内部,各个模块的具体调用.
2.4外观模式的实现
  • 对于一个子系统而言,外观类不需要很多,通常可以实现为一个单例.也可以直接把外观中的方法定义为静态方法,这样就不需要创建外观类的实例而直接调用.这种实现相当于把外观类当成是一个工具类实现.
  • Facade可以实现为一个接口,虽然Facade通常实现为类,但是也可以实现成真正的interface.只是这样会增加系统的复杂性,因为需要一个Facade的实现,还需要一个提供Facade接口对象的工厂.此时的结构:
    在这里插入图片描述Facade实现接口的好处:能够选择性的暴露接口方法,尽量减少模块对子系统外提供的接口方法.换句话说,一个模块的接口中定义的方法可以分为两个部分:一个是给子系统外部使用,一部分是个子系统内部的模块间相互调用时使用.
    Facade模式的好处是:松散耦合,简单易用,更好的划分访问的层次.缺点是:过多或者不合理的Facade会让人迷惑,到底是使用Facade好,还是直接使用子模块好.
2.5外观模式的思考

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

对设计原则的体现:外观模式体现了"最少知识原则".
不使用外观模式,客户端需要和系统内部很多模块交互,客户端和很多模块都有依赖关系,任意一个模块改变都可能引起客户端的变动.
使用外观模式:客户端只需要和外观类交互,只和外观类这一个有依赖关系.客户端会变得简单而且系统会变得更加有弹性,系统内部多个模块发生变化时,这个变化会被外观类吸收和消化,不会影响到客户端.

什么时候使用外观模式?
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值