当前位置: 首页 > article >正文

十、结构型(外观模式)

外观模式(Facade Pattern)

概念
外观模式(Facade Pattern)是一种结构型设计模式,旨在为复杂子系统提供一个简化的统一接口。通过外观模式,客户端可以与子系统交互,而无需了解子系统的内部复杂性。这种模式为客户端屏蔽了复杂系统的细节,使得客户端使用系统时变得更简单。


应用场景

  1. 简化客户端与复杂系统的交互:在一个复杂的系统中,如果客户端需要与多个子系统进行交互,外观模式通过提供一个简化的接口,隐藏了系统的复杂性。例如,图形系统、数据库操作、第三方接口等往往有多个复杂的接口,外观模式可以为这些接口提供统一入口。

  2. 减少类之间的耦合:客户端只需与外观类交互,而不需要直接调用多个子系统接口,从而降低了客户端与子系统之间的耦合度,增强了系统的可维护性。

  3. 层次化结构:外观模式可以用于设计层次化系统,每一层提供一个外观类,减少上下层的相互依赖。例如,Web应用程序中,业务层可能会通过外观类来调用底层的持久化层和其他服务。


注意点

  • 外观类不应包含太多业务逻辑:外观类的职责应是简化接口,而不是实现复杂的业务逻辑。实际业务逻辑应由子系统负责处理。
  • 外观模式并不强制子系统内部结构的简化:它只是对客户端提供了一个简化的接口,子系统内部仍然可能非常复杂。
  • 可扩展性问题:如果子系统发生变化,外观类可能需要随着调整。

核心要素

  1. Facade(外观类):为客户端提供简化的接口,封装复杂的子系统接口调用。
  2. Subsystem(子系统类):复杂子系统的一部分,通常是多个类组成的系统,外观类通过这些子系统类完成各种功能。
  3. 客户端(Client):使用外观类来与子系统交互,客户端无需知道子系统的细节。

Java代码完整示例

// 子系统A
class SubsystemA {
    public void operationA() {
        System.out.println("子系统A的操作");
    }
}

// 子系统B
class SubsystemB {
    public void operationB() {
        System.out.println("子系统B的操作");
    }
}

// 子系统C
class SubsystemC {
    public void operationC() {
        System.out.println("子系统C的操作");
    }
}

// 外观类
class Facade {
    private SubsystemA subsystemA;
    private SubsystemB subsystemB;
    private SubsystemC subsystemC;

    public Facade() {
        subsystemA = new SubsystemA();
        subsystemB = new SubsystemB();
        subsystemC = new SubsystemC();
    }

    // 提供简化的接口
    public void performOperation() {
        subsystemA.operationA();
        subsystemB.operationB();
        subsystemC.operationC();
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.performOperation();
    }
}

输出结果

子系统A的操作
子系统B的操作
子系统C的操作

