十、结构型(外观模式)

server/2024/10/21 15:13:09/

外观模式(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.ppmy.cn/server/133657.html

相关文章

.net framework 3.5sp1插件怎么启动

在Windows 10系统中启用.NET Framework 3.5 SP1插件,可以通过以下步骤操作: 一、通过控制面板启用.NET Framework 3.5 SP1插件 1.打开控制面板: 可以通过在开始菜单搜索“控制面板”来找到它。 或者按下Win R组合键,输入“co…

(七)信号

异步事件的获取方式通常只有两种:查询法,通知法。 假如我们使用一个烟雾传感器监测库房中是否发生了火灾,火灾的到来的时间就是一种异步事件。 我们可以通过两种方式获取是否发生了火灾: 1)查询法:传感器…

Android Studio简易项目|随机选择器(类似转盘)

一、背景 为了强化对flowlayout流式布局的理解和简易安卓项目架构结构的理解&#xff0c;写一个小项目&#xff0c;随机选择器&#xff0c;控制可见等 二、项目代码 2.1流式布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns…

Windows下搭建VUE开发环境

Windows下搭建VUE开发环境 文章目录 Windows下搭建VUE开发环境第一步 安装nodejs下载nodejs安装nodejs配置环境变量安装测试配置npm的路径配置npm的国内代理安装必要工具测试工具安装的使用 第二步 安装vscode下载vscode安装插件Chinese (Simplified) (简体中文) Language Pack…

两个字符串的最长 公共子序列

给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08;也可以…

如何得到两个蛋白质序列的一致性和相似性

一、概念辨析 &#xff08;1&#xff09;一致性 一致性&#xff08;identity&#xff09;&#xff1a;如果两个序列&#xff08;蛋白质或核酸&#xff09;长度相同&#xff0c;那么它们的一致性定义为它们对应位置上相同的残基&#xff08;一个字母&#xff0c;氨基酸或碱基&…

Spring Boot为大创项目提供智能报表解决方案

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

【C语言】字符函数和字符串函数(上)

本篇博客将讲解以下知识&#xff1a; &#xff08;1&#xff09;字符分类函数 &#xff08;2&#xff09;字符转换函数 &#xff08;3&#xff09;strlen的使用和模拟实现 1、字符分类函数 C语言中有一一系列的函数是专门做字符分类的&#xff0c;就是字符是属于什么类型的字符…