以下只是个人的一些理解,可能有一些错误或者误解,不建议根据本文来了解设计模式,如果要学习设计模式的话,还是建议找专业书籍资料学习。
01门面模式(外观模式)
引出
如果一个项目中有多个子系统,客户需要使用多个子系统中的某些功能,如果不使用门面模式的话就可能造成这种情况,用户与多个子系统之间打交道,造成了系统与用户之间的耦合过高。
图一


图二
但是如果使用了门面模式这种局面就会得以改善,使得用户和各个子系统之间的耦合度降低。

以下是代码实现。
代码(不使用门面模式)
A子系统
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * A子系统 6 * @date 2022/7/28 - 17:14 7 */ 8 public class A { 9 10 public void a() { 11 System.out.println("执行了A类中的a方法"); 12 } 13 14 public void b() { 15 System.out.println("执行了A类中的b方法"); 16 } 17 }
B子系统
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * B子系统 6 * @date 2022/7/28 - 17:15 7 */ 8 public class B { 9 public void a() { 10 System.out.println("执行了B类里的a方法"); 11 } 12 13 public void b() { 14 System.out.println("执行了B类里的b方法"); 15 } 16 }
C子系统
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * C子系统 6 * @date 2022/7/28 - 17:16 7 */ 8 public class C { 9 public void a() { 10 System.out.println("执行了C类里的a方法"); 11 } 12 13 public void b() { 14 System.out.println("执行了C类里的b方法"); 15 } 16 }
用户
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * @date 2022/7/28 - 17:36 6 */ 7 public class User { 8 /** 9 * 看作是用户 10 * @param args 11 */ 12 public static void main(String[] args) { 13 new A().a(); 14 new B().a(); 15 new C().a(); 16 } 17 /** 18 * 输出结果 19 * 执行了A类中的a方法 20 * 执行了B类里的a方法 21 * 执行了C类里的a方法 22 */ 23 }
结论:可以看到虽然成功调用了子系统中的方法,但是是通过直接获取子系统中方法所在的类的对象直接调用的,因此就会产生图一的情况。
代码(使用门面模式)
创建门面类DoorFace
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * @date 2022/7/28 - 17:18 6 */ 7 public class DoorFace { 8 public void a(){ 9 new A().a(); 10 new A().b(); 11 new B().a(); 12 new B().b(); 13 new C().a(); 14 new C().b(); 15 } 16 }
修改User类
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * @date 2022/7/28 - 17:36 6 */ 7 public class User { 8 /** 9 * 当前用户 10 */ 11 public void a() { 12 new DoorFace().a(); 13 } 14 } 15 16 package designMode.facadeMode; 17 18 /** 19 * @author littstone 20 * @date 2022/7/28 - 17:36 21 */ 22 public class User { 23 /** 24 * 当前用户 25 */ 26 public static void main(String[] args) { 27 new DoorFace().a(); 28 } 29 /** 30 * 执行了A类中的a方法 31 * 执行了A类中的b方法 32 * 执行了B类里的a方法 33 * 执行了B类里的b方法 34 * 执行了C类里的a方法 35 * 执行了C类里的b方法 36 */ 37 }
结论:可以看到用户并没有通过直接调用子系统中的方法,而是通过了一个媒介——门面类就完成了因要实现的功能。至于与子系统打交道就交给了门面类来做了。因此也实现了图二的效果。
优点其一(选择性暴漏)
问题:如果还是未使用门面类用户直接调用子系统中的方法,那么用户就可以看到当前子系统中的所有方法(public),但是有些方法是子系统之间来交流的,这些方法不能够被用户所看到。要实现用户只能看到当前类中的一部分这个要求,可以借助门面模式来实现。
实现
修改FaceDoor类
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * @date 2022/7/28 - 17:18 6 */ 7 public class DoorFace { 8 /** 9 * 选择性的调用各个子系统中的方法,如果某些方法不希望用户看到 10 * 就可以不在门面类里面调用这个方法。 11 */ 12 public void a(){ 13 new A().a(); 14 new B().a(); 15 new C().a(); 16 } 17 }
User类
1 package designMode.facadeMode; 2 3 /** 4 * @author littstone 5 * @date 2022/7/28 - 17:36 6 */ 7 public class User { 8 /** 9 * 当前用户 10 */ 11 public static void main(String[] args) { 12 new DoorFace().a(); 13 } 14 /** 15 * 执行了A类中的a方法 16 * 执行了B类里的a方法 17 * 执行了C类里的a方法 18 */ 19 }
结论:可以看到即使User类没有丝毫改变,但是调用的结果却发生了变化,这样就可以实现选择性暴漏子系统中的方法,提高了一些安全性也不至于调出太多的方法导致用户产生困惑。
使用场景
1:子系统的功能逐渐增多,需要提供一个接口简化方法的调用。
2:构建多层系统设计,可以使用门面模式来作为每层的入口。
---end---
浙公网安备 33010602011771号