为子系统提供一个统一的入口。封装子系统的复杂性,便于客户调用,常用于一些工具类的封装。
外观模式包含如下两个角色: (1) Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。 (2) SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。 具体的UML示意图如下:
下面我们通过一个启动计算机的程序来对外观模式进行一个简要的说明: 计算机的启动通常有以下的几个流程:
下面我们通过一段代码来简单模拟这个过程:
public class MyBIOS implements BIOS { @Override public void BiosCheck() { System.out.println("BIOS自检"); } } public class MyKernel implements Kernel { @Override public void run() { System.out.println("系统引导"); } } public class MySystems implements Systems { @Override public void init() { System.out.println("系统初始化"); } }
这时候如果我们需要在主程序中进行调用:
public class Client { public static void main(String[] args) { MyBIOS myBIOS=new MyBIOS(); myBIOS.BiosCheck(); MyKernel myKernel=new MyKernel(); myKernel.run(); MySystems mySystems=new MySystems(); mySystems.init(); } }
结果就是编写的代码相当的松散,这时候我们可以通过定义一个类,然后在类中将上述的代码进行包装,并向外提供一个方法来供调用者进行调用。
public class CentOS { public void start(){ MyBIOS myBIOS=new MyBIOS(); myBIOS.BiosCheck(); MyKernel myKernel=new MyKernel(); myKernel.run(); MySystems mySystems=new MySystems(); mySystems.init(); } }
这时候,我们在主程序中直接调用这个类即可。
public class Client { public static void main(String[] args) { CentOS centOS=new CentOS(); centOS.start(); } }
最后,给出项目的链接:https://github.com/memoryexplosion/design_pattern_review/tree/master/src/java/facade
