门面模式的理解:
设计模式中的门面模式是指当用户需要对多个子系统进行调用时,无需由用户亲自去调用各个子系统的方法,我们只需要创建一个类似于门面的类,由这个类去对子系统的各个方法进行调用,而用户只需要跟这个门面类进行交互就可以。
举个栗子:
比如淘宝美团的跑腿代购,我需要买点东西,买点菜,然后买个烧水壶,还有一袋吐司面包。。。如果没有这个跑腿代购呢,我就需要到菜市场去买才,然后转移阵地到苏宁啊国美啊之类的电器店来电烧水壶,然后再去面包店买一袋吐司面包。这样跑多麻烦呀,那么我可以叫一个跑腿的,我跟他说,我要去买这些东西,然后让他去帮我跑这些路程,这个跑腿的,就是这个门面类啦。
门面模式的结构:
门面模式没有一个一般化的类图描述,最好的描述方法实际上就是以一个例子说明。
由于门面模式的结构图过于抽象,因此把它稍稍具体点。假设子系统内有三个模块,分别是ModuleA、ModuleB和ModuleC,它们分别有一个示例方法,那么此时示例的整体结构图如下:
在这个对象图中,出现了两个角色:
● 门面(Facade)角色 :客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
● 子系统(SubSystem)角色 :可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合(如上面的子系统就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
上代码:
功能A:
public class ModelA {
//测试方法
public void testA(){
System.out.println("这是系统A功能~~~~~");
}
}
功能B:
public class ModelB {
//测试方法
public void testB(){
System.out.println("这是子系统B方法~~~~");
}
}
功能C:
public class ModelC {
//测试方法
public void testC(){
System.out.println("这是子系统的C方法~~~~~~");
}
}
门面类:
//门面类
public class Facade {
public void test(){
ModelA a = new ModelA();
ModelB b = new ModelB();
ModelC c = new ModelC();
a.testA();
b.testB();
c.testC();
}
}
客户端调用类:
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.test();
}
}
Facade类其实相当于A、B、C模块的外观界面,有了这个Facade类,那么客户端就不需要亲自调用子系统中的A、B、C模块了,也不需要知道系统内部的实现细节,甚至都不需要知道A、B、C模块的存在,客户端只需要跟Facade类交互就好了,从而更好地实现了客户端和子系统中A、B、C模块的解耦,让客户端更容易地使用系统。
使用门面模式还有一个附带的好处,就是能够有选择性地暴露方法。一个模块中定义的方法可以分成两部分,一部分是给子系统外部使用的,一部分是子系统内部模块之间相互调用时使用的。有了Facade类,那么用于子系统内部模块之间相互调用的方法就不用暴露给子系统外部了。
我们对ABC及Facade类稍作改动。
ModelA:
public class ModelA {
//测试方法
public void testA(){
System.out.println("这是系统A功能~~~~~");
}
//不想暴露i的方法
private void a(){};
}
ModelB:
public class ModelB {
//测试方法
public void testB(){
System.out.println("这是子系统B方法~~~~");
}
//不想暴露i的方法
private void b(){};
}
ModelC:
public class ModelC {
//测试方法
public void testC(){
System.out.println("这是子系统的C方法~~~~~~");
}
//不想暴露i的方法
private void c(){};
}
Facade:
//门面类
public class Facade {
ModelA a = new ModelA();
ModelB b = new ModelB();
ModelC c = new ModelC();
/**
* 给客户端提供的暴露的方法
*/
public void testA(){
a.testA();
}
public void testB(){
b.testB();
}
public void testC(){
c.testC();
}
}
一个系统可以有几个门面类
在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。当然这并不意味着在整个系统里只有一个门面类,而仅仅是说对每一个子系统只有一个门面类。或者说,如果一个系统有好几个子系统的话,每一个子系统都有一个门面类,整个系统可以有数个门面类。
门面模式的优点:
门面模式的优点:
● 松散耦合
门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。
● 简单易用
门面模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了。
● 更好的划分访问层次
通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节