GoF设计模式——结构型设计模式分析与应用

文章目录

    • UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。
      • 1. 继承(抽象,泛化关系)
      • 2. 关联
      • 3. 组合/聚合
      • 各种可能的配合:
        • 1. 关联后抽象
        • 2. 关联的集合
        • 3. 组合接口
        • 4. 递归聚合接口
      • Adapter
      • Bridge
      • Composite
      • Decorator
      • Facade
      • Flyweight
      • Proxy

GoF(Gang of Four)设计模式的三大类:

  • 创建型设计模式(Creational Patterns)
  • 结构型设计模式(Structural Patterns)
  • 行为设计模式(Behavioral Patterns)

Object Scope 可用于运行时

Class Scope 只能用于编译时

在这里插入图片描述


UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。

车是交通工具,车是我的,车里有发动机

1. 继承(抽象,泛化关系)

class Vehicle {String name;void move() {}
}class Car extends Vehicle {void drive() {}
}

2. 关联

class Person {Car car; // 关联关系
}class Car {String model;
}

3. 组合/聚合

class Car {Engine engine; // 组合关系GPS gps;       // 聚合关系
}class Engine {}
class GPS {}

各种可能的配合:

圈住部分即为原因。

1. 关联后抽象

在这里插入图片描述

2. 关联的集合

在这里插入图片描述

3. 组合接口

在这里插入图片描述

4. 递归聚合接口

在这里插入图片描述
这里递归怎么理解?

其实是虽然我的装饰器实现了这个接口,但是我的装饰器类内部成员可能还有有这个接口类



Adapter

适配器模式能够将不兼容的接口转换成兼容的接口,从而使得原本无法直接交互的类能够合作。
可以在不修改现有代码的情况下,重用第三方的功能或代码。
可以在不同的系统间进行灵活的接口转换,尤其适用于系统集成和迁移。

Adapter(适配器)设计模式

继承+关联 (“关联后抽象”)

“ 加一层,新接口。”
在这里插入图片描述

(“R”标记:可运行时改变;实心箭头指实现,空心指泛化)

设计逻辑的层次:

  • 先从具体类(ConcreteAdapter)的实现入手,明确其与其他类的关联(如 Adaptee)。
  • 然后在其上进一步抽象出一个统一的接口(Adapter),以适应多种实现需求。
// 老版本的播放器接口
class OldMediaPlayer {void playAudio() {System.out.println("Playing audio...");}
}// 新播放器接口
interface ModernPlayer {void play();
}// 适配器类
class PlayerAdapter implements ModernPlayer {private OldMediaPlayer oldMediaPlayer;public PlayerAdapter(OldMediaPlayer oldMediaPlayer) {this.oldMediaPlayer = oldMediaPlayer;}@Overridepublic void play() {oldMediaPlayer.playAudio(); // 使用旧方法适配新接口}
}// 客户端代码
public class AdapterExample {public static void main(String[] args) {OldMediaPlayer oldPlayer = new OldMediaPlayer();ModernPlayer modernPlayer = new PlayerAdapter(oldPlayer);modernPlayer.play(); // 使用新接口播放}
}

Bridge

解耦抽象和实现:桥接模式将抽象部分与实现部分分离,可以独立地扩展两者。
新增抽象层或者实现层时,不会影响到对方,增强了系统的可扩展性。
避免重复代码,增加代码复用性。

Bridge(桥)设计模式

组合接口

“ 比如形状类里加个颜色类。 而该形状可以在各种地方使用”
在这里插入图片描述

// 实现接口
interface Color {String fill();
}class Red implements Color {public String fill() {return "Color is Red";}
}class Blue implements Color {public String fill() {return "Color is Blue";}
}// 抽象类
abstract class Shape {protected Color color;public Shape(Color color) {this.color = color;}abstract void draw();
}class Circle extends Shape {public Circle(Color color) {super(color);}public void draw() {System.out.println("Drawing Circle. " + color.fill());}
}// 客户端代码
public class BridgeExample {public static void main(String[] args) {Shape redCircle = new Circle(new Red());Shape blueCircle = new Circle(new Blue());redCircle.draw();blueCircle.draw();}
}

Composite

树形结构:组合模式允许你以树形结构来组合对象,简化了对象的管理和处理。
统一操作:可以统一对单个对象和组合对象的处理,客户端不需要知道是单一对象还是组合对象。
递归结构:支持递归组合,使得层次结构更易于表示和管理,特别适用于有层次结构的对象模型。

Composite(组合)设计模式

递归聚合接口

“可以都放进一个容器,装满书的书包”

书包里可能还有一个书包,所以书包的“聚合”里,还有component抽象类——递归。
在这里插入图片描述

// 组件接口
interface Component {void operation();
}// 叶子节点
class Leaf implements Component {private String name;public Leaf(String name) {this.name = name;}public void operation() {System.out.println("Leaf: " + name);}
}// 容器节点
class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component component) {children.add(component);}public void operation() {for (Component child : children) {child.operation();}}
}// 客户端代码
public class CompositeExample {public static void main(String[] args) {Composite root = new Composite();Leaf leaf1 = new Leaf("Leaf 1");Leaf leaf2 = new Leaf("Leaf 2");Composite subTree = new Composite();subTree.add(new Leaf("SubTree Leaf 1"));root.add(leaf1);root.add(leaf2);root.add(subTree);root.operation(); // 遍历树形结构}
}

Decorator

动态扩展功能:装饰器模式可以在运行时动态地给对象添加新的功能,而不改变原有类的代码。
增加灵活性:通过装饰器,可以为对象添加多种功能,客户端可以根据需求进行组合,增加了系统的灵活性。
符合开放/关闭原则:装饰器通过扩展功能,而不是修改类本身,符合开放/关闭原则。

Decorator(装饰器)设计模式

递归聚合接口

“对不同物品可以进行不同装饰”

“两组抽象和实现。
装饰器里有【具体部件】和新的方法”
在这里插入图片描述

// 抽象组件(饮料)
interface Beverage {String getDescription();double cost();
}// 具体组件
class Coffee implements Beverage {public String getDescription() {return "Coffee";}public double cost() {return 5.0;}
}// 装饰器
abstract class AddOnDecorator implements Beverage {protected Beverage beverage;public AddOnDecorator(Beverage beverage) {this.beverage = beverage;}
}class Milk extends AddOnDecorator {public Milk(Beverage beverage) {super(beverage);}public String getDescription() {return beverage.getDescription() + ", Milk";}public double cost() {return beverage.cost() + 1.0;}
}class Sugar extends AddOnDecorator {public Sugar(Beverage beverage) {super(beverage);}public String getDescription() {return beverage.getDescription() + ", Sugar";}public double cost() {return beverage.cost() + 0.5;}
}// 客户端代码
public class DecoratorExample {public static void main(String[] args) {Beverage beverage = new Coffee();beverage = new Milk(beverage);beverage = new Sugar(beverage);System.out.println(beverage.getDescription() + " costs " + beverage.cost());}
}

Facade

简化接口:外观模式为复杂子系统提供了一个统一的、高层的接口,简化了客户端的调用方式。
降低耦合:客户端不需要了解各个子系统的实现细节,只需要与外观类交互,从而降低了系统的耦合度。
便于扩展:如果需要修改子系统的实现,可以在外观类中进行修改,而不影响客户端代码。

Façade(门面)设计模式

关联的集合

“将各个组件集成在一起”
在这里插入图片描述

class CPU {public void start() {System.out.println("CPU started.");}
}class Memory {public void load() {System.out.println("Memory loaded.");}
}class HardDrive {public void readData() {System.out.println("HardDrive read data.");}
}// 门面类
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 start() {cpu.start();memory.load();hardDrive.readData();}
}// 客户端代码
public class FacadeExample {public static void main(String[] args) {ComputerFacade computer = new ComputerFacade();computer.start(); // 一键启动}
}

Flyweight

内存优化:享元模式通过共享相同的对象实例,减少了内存的消耗,尤其适用于大量相似对象的场景。
提高性能:由于共享对象的使用,可以减少对象的创建和销毁,提高了系统的性能。

Flyweight(享元)设计模式

关联的集合

“共享的懒汉模式”
在这里插入图片描述

// 抽象享元
interface Shape {void draw();
}// 具体享元
class Circle implements Shape {private String color;public Circle(String color) {this.color = color;}public void draw() {System.out.println("Drawing " + color + " Circle");}
}// 享元工厂
class ShapeFactory {private static Map<String, Shape> shapeMap = new HashMap<>();public static Shape getCircle(String color) {if (!shapeMap.containsKey(color)) {shapeMap.put(color, new Circle(color));System.out.println("Created new " + color + " Circle");}return shapeMap.get(color);}
}// 客户端代码
public class FlyweightExample {public static void main(String[] args) {Shape redCircle = ShapeFactory.getCircle("Red");Shape blueCircle = ShapeFactory.getCircle("Blue");Shape anotherRedCircle = ShapeFactory.getCircle("Red");redCircle.draw();blueCircle.draw();anotherRedCircle.draw(); // 复用红色圆}
}

Proxy

控制访问:代理模式可以控制对真实对象的访问,例如延迟加载、权限控制、缓存等。
增强功能:代理类可以为目标对象增加额外的功能,比如日志记录、安全控制等,而不需要修改目标对象的代码。
降低耦合:代理类和目标类相互独立,客户端通过代理类访问目标对象,减少了对目标类的直接依赖。

Proxy(代理)设计模式

关联后抽象

“懒汉模式”
在这里插入图片描述

// 抽象接口
interface Image {void display();
}// 真实类
class RealImage implements Image {private String fileName;public RealImage(String fileName) {this.fileName = fileName;loadFromDisk();}private void loadFromDisk() {System.out.println("Loading " + fileName);}public void display() {System.out.println("Displaying " + fileName);}
}// 代理类
class ProxyImage implements Image {private RealImage realImage;private String fileName;public ProxyImage(String fileName) {this.fileName = fileName;}public void display() {if (realImage == null) {realImage = new RealImage(fileName); // 延迟加载}realImage.display();}
}// 客户端代码
public class ProxyExample {public static void main(String[] args) {Image image = new ProxyImage("test.jpg");image.display(); // 加载并显示image.display(); // 再次显示,无需加载}
}

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

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

相关文章

【C++】C++11新特性详解:可变参数模板与emplace系列的应用

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…

多模态大型语言模型(MLLM)综述

目录 多模态大语言模型的基础 长短期网络结构(LSTM) 自注意力机制 基于Transformer架构的自然语言处理模型 多模态嵌入的关键步骤 TF-IDF TF-IDF的概念 TF-IDF的计算公式 TF-IDF的主要思路 TF-IDF的案例 训练和微调多模态大语言模型(MLLM) 对比学习 (CLIP, ALIG…

Otter 安装流程

优质博文&#xff1a;IT-BLOG-CN 一、背景 随着公司的发展&#xff0c;订单库的数据目前已达到千万级别&#xff0c;需要进行分表分库&#xff0c;就需要对数据进行迁移&#xff0c;我们使用了otter&#xff0c;这里简单整理下&#xff0c;otter 的安装过程&#xff0c;希望对…

Web3 游戏周报(11.17 - 11.23)

回顾上周的区块链游戏概况&#xff0c;查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【11.17 - 11.23】Web3 游戏行业动态&#xff1a; 加密游戏开发商 Gunzilla Games 发推表示&#xff0c;其已与 Coinbase Ventures 达成合作并获得其投资。 国际足联将与 Mythica…

【linux学习指南】初识Linux进程信号与使用

文章目录 &#x1f4dd;信号快速认识&#x1f4f6;⽣活⻆度的信号&#x1f4f6; 技术应⽤⻆度的信号&#x1f309; 前台进程&#xff08;键盘&#xff09;&#x1f309;⼀个系统函数 &#x1f4f6;信号概念&#x1f4f6;查看信号 &#x1f320; 信号处理&#x1f309; 忽略此信…

3DEXPERIENCE软件是干什么的—3DE软件代理商微辰三维

在当今数字化转型浪潮席卷全球各个行业的大背景下&#xff0c;3DEXPERIENCE 软件宛如一颗璀璨的明星&#xff0c;闪耀在产品设计、制造以及协同创新等诸多领域。它是由达索系统公司推出的一款综合性的、功能强大的商业软件平台&#xff0c;为企业的整个产品生命周期管理带来了前…

【大数据学习 | Spark-Core】广播变量和累加器

1. 共享变量 Spark两种共享变量&#xff1a;广播变量&#xff08;broadcast variable&#xff09;与累加器&#xff08;accumulator&#xff09;。 累加器用来对信息进行聚合&#xff0c;相当于mapreduce中的counter&#xff1b;而广播变量用来高效分发较大的对象&#xff0c…

STM32编程小工具FlyMcu和STLINK Utility 《通俗易懂》破解

FlyMcu FlyMcu 模拟仿真软件是一款用于 STM32 芯片 ISP 串口烧录程序的专用工具&#xff0c;免费&#xff0c;且较为非常容易下手&#xff0c;好用便捷。 注意&#xff1a;STM32 芯片的 ISP 下载&#xff0c;只能使用串口1&#xff08;USART1&#xff09;&#xff0c;对应的串口…

MTK主板_安卓主板方案_MTK联发科主板定制开发

联发科(MTK)主板以其强大的性能和多样化的功能而受到广泛关注。该平台包括多个型号&#xff0c;例如MT6761、MT8766、MT6762、MT6765、MT8768和MT8788等&#xff0c;均配置了四核或八核64位处理器&#xff0c;主频可高达2.0GHz。采用先进的12nm工艺&#xff0c;搭载Android 11.…

信息收集(1)

学习视频引路信息收集&#xff08;1&#xff09;_哔哩哔哩_bilibili View信息收集&#xff08;1&#xff09; 分享一个漏洞挖掘平台&#xff1a;补天 以吉林通用航空职业技术学院|官网 (jlthedu.com)为目标 第一步&#xff1a;查看cdn和域名被注册的信息 可以查询域名信息的…

React(六)——Redux

文章目录 项目地址基本理解一、配置Redux store二、创建slice配置到store里并使用三、给Slice配置reducers&#xff0c;用来修改初始值 项目地址 教程作者&#xff1a;教程地址&#xff1a; 代码仓库地址&#xff1a; 所用到的框架和插件&#xff1a; dbt airflow基本理解 s…

如何利用ATECLOUD平台来实现数据报告的导出和数据分析?-纳米软件

1.数据报告导出 选择报告模板&#xff1a;ATECLOUD 平台通常会提供多种预设的数据报告模板&#xff0c;这些模板是根据不同的测试场景和需求设计的。例如&#xff0c;在电源模块测试中&#xff0c;有针对输出电压、电流、功率等基本参数的报告模板&#xff0c;也有包含纹波系数…

[ZJCTF 2019]NiZhuanSiWei

[ZJCTF 2019]NiZhuanSiWei 上面代码&#xff0c;使用get上传了三个参数&#xff0c;在text者用力恒等于&#xff0c;然后就输出&#xff0c;接着第二个参数中出现flag就输出not now&#xff0c;接着第三个参数是反序了一下输出。 ?textdata://text/plain,welcome to the zjct…

JSONCPP 数据解析与序列化

常用类接口 Json::Value 类 用于存储 JSON 数据的核心类。它支持将数据解析为对象、数组或基本类型&#xff08;如字符串、数值等&#xff09; 赋值操作符&#xff1a;Value& operator(Value other); 用于将一个 JSON 值赋给另一个 JSON 值 Json::Value value; value &…

40分钟学 Go 语言高并发:【实战】并发安全的配置管理器(功能扩展)

【实战】并发安全的配置管理器&#xff08;功能扩展&#xff09; 一、扩展思考 分布式配置中心 实现配置的集中管理支持多节点配置同步实现配置的版本一致性 配置加密 敏感配置的加密存储配置的安全传输访问权限控制 配置格式支持 支持YAML、TOML等多种格式配置格式自动…

ChatGPT 桌面版发布了,如何安装?

本章教程教大家如何进行安装。 一、下载安装包 官网地址地址&#xff1a;https://openai.com/chatgpt/desktop/ 支持Windows和MacOS操作系统 二、安装步骤 Windows用户下载之后&#xff0c;会有一个exe安装包&#xff0c;点击运行安装即可。 注意事项&#xff0c;如果Windows操…

【Electron学习笔记(二)】基于Electron开发应用程序

基于Electron开发本地应用程序 基于Electron开发本地应用程序前言正文1、创建 pages 目录2、创建 index.html 文件3 、创建 html.css 文件4 、main.js里引入页面5 、运行 start 命令6 、启用开发者模式7 、解决内容安全策略8、完善窗口行为9、配置自动重启&#xff0c;保存后自…

力扣--LCR 154.复杂链表的复制

题目 请实现 copyRandomList 函数&#xff0c;复制一个复杂链表。在复杂链表中&#xff0c;每个节点除了有一个 next 指针指向下一个节点&#xff0c;还有一个 random 指针指向链表中的任意节点或者 null。 提示&#xff1a; -10000 < Node.val < 10000 Node.random 为…

windows server 2019 启动 nginx 报错

环境 &#xff1a;windows server 2019 &#xff0c;nginx-1.19.7 背景&#xff1a; 自己经常用这个 nginx 包作为 web 服务器。今天发现 部署到 server 2019 上直接报错了。这可是原生的包&#xff0c;我啥也没改&#xff0c;怎么可能报错。而且之前在 其他服务器用都没问题…