定义:外观模式是软件工程中常用的一种软件设计模式。它为子系统中的一组接口提供一个统一的高层接口。这一接口使得子系统更加容易使用。

该定义引自百度百科,它的表现很简单,将一系列子接口的功能进行整理,从而产生一个更高层的接口。

相信做JAVA的各位大部分是WEB开发,那么肯定都对XXXDao,XXXService非常熟悉了,这显然和外观模式有一腿。当然,还有一大部分是android开发,LZ没接触过android开发,但是LZ大胆的想象,在移动领域的JAVA开发,应该也有类似的情况发生。

接下来,我们来看看外观模式的标准类图。

上述便是外观模式的类图,它主要由两部分组成,一部分是子系统(包括接口,实现类,等等),一部分是外观接口和实现类,外观接口负责提供客户端定制的服务,外观实现则负责组合子系统中的各个类和接口完成这些服务,外观接口则是提供给客户端使用的,这样就解除了客户端与子系统的依赖,而让客户端只依赖于外观接口,这是一个优秀的解耦实践。

下面LZ依然使用JAVA代码将上述的类图诠释出来,我们来直观的看看外观模式的实现方式。首先是我们的子系统,它包括三个接口,三个实现,LZ这里一并给出。

package com.facade;public interface Sub1 {void function1();}

package com.facade;public interface Sub2 {void function2();}

package com.facade;public interface Sub3 {void function3();}

package com.facade;public class Sub1Impl implements Sub1{public void function1() {System.out.println("子系统中Sub1接口的功能");}}

package com.facade;public class Sub2Impl implements Sub2{public void function2() {System.out.println("子系统中Sub2接口的功能");}}

package com.facade;public class Sub3Impl implements Sub3{public void function3() {System.out.println("子系统中Sub3接口的功能");}}

以上便是我们模拟出的一个子系统,那么现在便是我们最重要的接口出场的时候了,LZ给出Facade以及它的简单实现。

package com.facade;public interface Facade {/*  下面随便组装几个功能  */void function12();void function23();void function123();}

package com.facade;public class FacadeImpl implements Facade{private Sub1 sub1;private Sub2 sub2;private Sub3 sub3;public FacadeImpl() {super();this.sub1 = new Sub1Impl();this.sub2 = new Sub2Impl();this.sub3 = new Sub3Impl();}public FacadeImpl(Sub1 sub1, Sub2 sub2, Sub3 sub3) {super();this.sub1 = sub1;this.sub2 = sub2;this.sub3 = sub3;}public void function12() {sub1.function1();sub2.function2();}public void function23() {sub2.function2();sub3.function3();}public void function123() {sub1.function1();sub2.function2();sub3.function3();}}

以上便是我们的外观接口和实现类,它当中的功能一般是根据是客户端的需要定制的,将客户端的一个完整功能作为一个行为,然后调用子系统完成。下面我们看看客户端的调用。

package com.facade;public class Client {public static void main(String[] args) {Facade facade = new FacadeImpl();facade.function12();System.out.println("-------------------------");facade.function23();System.out.println("-------------------------");facade.function123();/*  以上为使用了外观模式的调用方式,以下为原始方式   */System.out.println("-------------以下原始方式--------------");Sub1 sub1 = new Sub1Impl();Sub2 sub2 = new Sub2Impl();Sub3 sub3 = new Sub3Impl();sub1.function1();sub2.function2();System.out.println("-------------------------");sub2.function2();sub3.function3();System.out.println("-------------------------");sub1.function1();sub2.function2();sub3.function3();}}

LZ在下面还给出了原始的调用方式,可以看出在外观模式的作用下,我们客户端只依赖外观一个接口,而在原始的方式下,我们的客户端依赖于整个子系统,所以外观模式主要解决的是类之间的耦合过于复杂。

附上LZ运行结果。

以上便是标准的外观模式展现,LZ下面再给出需要知晓的几点。

1,实际使用当中,接口并不是必须的,虽说根据依赖倒置原则,无论是处于高层的外观层,还是处于底层的子系统,都应该依赖于抽象,但是这会倒置子系统的每一个实现都要对应一个接口,从而导致系统的复杂性增加,所以这样做并不是必须的。

                     2,外观接口当中并不一定是子系统中某几个功能的组合,也可以是将子系统中某一个接口的某一功能单独暴露给客户端。

                     3,外观接口如果需要暴露给客户端很多的功能的话,可以将外观接口拆分为若干个外观接口,如此便会形成一层外观层。

上述LZ给出的第三点,便是为了引出我们标题当中的service,相信各位做过web开发的都见过我们项目中很多的service和dao(注:小型项目或许不需要service这一层),这一层service层,有一个非常重要的作用,就是为了方便我们管理项目中与业务逻辑相关的事物,而service层,其实是给我们的事务管理器提供了一个可以方便的配置切入点的事物管理层。

除了上述这个重要的功能外,service层同时也是组合dao层暴露给action的功能,dao层的各个类只是简单的数据操作对象,它们不具有业务逻辑,而赋予了它们业务逻辑方便action调用的功臣,正是service这一层。各位可以想象一下,假设没有service这一层,你的action当中有很多功能需要依赖多少个dao才可以完成工作。

同时在WEB项目中,有的项目会抽象出一层service接口和一层dao接口,这是为了降低客户端(这里的客户端可以认为是action)与业务实现细节以及service外观层与数据操作实现细节的耦合,而有的项目则没有抽象层,这也并非就是不合适的。