各种变形用法完整示例

  1. 分层外观模式
    在复杂系统中,多个子系统可能会存在多层次的依赖关系,可以为每一层提供一个外观类。例如,在一个大型企业级系统中,可以有数据层、业务逻辑层和表示层的外观类。

    代码示例

    // 数据层外观类
    class DataLayerFacade {
        private SubsystemA subsystemA;
        private SubsystemB subsystemB;
    
        public DataLayerFacade() {
            subsystemA = new SubsystemA();
            subsystemB = new SubsystemB();
        }
    
        public void dataLayerOperation() {
            subsystemA.operationA();
            subsystemB.operationB();
        }
    }
    
    // 业务层外观类
    class BusinessLayerFacade {
        private DataLayerFacade dataLayerFacade;
        private SubsystemC subsystemC;
    
        public BusinessLayerFacade() {
            dataLayerFacade = new DataLayerFacade();
            subsystemC = new SubsystemC();
        }
    
        public void businessLayerOperation() {
            dataLayerFacade.dataLayerOperation();
            subsystemC.operationC();
        }
    }
    
    // 客户端
    public class ClientLayered {
        public static void main(String[] args) {
            BusinessLayerFacade businessLayerFacade = new BusinessLayerFacade();
            businessLayerFacade.businessLayerOperation();
        }
    }
    
  2. 双重外观模式
    双重外观模式是将多个外观模式结合使用,客户端可以选择使用不同的外观类来访问不同的子系统。例如,一个系统可能包含多个独立模块,每个模块有自己的外观类,客户端可以选择使用特定模块的外观类。

    代码示例

    // 外观A
    class FacadeA {
        private SubsystemA subsystemA;
        private SubsystemB subsystemB;
    
        public FacadeA() {
            subsystemA = new SubsystemA();
            subsystemB = new SubsystemB();
        }
    
        public void operationA() {
            subsystemA.operationA();
            subsystemB.operationB();
        }
    }
    
    // 外观B
    class FacadeB {
        private SubsystemC subsystemC;
    
        public FacadeB() {
            subsystemC = new SubsystemC();
        }
    
        public void operationB() {
            subsystemC.operationC();
        }
    }
    
    // 客户端
    public class ClientMultipleFacades {
        public static void main(String[] args) {
            FacadeA facadeA = new FacadeA();
            facadeA.operationA();
            
            FacadeB facadeB = new FacadeB();
            facadeB.operationB();
        }
    }
    
  3. 与单例模式结合的外观模式
    外观模式常与单例模式结合使用,以确保系统中的外观类只有一个实例,减少系统开销,确保统一的接口访问。

    代码示例

    // 外观类使用单例模式
    class SingletonFacade {
        private static SingletonFacade instance;
        private SubsystemA subsystemA;
        private SubsystemB subsystemB;
    
        private SingletonFacade() {
            subsystemA = new SubsystemA();
            subsystemB = new SubsystemB();
        }
    
        public static SingletonFacade getInstance() {
            if (instance == null) {
                instance = new SingletonFacade();
            }
            return instance;
        }
    
        public void performOperations() {
            subsystemA.operationA();
            subsystemB.operationB();
        }
    }
    
    // 客户端
    public class ClientSingletonFacade {
        public static void main(String[] args) {
            SingletonFacade facade = SingletonFacade.getInstance();
            facade.performOperations();
        }
    }
    

总结
外观模式的主要作用是简化客户端对复杂系统的访问。通过引入外观类,系统的可维护性、可扩展性和模块化得到了提升。装饰者模式和外观模式的不同之处在于,装饰者模式注重在运行时增加功能,而外观模式侧重于为子系统提供一个简化的接口。


http://www.kler.cn/a/350265.html

相关文章:

  • Gin框架操作指南02:JSON渲染
  • 利用 Llama 3.1模型 + Dify开源LLM应用开发平台,在你的Windows环境中搭建一套AI工作流
  • 理解前端开发和小程序开发中的 build 和 dev 模式
  • 迪杰斯特拉算法的理解
  • Content-Type 详解
  • 打破医院内外网通讯壁垒的关键-消息摆渡
  • mysql用户管理(user表列信息介绍,本质,管理操作),数据库的权限管理(权限列表,权限操作)
  • MySQL 通过 Next-Key Locking 技术(行锁+间隙锁)避免幻读问题
  • Java中的Iterator接口,以及HashSet和TreeSet
  • Pytest中fixture的scope详解
  • iMeta: 南医大余光创组ggtree最新文章-系统发育树存储与可视化的数据结构
  • MySQL(python开发)——(3)表数据的基本操作,增删改查
  • C语言之练习题
  • Jenkins---01
  • 【黑苹果】记录MacOS升级Sonoma的过程
  • Android 应用中 MQTT 消息处理:选择适合的后台处理方案
  • 使用 Python 爬虫批量下载百度图片的详细教程
  • 自动化测试实施过程中需要考虑的因素!
  • 【数学二】一元函数积分学-不定积分与定积分的计算-6个有用得定积分公式
  • 【Flutter】Dart:pubspec.yaml文件