结构型设计模式(一):门面模式 组合模式

门面模式 Facade

1、什么是门面模式

门面模式(Facade Pattern)是一种结构型设计模式,旨在为系统提供一个统一的接口,以便于访问子系统中的一群接口。它通过定义一个高层接口,简化了客户端与子系统之间的交互,从而降低了系统的复杂性。

2、为什么使用门面模式

  1. 简化接口:门面模式通过定义一个高层接口,简化了客户端与子系统之间的交互,使得客户端无需直接与子系统的复杂接口打交道。
  2. 解耦客户端和子系统:通过引入门面,客户端与子系统的依赖关系得到解耦,客户端只需与门面进行交互,而不需要关心子系统的具体实现。
  3. 提高可维护性:门面模式将子系统的实现细节封装起来,有助于提高系统的可维护性,降低了系统的复杂性。

3、如何实现门面模式

设计实现一个简单的计算启动过程

// 子系统 - CPU
class CPU {public void start() {System.out.println("CPU is starting...");}
}// 子系统 - Memory
class Memory {public void load() {System.out.println("Memory is loading...");}
}// 子系统 - HardDrive
class HardDrive {public void read() {System.out.println("HardDrive is reading...");}
}// 门面类 - ComputerFacade
class ComputerFacade {private CPU cpu;private Memory memory;private HardDrive hardDrive;public ComputerFacade() {this.cpu = new CPU();this.memory = new Memory();this.hardDrive = new HardDrive();}public void startComputer() {cpu.start();memory.load();hardDrive.read();System.out.println("Computer is started and ready to use.");}
}// 客户端代码
public class Client {public static void main(String[] args) {ComputerFacade computerFacade = new ComputerFacade();computerFacade.startComputer();}
}

4、是否存在缺陷和不足

  1. 不符合开闭原则:当系统中的子系统发生变化时,可能需要修改门面类,不符合开闭原则。
  2. 可能导致过多门面类:随着系统的不断扩展,可能会出现多个门面类,导致系统变得复杂。

5、如何缓解缺陷和不足

  1. 使用配置文件:将子系统的配置信息放置在配置文件中,通过读取配置文件的方式动态创建门面类,提高系统的灵活性。
  2. 使用抽象工厂模式:可以结合抽象工厂模式,将门面的创建过程交给工厂类,从而降低客户端与门面的耦合度。
// 抽象产品 - CPU
interface CPU {void start();
}// 具体产品A - ConcreteCPUA
class ConcreteCPUA implements CPU {@Overridepublic void start() {System.out.println("ConcreteCPUA is starting...");}
}// 具体产品B - ConcreteCPUB
class ConcreteCPUB implements CPU {@Overridepublic void start() {System.out.println("ConcreteCPUB is starting...");}
}// 抽象产品 - Memory
interface Memory {void load();
}// 具体产品A - ConcreteMemoryA
class ConcreteMemoryA implements Memory {@Overridepublic void load() {System.out.println("ConcreteMemoryA is loading...");}
}// 具体产品B - ConcreteMemoryB
class ConcreteMemoryB implements Memory {@Overridepublic void load() {System.out.println("ConcreteMemoryB is loading...");}
}// 抽象产品 - HardDrive
interface HardDrive {void read();
}// 具体产品A - ConcreteHardDriveA
class ConcreteHardDriveA implements HardDrive {@Overridepublic void read() {System.out.println("ConcreteHardDriveA is reading...");}
}// 具体产品B - ConcreteHardDriveB
class ConcreteHardDriveB implements HardDrive {@Overridepublic void read() {System.out.println("ConcreteHardDriveB is reading...");}
}// 抽象工厂接口
interface ComputerFactory {CPU createCPU();Memory createMemory();HardDrive createHardDrive();
}// 具体工厂A
class ConcreteFactoryA implements ComputerFactory {@Overridepublic CPU createCPU() {return new ConcreteCPUA();}@Overridepublic Memory createMemory() {return new ConcreteMemoryA();}@Overridepublic HardDrive createHardDrive() {return new ConcreteHardDriveA();}
}// 具体工厂B
class ConcreteFactoryB implements ComputerFactory {@Overridepublic CPU createCPU() {return new ConcreteCPUB();}@Overridepublic Memory createMemory() {return new ConcreteMemoryB();}@Overridepublic HardDrive createHardDrive() {return new ConcreteHardDriveB();}
}// 门面类
class ComputerFacade {private CPU cpu;private Memory memory;private HardDrive hardDrive;public ComputerFacade(ComputerFactory factory) {this.cpu = factory.createCPU();this.memory = factory.createMemory();this.hardDrive = factory.createHardDrive();}public void startComputer() {cpu.start();memory.load();hardDrive.read();System.out.println("Computer is started and ready to use.");}
}// 客户端代码
public class Client {public static void main(String[] args) {// 使用工厂A创建电脑ComputerFactory factoryA = new ConcreteFactoryA();ComputerFacade computerFacadeA = new ComputerFacade(factoryA);computerFacadeA.startComputer();// 使用工厂B创建电脑ComputerFactory factoryB = new ConcreteFactoryB();ComputerFacade computerFacadeB = new ComputerFacade(factoryB);computerFacadeB.startComputer();}
}

上面这个例子中,抽象工厂模式用于创建不同系列的电脑产品,而门面类的创建过程交给工厂类,客户端代码通过选择不同的工厂来创建不同系列的电脑,无需关心具体产品的创建过程,有助于提高系统的灵活性和可维护性

组合模式 Composite

1、什么是组合模式

组合模式通过将对象组织成树形结构来表示整体-部分层次结构,使得客户端可以统一对待单个对象和对象的组合。它主要包含三个角色:叶子节点(Leaf)、组合节点(Composite)、客户端(Client)。

2、为什么使用组合模式

  1. 统一接口:组合模式使得客户端可以统一对待单个对象和对象的组合,因为它们共享相同的接口。
  2. 灵活性:客户端无需关心对象是叶子节点还是组合节点,可以在不同层次构建复杂的对象结构。
  3. 简化客户端代码:客户端无需判断操作的是单个对象还是对象组合,简化了客户端代码。

3、如何使用组合模式

设计实现一个文件系统

import java.util.ArrayList;
import java.util.List;// 抽象组件 - 文件和目录的共同接口
interface FileSystemComponent {void display();
}// 叶子节点 - 文件
class FileLeaf implements FileSystemComponent {private String name;public FileLeaf(String name) {this.name = name;}@Overridepublic void display() {System.out.println("File: " + name);}
}// 组合节点 - 目录
class DirectoryComposite implements FileSystemComponent {private String name;private List<FileSystemComponent> components;public DirectoryComposite(String name) {this.name = name;this.components = new ArrayList<>();}public void addComponent(FileSystemComponent component) {components.add(component);}public void removeComponent(FileSystemComponent component) {components.remove(component);}@Overridepublic void display() {System.out.println("Directory: " + name);for (FileSystemComponent component : components) {component.display();}}
}// 客户端代码
public class Client {public static void main(String[] args) {// 构建文件系统结构FileSystemComponent file1 = new FileLeaf("file1.txt");FileSystemComponent file2 = new FileLeaf("file2.txt");DirectoryComposite dir1 = new DirectoryComposite("Folder 1");dir1.addComponent(file1);dir1.addComponent(file2);FileSystemComponent file3 = new FileLeaf("file3.txt");DirectoryComposite dir2 = new DirectoryComposite("Folder 2");dir2.addComponent(file3);dir2.addComponent(dir1);// 显示文件系统结构dir2.display();}
}

4、是否存在缺陷和不足

  1. 限制类型一致性:组合模式要求所有组件都实现相同的接口,这可能限制了组件的类型一致性。
  2. 不支持单个对象的特殊处理:组合模式统一对待单个对象和组合对象,因此可能无法支持对单个对象的特殊处理。

5、如何缓解缺陷和不足

