随着系统的不断改进和开发的深入,它们会变得越来越复杂,系统会生成大量的类,这使得程序更难被理解。门面模式可谓这些类提供一个简化的接口,从而简化访问这些类的复杂性,有时候这种简化可能降低访问这些底层累的灵活性,但除了要求特别苛刻的客户端之外(即调用方法的类),它通常都可以提供所需的全部功能。当然,那些苛刻的客户端仍然可以直接访问底层的类和方法。

门面(Facade)模式也被称为正面模式、外观模式,这种模式用于将一组复杂的类包装到一个简单的外部接口中。

现在考虑这样的场景:我们有一个顾客需要到饭店用餐,这就需要定义一个Customer类,并为该类定义一个haveDinner方法。假设该饭店有三个部门:收银部、厨师部和服务生部,用户就餐需要这三个部门协调才能完成。本示例程序先定义一个收银部,用户需要调用该部门的pay方法:

public class PaymentImpl implements Payment {

public String pay(double price) {

String food = "快餐";

System.out.println("您已付款:" + price + "元,购买的是:" + food);

return food;

}

}

接下来定义厨师部门:

public class CookImpl implements Cook {

public String cook(String food) {

System.out.println("厨师正在烹调:" + food);

}

}

服务生部门:

public class WaiterImpl implements Waiter {

public void serve(String food) {

System.out.println("服务员正在端菜:" + food);

}

}

接下来实现Customer类的haveDinner方法:

public class Customer {

public void haveDinner() {

//依次创建三个部门

Payment payment = new PaymentImpl();

Cook cook = new CookImpl();

Waiter waiter = new WaiterImpl();

//依次调用三个部门的不同方法

String food = payment.pay();

cook.cook(food);

waiter.serve(food);

//直接依赖于Facade类来实现用餐方法

Facade f = new Facade();

f.serveFood();

}

}

正如上面的代码所示,Customer需要依次调用三个部门的方法才能完成这个haveDinner方法,实际上,如果这个饭店有更多的部门,那么程序就需要调用更多部门的方法来实现这个haveDinner方法——这就会增加haveDinner方法的实现难度了。

为了解决这个问题,我们可以为Payment、Cook、Waiter三个部门提供一个门面(Facade),使用Facade来包装这些类,对外提供一个简单的访问方法:

public class Facade() {

//定义被封装的三个部门

Payment payment;

Cook cook;

Waiter waiter;

//构造函数

public Facade(Payment payment, Cook cook, Waiter waiter) {

this.payment = payment;

this.cook = cook;

this.waiter = waiter;

}

public void serveFood() {

String food = payment.pay();

cook.cook(food);

waiter.serve(food);

}

}

从Facade代码可以看出,该门面保证了Payment,Cook和Waiter三个部门,程序对外提供了一个简单的serveFood方法,该方法对外提供了一个用餐的方法,而底层则依赖于三个部门的pay(),cook(),serve()三个方法。一旦程序提供了这个门面类Facade后,Customer类实现haveDinner方法就变得更加简单了,下面是通过Facade类实现的haveDinner方法:

public void haveDinner() {

Facade f = new Facade();

f.serveFood();

}

从上面的结构可以看出,如果不采用门面模式,客户端需要自行决定需要调用哪些类、哪些方法,并需要按合理的顺序来调用它们才能实现所需的功能。不采用门面模式时,程序有如图所示的结构:

然而,使用了门面模式之后,客户端代码只需要和门面类进行交互即可,于是,程序结构图变成了如下样式:

其实,Spring的HibernateTemplate类就是使用的门面模式:当我们的程序使用Hibernate的find()方法时,程序只要一行代码即可得到查询返回的List。但实际上该find()方法后隐藏了如下代码:

Session session = sf.openSession();

Query query = session.createQuery(hql);

for(int i=0; i

query.setParameter(i, args[i]);

}

query.list();

因此我们可以认为HibernateTemplate是SessionFactory,Session、Query等类的门面。当客户端程序需要进行持久化查询时,程序无需调用这些类,而是直接调用HibernateTemplate门面类中的相印方法即可。

除此之外,JavaEE应用里使用业务逻辑组件来封装DAO组件也是典型的门面模式——每个业务逻辑组件(一般是Service层)都是众多DAO组件的门面,系统的控制器类无需直接访问DAO组件,而是由业务逻辑方法来组合多个DAO方法以完成所需功能。而Action只需与业务逻辑组件交互即可。

