设计模式之外观模式

为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

外观模式其实也很好理解,举个简单例子:我们去医院的话,经常要经历挂号、缴费、取药等步骤,如果有要求化验啥的,还得先去缴费,然后去化验,再回医生那边继续确诊。如果医院安排个接待员,负责帮来看病的人挂号、缴费、取药等,就方便了很多。而这个接待员即是我们要讲的外观模式。病人只需和接待员接触,不用亲自到每个部门去。

外观模式结构图

外观模式结构图

  • Facade:客户端可以调用这个角色的方法。该角色知道相关子系统的功能与责任。会将客户端发来的请求委派给相应的子系统。
  • SubSystem:可有一个或多个子系统。每个子系统可被客户端直接调用或Facade角色调用。子系统不知道Facade的存在,对于子系统来说,Facade只是另一个Client而已。

案例分析

来看一个很简单的案例。我们要取一个重要文件,文件锁在一个箱子中,箱子的钥匙被锁在另一个箱子中。我们自己来取的话需要先取第一个箱子里的钥匙,通过钥匙再去取第二个箱子的重要文件。在例子中,我们定义了一个帮手,我们只要跟他说要那个文件,剩下的就交给他了。

  1. 定义两个箱子,第一个箱子里放着钥匙,第二个箱子里放着重要文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class DrawerOne {
    public void open(){
    System.out.println("打开第一个箱子");
    getKey();
    }
    public void getKey(){
    System.out.println("得到钥匙");
    }
    }
    public class DrawerTwo {
    public void open(){
    System.out.println("打开第二个箱子");
    getFile();
    }
    public void getFile(){
    System.out.println("得到重要文件");
    }
    }
  2. 召唤帮手来,我们只要文件,怎么拿到让帮手自己去解决:

    1
    2
    3
    4
    5
    6
    7
    8
    public class Facade {
    DrawerOne one = new DrawerOne();
    DrawerTwo two = new DrawerTwo();
    public void open(){
    one.open();
    two.open();
    }
    }
  3. 这样,就可以叫帮手干活了:

    1
    2
    3
    4
    public static void main(String[] args) {
    Facade drawer = new Facade();
    drawer.open();
    }
  4. 看看活干得如何

    1
    2
    3
    4
    打开第一个箱子
    得到钥匙
    打开第二个箱子
    得到重要文件

总结

外观模式,其实就是要做的事情步骤有点繁琐或者负责,自己不想一步一步实现,于是交给一个角色来专门打理。即为一个复杂的子系统提供一个简单的接口。这样做也提高了子系统的独立性。

优点

  • 降低耦合。降低了客户端与子系统的耦合,让子系统内部模块能更容易拓展和维护。
  • 简单易用。让复杂的子系统更加容易使用。客户端不需要了解子系统的内部实现。也不需要与子系统内部模块进行交互,只要跟Facade角色进行交互即可。
  • 更好的划分访问层次。合理使用Facade角色,可以更好的划分访问层次。有些方法是对系统外的,有些是对系统内的,把需要暴露给外部的功能集中到门面中,这样既方便客户端使用也很好地隐藏了内部的细节。

缺点

  • 不能很好的限制客户使用子系统。
  • 在不引入抽象外观类的情况下,增加子系统可能需要修改外观来或客户端,违反了“开放-封闭原则”。
黄自豪 wechat
欢迎我的公众号!
如果你觉得文章对你有帮助,可点击下面的打赏按钮,支持一下!