• 设计模式之外观模式(Facade)详解及代码示例


    一、外观模式的定义

      外观(Facade)模式的定义:又叫门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

    二、外观模式优缺点

      优点:

    • 简化了调用过程,无需了解深入子系统,防止带来风险
    • 减少系统依赖、松散耦合
    • 更好的划分访问层次
    • 符合迪米特法则,即最少知道原则

      缺点:

    • 增加子系统、扩展子系统行为容易引入风险
    • 不符合开闭原则

    三、外观模式的实现

      外观(Facade)模式的结构比较简单,主要是定义了一个高层接口。它包含了对各个子系统的引用,客户端可以通过它访问各个子系统的功能。现在来分析其基本结构和实现方法。

      外观(Facade)模式包含以下主要角色。

    • 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
    • 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
    • 客户(Client)角色:通过一个外观角色访问各个子系统的功能。

      其结构图如图所示:

                  

      代码常见有两种情况都是属于外观模式,如下代码:

      所有子系统实现统一接口:

    public interface System {
        public void dosomething();
    }
    
    public class SubSystemA implements System {
    
        public void dosomething() {
            System.out.println("子系统方法A");
        }
    }
    
    public class SubSystemB implements System {
    
        public void dosomething() {
            System.out.println("子系统方法B");
        }
    }
    
    public class Facade {
    
        //被委托的对象
        System a,b;
        
        public Facade() {
            a = new SubSystemA();
            b = new SubSystemB();
        }
        
        //提供给外部访问的方法
        public void methodA() {
            this.a.dosomething();
        }
        
        public void methodB() {
            this.b.dosomething();
        }
    }
    
    public class Client {
    
        public static void main(String[] args) {
            Facade facade = new Facade();
            
            facade.methodA();
            facade.methodB();
        }
    }

      所有子系统未实现统一接口:

    public class SubSystemA {
    
        public void dosomethingA() {
            System.out.println("子系统方法A");
        }
    }
    
    public class SubSystemB {
    
        public void dosomethingB() {
            System.out.println("子系统方法B");
        }
    }
    
    public class Facade {
    
        //被委托的对象
        SubSystemA a;
        SubSystemB b;
        
        public Facade() {
            a = new SubSystemA();
            b = new SubSystemB();
        }
        
        //提供给外部访问的方法
        public void methodA() {
            this.a.dosomethingA();
        }
        
        public void methodB() {
            this.b.dosomethingB();
        }
    }
    
    public class Client {
    
        public static void main(String[] args) {
            Facade facade = new Facade();
            
            facade.methodA();
            facade.methodB();
        }
    }

      测试结果如下:

    子系统方法A
    子系统方法B

    四、外观模式的应用场景

      通常在以下情况下可以考虑使用外观模式。

    • 子系统越来越复杂,增加外观模式提供简单接口调用
    • 构建多层系统结构,利用外观对象作为每层的入口,简化层间调用

    五、外观模式的扩展

      在外观模式中,当增加或移除子系统时需要修改外观类,这违背了“开闭原则”。如果引入抽象外观类,则在一定程度上解决了该问题,其结构图如图所示:
               

      代码如下:

    public class FacadePattern
    {
        public static void main(String[] args)
        {
            Facade f=new FacadeImpl1();
            f.method();
            f=new FacadeImpl2();
            f.method();
        }
    }
    
    interface Facade {
        public void method();
    }
    
    //外观角色
    class FacadeImpl1 implements Facede
    {
        private SubSystem01 obj1=new SubSystem01();
        private SubSystem02 obj2=new SubSystem02();
        private SubSystem03 obj3=new SubSystem03();
        public void method()
        {
            obj1.method1();
            obj2.method2();
            obj3.method3();
        }
    }
    //外观角色
    class FacadeImpl1 implements Facede
    {
        private SubSystem02 obj2=new SubSystem02();
        private SubSystem03 obj3=new SubSystem03();
        private SubSystem04 obj4=new SubSystem04();
        public void method()
        {
            obj2.method2();
            obj3.method3();
            obj4.method4();
        }
    }
    
    //子系统角色
    class SubSystem01
    {
        public  void method1()
        {
            System.out.println("子系统01的method1()被调用!");
        }   
    }
    //子系统角色
    class SubSystem02
    {
        public  void method2()
        {
            System.out.println("子系统02的method2()被调用!");
        }   
    }
    //子系统角色
    class SubSystem03
    {
        public  void method3()
        {
            System.out.println("子系统03的method3()被调用!");
        }   
    }
    //子系统角色
    class SubSystem04
    {
        public  void method4()
        {
            System.out.println("子系统04的method4()被调用!");
        }   
    }
  • 相关阅读:
    【FROM】java控件重绘AWT/SWINGPainting in AWT and Swing (EN)
    linux yum使用管理详细使用
    远程控制 vc++实现
    java 鼠标事件Dragged和Moved 及java显示GIF在JLabel、JButton
    C语言字符串函数大全
    C# 训练场(四)创建系统热键,并向活动窗口输入信息
    潜移默化学会WPF(样式) DataGrid(转载)
    时间查询
    Sqlserver2012 根据数据库mdf文件生成log文件,解决无法附加mdf文件
    我知道的一些 ”运行“ 窗体下的命令,个人使用
  • 原文地址:https://www.cnblogs.com/jing99/p/12602696.html
Copyright © 2020-2023  润新知