  1. 使用抽象构件类:引入一个抽象构建类,包含所有子类共有的方法,从而提高组件的类型一致性。
  2. 在叶子节点实现特殊处理:在叶子节点类中实现特殊处理逻辑,以满足对单个对象的特殊需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/229515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优质全套SpringMVC教程

三、SpringMVC 在SSM整合中&#xff0c;MyBatis担任的角色是持久层框架&#xff0c;它能帮我们访问数据库&#xff0c;操作数据库 Spring能利用它的两大核心IOC、AOP整合框架 1、SpringMVC简介 1.1、什么是MVC MVC是一种软件架构的思想&#xff08;不是设计模式-思想就是我们…

【具身智能评估3】具身视觉语言规划(EVLP)度量标准汇总

参考论文&#xff1a;Core Challenges in Embodied Vision-Language Planning 论文作者&#xff1a;Jonathan Francis, Nariaki Kitamura, Felix Labelle, Xiaopeng Lu, Ingrid Navarro, Jean Oh 论文原文&#xff1a;https://arxiv.org/abs/2106.13948 论文出处&#xff1a;Jo…

netty-daxin-4(httpwebsocket)

文章目录 学习链接http服务端NettyHttpServerHelloWorldServerHandler 客户端ApiPost websocket初步了解为什么需要 WebSocket简介 浏览器的WebSocket客户端客户端的简单示例客户端的 APIWebSocket 构造函数webSocket.readyStatewebSocket.onopenwebSocket.onclosewebSocket.ο…

MATLAB - MPC - QP Solvers

系列文章目录 前言 模型预测控制器 QP 求解器将线性 MPC 优化问题转换为一般形式的 QP 问题 受到线性不等式约束 其中 x 是解向量。H 是黑森矩阵。当预测模型和调整权重在运行时不发生变化时&#xff0c;该矩阵保持不变。A 是线性约束系数矩阵。当预测模型在运行时不发生变化时…

Eclipse 自动生成注解,如果是IDEA可以参考编译器自带模版进行修改

IDEA添加自动注解 左上角选择 File -> Settings -> Editor -> File and Code Templates&#xff1b; 1、添加class文件自动注解&#xff1a; ​/*** <b>Function: </b> todo* program: ${NAME}* Package: ${PACKAGE_NAME}* author: Jerry* date: ${YEA…

介绍strncpy函数

strncpy函数需要引用#include <string.h>头文件 函数原型&#xff1a; char *_Dest 是字符串的去向 char *_Source是字符串的来源 size_t_Count是复制字符串的大小 #include <stdio.h> #include <string.h> int main() { char arr[128] { \0 }; …

【JAVA-Day69】抛出异常的精髓:深度解析 throw、throws 关键字,优雅处理异常问题

抛出异常的精髓&#xff1a;深度解析 throw、throws 关键字&#xff0c;优雅处理异常问题 &#x1f680; 抛出异常的精髓&#xff1a;深度解析 throw、throws 关键字&#xff0c;优雅处理异常问题 &#x1f680;一、什么是抛出异常 &#x1f60a;二、如何抛出异常 &#x1f914…

MetaAI语音翻译大模型Seamless登场,主打AI无缝同声传译

论文题目&#xff1a; Seamless: Multilingual Expressive and Streaming Speech Translation 论文链接&#xff1a; https://ai.meta.com/research/publications/seamless-multilingual-expressive-and-streaming-speech-translation/ 代码链接&#xff1a; GitHub - facebook…

DSP捕获输入简单笔记

之前使用stm32的大概原理是&#xff1a; 输入引脚输入一个脉冲&#xff0c;捕获1开始极性捕获&#xff0c;捕获的是从启动捕获功能开始计数&#xff0c;捕获的是当前的计数值&#xff1b; 例如一个脉冲&#xff0c;捕获1捕获上升沿&#xff0c;捕获2捕获下降沿&#xff1b;而两…

reactive数据不响应

我们知道&#xff0c;reactive函数用于创建对象等复杂数据的响应式代理对象&#xff0c;当该对象的属性发生变化时&#xff0c;会自动触发视图更新。 但在Vue 3中&#xff0c;当我们使用reactive创建的对象或数组进行赋值时&#xff0c;尽管能够完成正常的赋值操作&#xff0c…

TrustZone之调试、跟踪和分析

接下来,我们将查看系统中的调试和跟踪组件,如下图所示: 现代Arm系统包括支持调试和性能分析的广泛功能。在TrustZone中,我们必须确保这些功能不能被用来危害系统的安全性。 关于调试功能,考虑开发新的SoC。不同的开发人员被信任调试系统的不同部分。芯片公司的工程…

SearchWP WordPress高级网站内容搜索插件(包含所有专业扩展)

点击阅读SearchWP WordPress高级网站内容搜索插件(包含所有专业扩展)原文 SearchWP WordPress高级网站内容搜索插件是一个非常强大的工具&#xff0c;可以显着增强您网站的搜索功能。通过向网站访问者提供高度相关和精确的搜索结果&#xff0c;它可以有效地简化他们的搜索过程…

C语言使用posix正则表达式库

在C语言中&#xff0c;你可以使用 POSIX 正则表达式库&#xff08;regex.h&#xff09;来进行正则表达式的模式匹配。POSIX 正则表达式库提供了一组函数来编译、执行和释放正则表达式。 下面是使用 POSIX 正则表达式库的基本步骤&#xff1a; 包含头文件 <regex.h>&…

项目管理软件助力科研项目管理

作为一名研究人员&#xff0c;你可能会觉得你的成功取决于你的研究有多创新和你工作有多努力。实际上&#xff0c;创新和勤奋很重要&#xff0c;但聪明地工作也很重要。如果你是那种在早上打开电子邮件并开始自上而下的工作的人&#xff0c;你可能很快就会发现你的电子邮件多得…

论文降重宝同义词替换功能的优势与特点 PaperBERT

大家好&#xff0c;今天来聊聊论文降重宝同义词替换功能的优势与特点&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 标题&#xff1a;论文降重宝同义词替换功能的优势与特…

C# WPF上位机开发(函数运行时间分析)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 上位机除了基本功能和稳定性之外&#xff0c;还有一个要注意的就是运行效率的问题。如果我们想提高软件的运行效率&#xff0c;单位时间做更多的工…

1.新入手的32位单片机资源和资料总览

前言&#xff1a; 学了将近1年的linux驱动和uboot&#xff0c;感觉反馈不足&#xff0c;主要是一直在学各种框架&#xff0c;而且也遇到了门槛&#xff0c;比如驱动部分&#xff0c;还不能随心所欲地编程&#xff0c;原因是有些外设的原理还不够深刻、有些复杂的底层驱动的代码…

计算机网络:数据链路层(VLAN)

今天又学到一个知识&#xff0c;加油&#xff01; 目录 一、传统局域网的局限&#xff08;促进VLAN的诞生&#xff09; 二、VLAN简介 三、VLAN的实现 总结 一、传统局域网的局限&#xff08;促进VLAN的诞生&#xff09; 缺乏流量隔离:即使把组流量局域化道一个单一交换机中…

Python Django 连接 PostgreSQL 操作实例

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python Django 连接 PostgreSQL 操作实例&#xff0c;全文3500字&#xff0c;阅读大约10分钟 在Web开发中&#xff0c;使用Django连接到PostgreSQL数据库是一种常见的选择。…

svn 安装

安装系统 ubuntu 22 安装命令&#xff1a; sudo apt-get install subversion 创建第一个工程&#xff1a; 创建版本库、项目 1、先创建svn根目录文件夹 sudo mkdir /home/svn 2、创建项目的目录文件夹 sudo mkdir /home/svn/demo_0 svnadmin create /home/svn/demo_0 配置&a…