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.mzph.cn/news/887406.shtml

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

相关文章

Unity中动态生成贴图并保存成png图片实现

实现原理&#xff1a; 要生成长x宽y的贴图&#xff0c;就是生成x*y个像素填充到贴图中&#xff0c;如下图&#xff1a; 如果要改变局部颜色&#xff0c;就是从x1到x2(x1<x2),y1到y2(y1<y2)这个范围做处理&#xff0c; 或者要想做圆形就是计算距某个点&#xff08;x1,y1&…

互联网直播/点播EasyDSS视频推拉流平台视频点播有哪些技术特点?

在数字化时代&#xff0c;视频点播应用已经成为我们生活中不可或缺的一部分。监控技术与视频点播的结合正悄然改变着我们获取和享受媒体内容的方式。这一变革不仅体现在技术层面的进步&#xff0c;更深刻地影响了我们。 EasyDSS视频直播点播平台是一款高性能流媒体服务软件。E…

1语言基础

数据结构与算法可以说是每位程序员的必修课&#xff0c;即使是AI高速发展的今天&#xff0c;熟悉数据结构与算法都无疑是面向开发的一项加分项。先从一个问题看起&#xff1a; # 怎么让后面不带空格 print("11",11) # 11 2方案可能有更多&#xff0c;就像一个问题&am…

Redis 可观测最佳实践

Redis 介绍 Redis 是一个开源的高性能键值对&#xff08;key-value&#xff09;数据库。它通常用作数据库、缓存和消息代理。Redis 支持多种类型的数据结构&#xff0c;Redis 通常用于需要快速访问的场景&#xff0c;如会话缓存、全页缓存、排行榜、实时分析等。由于其高性能和…

【前端】JavaScript 变量声明和函数声明的提升机制:深入探讨提升优先级与其行为

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;提升&#xff08;Hoisting&#xff09;概述&#x1f4af;提升机制——函数声明 vs 变量声明&#x1f4af;代码示例&#xff1a;函数与 var 的提升提升后的代码解析分析 …

fastadmin实现站内通知功能

实现效果如下 application/admin/view/common/header.html <style>#notificationMenu {display: none;position: absolute;top: 40px;right: 0;background: #fff;border-radius: 6px;padding: 10px 0;width: 300px;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);z-inde…

Axure RP教程:创建高效用户界面和交互

Axure RP是一款广受好评的软件&#xff0c;专门用于设计精致的用户界面和交互体验。这款软件提供了众多UI控件&#xff0c;并根据它们的用途进行了分类。与此同时&#xff0c;国产的即时设计软件作为Axure的替代品&#xff0c;支持在线协作和直接在浏览器中使用&#xff0c;无需…

2024-11-25 二叉树的定义

一、基本概念 1.二叉树是n(n>0)个结点的有限集合: ① 或者为空二叉树&#xff0c;即n0。 ②或者由一个根结点和两个互不相交的被称为根的左子树和右子树组成。左子树和右子树又分别是一棵二叉树。 特点&#xff1a; ①每个结点至多只有两棵子树。 ②左右子树不能颠倒&am…

部署实战(二)--修改jar中的文件并重新打包成jar文件

一.jar文件 JAR 文件就是 Java Archive &#xff08; Java 档案文件&#xff09;&#xff0c;它是 Java 的一种文档格式JAR 文件与 ZIP 文件唯一的区别就是在 JAR 文件的内容中&#xff0c;多出了一个META-INF/MANIFEST.MF 文件META-INF/MANIFEST.MF 文件在生成 JAR 文件的时候…

对象的大小

文章目录 一、对象大小 一、对象大小 对象是类实例化出来的&#xff0c;让我们分析一下类对象中哪些成员呢&#xff1f; 类实例化出的每个对象&#xff0c;每个都有独立的数据空间&#xff0c;所以对象中肯定包含 成员变量&#xff0c;那么成员函数是否包含呢&#xff1f; 首…

01-go入门

文章目录 Go语言学习1. 简介安装windows安装linux安装编译工具安装-goland 2. 入门2.1 Helloworld注释 2.2 变量初始化打印内存地址变量交换匿名变量作用域局部变量全局变量 2.3 常量iota 2.4 数据类型布尔整数浮点类型复数字符串定义字符串字符串拼接符定义多行字符串 map数据…

数据库的联合查询

数据库的联合查询 简介为什么要使⽤联合查询多表联合查询时MYSQL内部是如何进⾏计算的构造练习案例数据案例&#xff1a;⼀个完整的联合查询的过程 内连接语法⽰例 外连接语法 ⽰例⾃连接应⽤场景示例表连接练习 ⼦查询语法单⾏⼦查询多⾏⼦查询多列⼦查询在from⼦句中使⽤⼦查…

LeetCode-632. Smallest Range Covering Elements from K Lists [C++][Java]

目录 题目描述 解题思路 【C】 【Java】 LeetCode-632. Smallest Range Covering Elements from K Listshttps://leetcode.com/problems/smallest-range-covering-elements-from-k-lists/description/ 题目描述 You have k lists of sorted integers in non-decreasing o…

UI自动化测试中公认最佳的设计模式-POM

一、概念 什么是POM&#xff1f; POM是PageObjectModule&#xff08;页面对象模式&#xff09;的缩写&#xff0c;其目的是为了Web UI测试创建对象库。在这种模式下&#xff0c;应用涉及的每一个页面应该定义为一个单独的类。类中应该包含此页面上的页面元素对象和处理这些元…

Scala文件读写——成绩分析

根据文件解决下例问题 1.读入txt文件&#xff1a;按行读入 import scala.io.Sourceobject Test文件读写_成绩分析 {def main(args: Array[String]): Unit {//1.按行读入val source Source.fromFile("score.txt")val it source.getLines()it.next()//跳过第一行wh…

C# Winform 俄罗斯方块小游戏源码

文章目录 1.设计来源俄罗斯方块小游戏讲解1.1 主界面1.2 游戏界面1.3 游戏结束界面1.4 配置游戏界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;https:…

前端框架Vue3——响应式数据,v-on,v-show和v-if,v-for,v-bind

Vue的定义为渐进式的JavaScript框架。所谓渐进式&#xff0c;是指其被设计 为可以自底向上逐层应用。我们可以只使用Vue框架中提供的某层的功 能&#xff0c;也可以与其他第三方库整合使用。当然&#xff0c;Vue本身也提供了完整的 工具链&#xff0c;使用其全套功能进行项目的…

实验二 系统响应及系统稳定性

实验目的 &#xff08;1&#xff09;学会运用Matlab 求解离散时间系统的零状态响应&#xff1b; &#xff08;2&#xff09;学会运用Matlab 求解离散时间系统的单位取样响应&#xff1b; &#xff08;3&#xff09;学会运用Matlab 求解离散时间系统的卷积和。 实验原理及实…

.NET Core发布网站报错 HTTP Error 500.31

报错如图&#xff1a; 解决办法&#xff1a; 打开任务管理器》》服务》》找到这仨服务&#xff0c;右键启动即可&#xff0c;如果已经启动了就重启&#xff1a;

麒麟安全增强-kysec

DAC: 自主访问控制是linux下默认的接入控制机制,通过对资源读、写、执行操作,保证系统安全 MAC:安全接入控制机制,由操作系统约束的访问控制,默认情况下,MAC不允许任何访问,用户可以自定义策略规则制定允许什么 ,从而避免很多攻击。 MAC强制访问控制常见的实现方式:…