门面模式的结构
门面(Facade)角色 :客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
子系统(SubSystem)角色 :可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合(如上面的子系统就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
门面(Facade)角色 :客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
子系统(SubSystem)角色 :可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合(如上面的子系统就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
也就是说,本来应该客户端来跟各个子系统来接触,但是有了门面模式之后,客户端有什么操作只需要跟门面来打交道,告诉门面类,下面的事情就交给门面来来做,来门面类负责跟各个子系统打交道,可以这样理解,公司里面,并不是什么事都是董事长亲自出来跟基层各个部门打交道的,它会跟总经理打交道,把任务下达给总经理,剩下的事就是总经理来做了,由总经理来把事情分配给各个部门。这里总经理就起到门面的作用了。
使用门面模式:
不使用门面模式:
子系统角色中的类:
public class ModuleA {
//示意方法
public void testA(){
System.out.println("调用ModuleA中的testA方法");
}
}
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();
}
}
Android中的门面模式
Context是最重要的一个类型。它封装了很多重要的操作,比如startActivity()、sendBroadcast()等,几乎是开发者对应用操作的统一入口。Context是一个抽象类,它只是定义了抽象接口,真正的实现在ContextImpl类中。它就类似于门面类。
另外在Android里面我们往往会写各种各样的工具来,这些工具类可以帮我们完成各种各样的操作或者帮我们获取到各种各样的信息,它也相当于一个门面类,使用了门面模式,我们需要什么操作直接调用就可以,它屏蔽了底层的实现。
优点与缺点
优点
使用方便,使用外观模式客户端完全不需要知道子系统的实现过程;
降低客户端与子系统的耦合;
更好的划分访问层次;
缺点
减少了可变性和灵活性;
在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”;
参考文章: