设计模式学习笔记------外观模式
外观模式
一、外观模式
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式结构示意图
二、代码实例
1 /** 2 * A模块接口 3 * @author abc 4 * 5 */ 6 public interface AModule { 7 public void testA(); 8 } 9 10 /** 11 * A模块接口实现类 12 * @author abc 13 * 14 */ 15 public class AModuleImpl implements AModule { 16 17 @Override 18 public void testA() { 19 System.err.println("实现AModule"); 20 } 21 22 } 23 24 /** 25 * B模块接口 26 * @author abc 27 * 28 */ 29 public interface BModule { 30 public void testB(); 31 } 32 33 /** 34 * B模块接口实现类 35 * @author abc 36 * 37 */ 38 public class BModuleImpl implements BModule { 39 40 @Override 41 public void testB() { 42 System.err.println("实现BModule"); 43 } 44 45 } 46 47 /** 48 * C模块接口 49 * @author abc 50 * 51 */ 52 public interface CModule { 53 public void testC(); 54 } 55 56 /** 57 * C模块接口实现类 58 * @author abc 59 * 60 */ 61 public class CModuleImpl implements CModule { 62 63 @Override 64 public void testC() { 65 System.err.println("实现CModuel"); 66 } 67 68 } 69 70 /** 71 * 外观对象 72 * @author abc 73 * 74 */ 75 public class Facade { 76 77 /** 78 * 示意方法,满足用户需求 79 */ 80 public void test() { 81 //在内部实现会调用到的子系统的模块 82 AModule a = new AModuleImpl(); 83 a.testA(); 84 BModule b = new BModuleImpl(); 85 b.testB(); 86 CModule c = new CModuleImpl(); 87 c.testC(); 88 } 89 90 public static void main(String[] args) { 91 Facade facade = new Facade(); 92 facade.test(); 93 } 94 }
三、理解外观模式
外观模式的目的
外观模式的目的不是给子系统添加新的功能接口,而是让外部减少与子系统内多个模块的交互,松散耦合,从而让外部能够更简单地使用子系统。
使用外观和不适用外观有和变化
外观属于系统,它可以屏蔽外部客户端和系统内部模块的交互,从而把子模块(A,B,C...)成为一个整体对外,不但方便客户端的调用,而且封装了系统内部的细节功能。也就是说Facade与各个模块交互的过程已经是内部实现了。这样一来,如果今后调用模块的算法发生了变化,比如变化成要先调用B,然后在调用A,那么只需要修改Facade的实现就可以了。
有外观,但是可以不使用
虽然有了外观,如果有需要,外部还是可以绕开Facade,而直接调用摸个具体模块的接口,这样就能实现兼顾组合功能和细节功能。
外观提供了缺省的功能实现
外观对象可以为用户提供一个简单、缺省的实现,这个实现对大多数的用户来说都已经足够了。但是外观并不限制那些需要更多制定功能的用户,可以直接越过外观去访问内部模块的功能。
外观模式的调用顺序示意图
四、外观模式的优缺点
优点:
松散耦合
外观模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。
简单易用
外观模式让子系统更加易用,客户端不在需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟外观交互就可以,相当于外观类为外部客户端使用子系统提供了一站式服务。
更好地划分访问的层次
通过合理的使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到外观中,这样既方便客户端使用,也很好的隐藏了内部的细节。
缺点:
过多的或者是不太合理的Facade也容易让人迷惑。到底是调用Facade好呢,还是直接调用模块好。