我们先来讨论一个很常见的问题。
餐馆吃饭的问题。
在有些餐馆,客人进去吃饭是需要自己找座位,自己倒茶,自己写菜单,然后将菜单交给服务员,由服务员去完成剩下的工作。
但是也有很多那种高级的餐厅,或者服务很周到的餐厅是这样做的,你一进门,就会有服务员领着你到给你安排座位(我们现在假设安排座位是专门一个部门来完成的,只是这个服务员直接问了座位部那些座位是空的,然后领着去对应的地方就可以了)。然后你坐下之后服务员给你端茶倒水(茶水有茶水部门来负责泡茶,烧水之类的),然后你告诉服务员我现在要吃什么菜,服务员帮你写下菜单就可以了。
如果是这样的话,你每次吃饭是不是会心里很爽呢?对啊,你什么也没有做,都是服务员帮你完成的,你完全没有自己去找座位,自己去倒茶,自己写菜单。
这就是门面模式的定义:将有顺序的,有规律的,事情交给一个门面来做。
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,门面模式提供一个高层次的接口,使得子系统更容易使用。这是它的官方定义。那么我们来看看怎么实现它呢。
BoardDepartment 这是管理座位的部门
package com.gengu.门面模式; /** * 座位系统 * 帮助用户找座位 * */ public class BoardDepartment { //给客人找空位 public void providBoard(){ System.out.println("给客人分配座位号为"+new java.util.Random().nextInt(100)); } }
TeaDepartment 管理负责茶水的部门
package com.gengu.门面模式; /** * 茶水部 * 专门负责给人提供茶水 * */ public class TeaDepartment { //提供茶水 public void Provide(){ System.out.println("给客人提供乌龙茶"); } }
package com.gengu.门面模式; /** * 帮客人完成菜单 * 菜单部门 * */ public class MenuDepartment { //给客人找空位 public void providMenu(String message){ System.out.println("客人点的菜是"+message); //doSomeThing } }
下面是门面模式的核心,Facade 客户端可以调用这个角色的方法,此角色直销子系统的所有功能和责任,一般情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去,也就是上面的相关部门。
package com.gengu.门面模式; /** * 门面模式的 * 这是餐厅的一个侍者 * 他负责帮客人端茶递水,找座位,写菜单之类的操作 * */ public class Waiter { BoardDepartment boardDepartment = new BoardDepartment(); TeaDepartment teaDepartment = new TeaDepartment(); MenuDepartment menuDepartment = new MenuDepartment(); //帮助客人 public void helpCustomer(String message){ boardDepartment.providBoard(); teaDepartment.Provide(); menuDepartment.providMenu(message); } }
下面是客户端
package com.gengu.门面模式; public class Client { public static void main(String[] args) { Waiter waiter = new Waiter(); waiter.helpCustomer("鱼香肉丝"); } }
客户端要做的事情非常少,就是仅仅完成说出是什么菜就完成了,剩下的一切都由门面模式来完成了。