首先添加抽象层会大大的加剧项目的类文件数量,从而使项目的复杂性增加,而且在项目刚进入开发的时候,往往接口是不稳定的,因为我们经常会需要要给某一个service添加一个方法,而为了将方法暴露给客户端(即action),我们必须将该方法添加到对应的接口当中。

所以针对这一情况,我们更好的做法是等到接口行为相对稳定时,再考虑是否要重构去添加抽象的接口,而且现在的IDE工具都在一定程度上对重构进行了支持,比如eclipse就可以直接导出一个类的接口,所以我们完全可以在需要时快速的给项目添加抽象的接口层。

相比起观察者模式,适配器模式等适合小规模使用的设计模式,外观模式更多的是大范围的使用,它会是很多时候支撑我们整个架构的设计思路

鉴于此,LZ此处不再给出具体的service和dao的示例,各位的项目中到处都充斥着这种例子。

转载于:https://www.cnblogs.com/2019lgg/p/11090472.html

十一:外观模式详解(Service,action与dao)相关推荐

  1. 设计模式之外观模式详解(附应用举例实现)

    文章目录 1 外观模式概述 2 外观模式详解 2.1 外观模式结构 2.2 外观模式实现 2.3 外观模式应用举例 3 抽象外观类 1 外观模式概述 在软件开发中,有时候为了完成一项较为复杂的功能,一 ...

  2. 设计模式——外观模式详解

    0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...

  3. (二十一)状态模式详解(DOTA版) - 转

    作者:zuoxiaolong8810(左潇龙),转载请注明出处. 本次LZ给各位介绍状态模式,之前在写设计模式的时候,引入了一些小故事,二十章职责连模式是故事版的最后一篇,之后还剩余四个设计模式,LZ ...

  4. Android  Doze and App Standby模式详解

    Android  Doze and App Standby模式详解 来源:腾云阁 https://www.qcloud.com/community Optimizing for Doze and Ap ...

  5. 设计模式之门面模式详解

    设计模式之门面模式详解 文章目录 设计模式之门面模式详解 一.什么是门面模式 二.门面模式的应用场景 三.门面模式的角色组成 四.门面模式通用写法 五.门面模式在业务中的应用 六.门面模式优缺点 一. ...

  6. Android M新特性Doze and App Standby模式详解

    转载请标明出处:http://blog.csdn.net/xx326664162/article/details/52312122 文章出自:薛瑄的博客 你也可以查看我的其他同类文章,也会让你有一定的 ...

  7. 代理模式详解(静态代理和动态代理的区别以及联系)

    原文链接:https://www.cnblogs.com/takumicx/p/9285230.html 1. 前言 代理模式可以说是生活中处处可见.比如说在携程上定火车票,携程在这里就起到了一个代理 ...

  8. iOS里面MVC模式详解

    iOS里面MVC模式详解 MVC是IOS里面也是很多程序设计里面的一种设计模式,M是model,V是view,C是controller.MVC模式在ios开发里面可谓是用得淋漓尽致. 以下是对斯坦福大 ...

  9. C#中的递归APS和CPS模式详解(转载)

    这篇文章主要介绍了C#中的递归APS和CPS模式详解,本文讲解了累加器传递模式.CPS函数.CPS变换.CPS尾递归.尾递归与Continuation等内容,需要的朋友可以参考下 累加器传递模式(Ac ...

最新文章

  1. NFV — 安全策略
  2. datalist,Repeater和Gridview的区别分析
  3. linux进程接受信号,linux – 一个进程如何知道它已经收到一个信号
  4. Delegate(QLabel和QComboBox)
  5. 前端学习(1420):ajax的post请求
  6. kindeditor编辑器图片上传session丢失_微信公众号排版编辑器全指南!
  7. linux知识点查阅
  8. python跟java适用专业_javaweb中java和python混合使用
  9. Windows下使用C++(Win32SDK)编程无需提权读取硬盘序列号(XP、Win7和Win10都可用)
  10. 看流畅的python感觉有难度_读《流畅的Python》有感
  11. 如何在Java项目中定义并调用自己编写的native方法?
  12. 数组与集合的区别(概况)
  13. 数据的预处理——平滑处理
  14. 2.try、catch、finally执行顺序 以及final、finally和finalize的区别
  15. 高效程序员的7个技能
  16. 通讯:春运中的墨西哥“乘务员”
  17. 5V和USB供电 的隔离电路
  18. Pycharm导入同级目录模块解决办法汇总
  19. 人口只有北京的1/3,这个国家创立了全球一半的科技公司
  20. linux高手知乎,配置一个简洁高效的 Zsh | Linux 中国

热门文章

  1. 《数学之美》第12章 有限状态机—地图与本地搜索的核心技术
  2. python中字符串前面加一个u或者r的区别
  3. “厌氧动物”出现,科学家不清楚代谢方式,或颠覆对生命的认知
  4. 鸿蒙系统全面解析,诞生背景、技术细节生态圈一文看懂
  5. 中国AI芯片产业发展白皮书:未来三年年均增长率超50%
  6. 交换机与路由器大战已结束,超大规模计算公司胜出
  7. 能源枯竭?在能源互联网时代不存在!
  8. 自定义注解!绝对是程序员装大佬的利器!!
  9. Unity “出圈”:游戏引擎的技术革新和跨界商机
  10. 使用this.$router.push('')的方法进行路由跳转,提示'$router' of undefined问题