php门面设计模式,经典设计模式——门面模式相关推荐

  1. 门面设计模式php,学习php设计模式 php实现门面模式(Facade)

    这篇文章主要介绍了php设计模式中的门面模式,使用php实现门面模式,感兴趣的小伙伴们可以参考一下 一.意图 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层次的接口,使得子系统 ...

  2. .net 有哪些主流的设计模式_「设计模式自习室」门面模式 Facade Pattern

    前言 <设计模式自习室>系列,顾名思义,本系列文章带你温习常见的设计模式.主要内容有: 该模式的介绍,包括: 引子.意图(大白话解释) 类图.时序图(理论规范) 该模式的代码示例:熟悉该模 ...

  3. 【设计模式自习室】门面模式 Facade Pattern

    前言 <设计模式自习室>系列,顾名思义,本系列文章带你温习常见的设计模式.主要内容有: 该模式的介绍,包括: 引子.意图(大白话解释) 类图.时序图(理论规范) 该模式的代码示例:熟悉该模 ...

  4. java策略模式详解_Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式 ...

  5. 经典伴读_GOF设计模式_结构型模式

    经典伴读系列文章,不是读书笔记,自己的理解加上实际项目中运用,旨在5天读懂这本书.如果这篇文章对您有些用处,请点赞告诉我O(∩_∩)O. 如何使用设计模式抽象实例化过程.请参考<经典伴读_GOF ...

  6. 设计模式之委派模式(不属于23种经典设计模式之一)

    介绍 标准定义:委派模式的原理为类B和类A是两个互相没有任何关系的类,B具有和A一模一样的方法和属性,并且调用B中的方法.属性就是调用A中同名的方法和属性.B好像就是一个受A授权委托的中介.第三方的代 ...

  7. 简易理解设计模式之:桥接模式——穿衣服经典案例2

    介绍: 桥接模式属于结构型模式.它的定义为:将抽象部分与实现部分分离,使它们都可以独立的变化. 类图: Abstraction(抽象化角色):抽象部分,保持对实现部分对象的引用,抽象部分中的方法需要调 ...

  8. Java 经典设计模式-- 03.结构型模式

    前言 书接上文,上一篇中创建型设计模式中的常用设计模式做了简单的介绍,本篇将继续对结构型设计模式中的常用模式进行介绍与分析. 目录: 适配器模式 桥接模式 组合模式 修饰模式 代理模式 简单提及: M ...

  9. 23种经典设计模式都有哪些,如何分类?Java设计模式相关面试

    23种经典设计模式都有哪些,如何分类? 23种经典设计模式都有哪些,如何分类? java常用的设计模式?说明工厂模式 Java 中的23 种设计模式: Factory(工厂模式), Builder(建 ...

最新文章

  1. 揭开神秘的“记忆”面纱!
  2. SDWebImage 在Swift中遇坑解决
  3. 使用OpenGL一年后
  4. 让linux系统做网关,代理上网!!!
  5. android layer阴影,Android Layer-List实现自定义Shape阴影
  6. RabbitMQ-Failed to check/redeclare auto-delete queue(s).
  7. FreeSWITCH黑名单功能设置
  8. HDOJ(HDU) 2097 Sky数(进制)
  9. robotium3.6与4.0以后的区别
  10. 基于 HttpClient 4.5 的 HttpClientUtils
  11. 微信模拟地理位置_微信伪装地理位置是什么个原理
  12. MySQL分库分表及中间件Mycat
  13. 随意切换双卡流量,立即获取对应卡的SMIS
  14. PDF文件转换文件格式
  15. 前端实习工作找不到,怎么增长实战经验
  16. 如何将Word中数据转换为excel表格
  17. ALESA切削刀具1355.3904-01
  18. Mysql、Oracle、DM、Tbase数据库差异性
  19. 价值100亿美元!微软刚刚击败亚马逊,拿下美国国防部十年云计算基建订单
  20. windows10安装Sql server 2000

热门文章

  1. BIOS介绍及其设置
  2. 基于SSH开发学生公寓管理系统
  3. Adreno OpenGL ES 3.1 介绍(3)
  4. 国产数据库DM7与DM6最明显的区别
  5. 安装Cloudera manager Server步骤详解
  6. 织梦(dedecms)仿站教程第一讲-准备工作
  7. 水果店收入,水果店年收入多大
  8. 贝塞尔函数(原理与实现)
  9. MATLAB simulink 仿真步长
  10. 解决pycharm汉化后无法打开设置