23种设计模式之外观模式

外观模式(Facade)[fəˈsɑːd]

核心思想:为子系统中的一组接口提供一个统一的界面,Facade定义它为一个高层接口,目的是更加容易的使用这些子系统。

举个生活中的简单例子

​ 你去超市买空调,首先导购带着你进行商品选购,选定之后你带着有销售人员开好的小票去收银台结账,然后去送货处登记住址及联系方式,好让送货人员在合适的时间去上门送货安装,经过调试正常后本次购物完成。

简单分析一下这个例子。

​ 首先这个例子是一个顾客,如果是多个顾客的话,每个顾客需要按照自己的需求调用超市的各种系统,就会出现下面几个问题:

  • 每位顾客都需要了解每个子系统;
  • 一个子系统有修改,所有顾客的使用方法都会受到影响;
  • 子系统接口复杂;
  • 违反了迪米特法则

外观模式的结构

外观模式解决了客户所要使用的系统中由于子系统过多导致的客户使用复杂的情况。

外观模式的简单实战

​ 针对复杂的子系统的系统设计的设计思路就是,简化客户端代码,隔离子系统的变化,在设计时会对其进行一个外观模式的包装。

​ 继续上面的例子,顾客需要打听各个子系统的工作地点然后亲自去办理业务,这一过程比较复杂,如果这个时候有个美女带你去一步一步办理,你只需要跟着,那么这次购物就变得非常轻松了。美女了解你本次购物的所有流程,从你选购到送货上门,她就相当于把这些子系统包装起来套了个壳,我们可以理解她就是一个外观类。有了美女的帮助,本次购物相比之前没有帮助的情况产生了下面几点优势:

  • 顾客无需知道各个子系统,有美女统一服务;
  • 若其中一个子系统有改变,顾客无需修改使用方法;
  • 子系统的复杂接口被外观类简化了。

具体代码实现

/*
导购
*/
public class Saler {
    public void work(Scanner scanner){
        //售货员给出选择
        System.out.println("请输入要买的商品编号:");
        System.out.println("1.电视  2.冰箱  3.洗衣机  4.空调");
        //顾客购买
        String goodId = scanner.nextLine();
        System.out.println("感谢您购买"+goodId+"号商品");
    }
}
/*
收款子系统
 */
public class CashDesk {
    public void work(Scanner scanner){
        //收款员提示付款
        System.out.println("请付款:");
        //顾客付款
        String money = scanner.nextLine();
        System.out.println("感谢您付款"+money+"元");
    }
}
/*
注册子系统
 */
public class Register {
    public void work(Scanner scanner){
        //提示登记
        System.out.println("请输入联系电话:");
        //顾客登记
        String phone = scanner.nextLine();
        System.out.println("已录入您的电话号码:"+phone);
    }
}
/*
送货子系统
 */
public class Deliverer {
    public void work(Scanner scanner){
        //提示给出送货时间
        System.out.println("请输入送货时间:");
        //顾客给出送货时间
        String date = scanner.nextLine();
        System.out.println("送货时间:"+date);
    }
}
/*
美女外观类
*/
public class prettyGirl {
    //销售人员
    private Saler saler = new Saler();
    //收银员
    private CashDesk cashDesk = new CashDesk();
    //注册员
    private Register register = new Register();
    //送货员
    private Deliverer deliverer = new Deliverer();
    //帮助方法
    public void help(){
        System.out.println("美女说:开始购物!");
        Scanner scanner = new Scanner(System.in);
        saler.work(scanner);
        cashDesk.work(scanner);
        register.work(scanner);
        deliverer.work(scanner);
        System.out.println("美女说:购物结束!");

    }
}
/*
客户端
*/
public class Client {
    public static void main(String[] args) {
        //找到美女进行购物
        prettyGirl girl = new prettyGirl();
        girl.help();
    }
}

运行结果

总结

​ 外观模式为一组具有类似功能的类群,比如子系统等,提供了一个一致的接口,被称为Fcade, Fcade这个外观类通常会使用简单的接口来调用各个子系统来实现用户功能,用户不需要直接调用子系统而调用外观类即可。优点:

  • 隐藏了具体的实现细节,简化调用关系;
  • 使得调用的代码更加简洁明了;
  • 通过Fcade,降低了外部调用类与内部被调用类间的耦合程度;
  • 可以为每个不同的任务需要提供经过良好设计的简单接口。

应该在子系统比较复杂的情况下优先考虑外观模式简化系统的使用!

posted @ 2020-07-11 14:28  雷歌儿  阅读(191)  评论(0编辑  收藏  举报