门面模式
门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用;
举一个医院的例子,医院里面有很多的小部门,包括门诊,挂号,取药,划价等等,而病人就得一个个地问啊,一个个去报答,而病人本来身体就不舒服了,你要他去折腾这些,所以,门面模式就出现了,门面模式就相当于一个接待员的位置,由接待员负责代为挂号,划价,缴费,取药,而病人只需要跟接待员说一声就好了,接待员更加了解医院里面的系统逻辑,由接待员与各个部门打交道;
门面模式的角色:
门面角色:客户端可以调用这个角色的方法。此角色知晓相关的子系统的功能和责任,在正常情况下,本角色会将所有从客户端发来的请求委托到相应的子系统去。
子系统角色:可以同时有一个或者多个子系统,每个子系统都不是单独的类,而是一个类的集合,每个子系统都可以被客户端直接调用,或者被门面角色调用,子系统并不知道门面的存在,对于子系统而言,门面仅仅只是另外一个客户端而已;
子系统角色:
public class ModuleB { //示意方法 public void testB(){ System.out.println("调用ModuleB中的testB方法"); } }
public class ModuleB { //示意方法 public void testB(){ System.out.println("调用ModuleB中的testB方法"); } }
public class ModuleC { //示意方法 public void testC(){ System.out.println("调用ModuleC中的testC方法"); } }
门面角色:
public class Facade { //示意方法,满足客户端需要的功能 public void test(){ ModuleA a = new ModuleA(); a.testA(); ModuleB b = new ModuleB(); b.testB(); ModuleC c = new ModuleC(); c.testC(); } }
客户端角色:
public class Client { public static void main(String[] args) { Facade facade = new Facade(); facade.test(); } }
这样的话,客户端只需要调用一个接待员对象的方法,就可以变相地调用所有的方法了。
使用门面模式还有一个附带的好处,就是能够有选择性地暴露方法,一个模块中定义的方法可以分成两部分,一部分是给子系统外部使用的,一部分是 子系统内部模块之间相互调用时使用的,有了Facade类,那么用于子系统内部模块之间相互调用的方法就不用暴露给子系统外部了。
public class Module { /** * 提供给子系统外部使用的方法 */ public void a1(){}; /** * 子系统内部模块之间相互调用时使用的方法 */ public void a2(){}; public void a3(){}; }
public class ModuleB { /** * 提供给子系统外部使用的方法 */ public void b1(){}; /** * 子系统内部模块之间相互调用时使用的方法 */ public void b2(){}; public void b3(){}; }
public class ModuleB { /** * 提供给子系统外部使用的方法 */ public void b1(){}; /** * 子系统内部模块之间相互调用时使用的方法 */ public void b2(){}; public void b3(){}; }
public class ModuleFacade { ModuleA a = new ModuleA(); ModuleB b = new ModuleB(); ModuleC c = new ModuleC(); /** * 下面这些是A、B、C模块对子系统外部提供的方法 */ public void a1(){ a.a1(); } public void b1(){ b.b1(); } public void c1(){ c.c1(); } }
门面模式的优点:
松散耦合:
门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护;
简单易用:
门面模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了,
更好的划分访问层次:
可以帮助我们更好地划分访问的层次,有些方法是对系统外的,有些方法是系统内部使用的,把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节;