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

15分钟学 Go 第 56 天:架构设计基本原则

第56天:架构设计基本原则

学习目标

理解和掌握基本的架构设计原则,以提升软件系统的可维护性、可扩展性和可重用性。

内容提纲

  1. 架构设计原则概述
  2. 常见架构设计原则
    • 单一职责原则 (SRP)
    • 开放/封闭原则 (OCP)
    • 里氏替换原则 (LSP)
    • 接口分离原则 (ISP)
    • 依赖反转原则 (DIP)
  3. 架构设计的最佳实践
  4. 示例代码
  5. 运行流程图
  6. 总结

1. 架构设计原则概述

架构设计原则是开发软件系统时用以指导设计和开发过程的基本准则。这些原则帮助开发者创建更优秀的软件架构,从而确保可维护性、可扩展性、可重用性和良好的性能。

2. 常见架构设计原则

2.1 单一职责原则 (SRP)

定义:一个类应该只有一个原因引起它的变化。换句话说,每个类应该专注于完成一项职责。

示例代码

package mainimport "fmt"// 用户管理类
type User struct {Name stringAge  int
}// 发送邮件功能
type EmailService struct{}func (es *EmailService) SendEmail(email string) {fmt.Printf("Sending email to %s\n", email)
}// 用户服务
type UserService struct {emailService *EmailService
}func (us *UserService) CreateUser(name string, age int, email string) {user := User{Name: name, Age: age}fmt.Printf("User created: %+v\n", user)us.emailService.SendEmail(email)
}func main() {emailService := &EmailService{}userService := &UserService{emailService: emailService}userService.CreateUser("Alice", 30, "alice@example.com")
}

运行流程图

+---------------------+
|  创建 UserService   |
|  +----------------+  |
|  | EmailService   |  |
|  +----------------+  |
+---------------------+|+---------------------+|  CreateUser        |+---------------------+|+---------------------+|  发送邮件          |+---------------------+

2.2 开放/封闭原则 (OCP)

定义:软件实体(类、模块、函数等)应当对扩展开放,对修改封闭。即,应该可以通过添加新功能或新代码来扩展系统,而不需要去修改现有的代码。

示例代码

package mainimport "fmt"// Shape 接口
type Shape interface {Area() float64
}// 矩形
type Rectangle struct {Width, Height float64
}func (r Rectangle) Area() float64 {return r.Width * r.Height
}// 圆
type Circle struct {Radius float64
}func (c Circle) Area() float64 {return 3.14 * c.Radius * c.Radius
}// 计算总面积
func TotalArea(shapes []Shape) float64 {total := 0.0for _, shape := range shapes {total += shape.Area()}return total
}func main() {shapes := []Shape{Rectangle{Width: 10, Height: 5},Circle{Radius: 7},}fmt.Printf("Total Area: %.2f\n", TotalArea(shapes))
}

运行流程图

+---------------------+
|   TotalArea        |
+---------------------+|
+----------+----------+
|                     |
|                     |
+                     +
|                     |
+--------+------------+
|  计算每个 Area     |
+---------------------+

2.3 里氏替换原则 (LSP)

定义:子类对象能够替换父类对象,并且在程序运行中不会影响程序的正常运行。

示例代码

package mainimport "fmt"// Bird 接口
type Bird interface {Fly() string
}// Sparrow 是 Bird 的实现
type Sparrow struct{}func (s Sparrow) Fly() string {return "Sparrow flying"
}// Ostrich 是 Bird 的实现,但不能飞
type Ostrich struct{}func (o Ostrich) Fly() string {return "Ostrich can't fly"
}// 使用 Bird 接口
func MakeBirdFly(bird Bird) {fmt.Println(bird.Fly())
}func main() {sparrow := Sparrow{}ostrich := Ostrich{}MakeBirdFly(sparrow) // 输出: Sparrow flyingMakeBirdFly(ostrich) // 输出: Ostrich can't fly
}

运行流程图

+---------------------+
|   MakeBirdFly      |
+---------------------+|
+----------+----------+
|                     |
|                     |
+                     +
|                     |
+--------+------------+
|  调用 Fly 方法     |
+---------------------+

2.4 接口分离原则 (ISP)

定义:客户端不应该被迫依赖于它不使用的方法。即接口应该尽可能的细小,客户端只需关注自身需要的方法。

示例代码

package mainimport "fmt"// 形状接口
type Shape interface {Area() float64
}// 3D 形状接口
type ThreeDimensionalShape interface {ShapeVolume() float64
}// 矩形
type Rectangle struct {Width, Height float64
}func (r Rectangle) Area() float64 {return r.Width * r.Height
}// 立方体
type Cube struct {Side float64
}func (c Cube) Area() float64 {return 6 * (c.Side * c.Side)
}func (c Cube) Volume() float64 {return c.Side * c.Side * c.Side
}func main() {var shapes []Shapeshapes = append(shapes, Rectangle{Width: 10, Height: 5})for _, shape := range shapes {fmt.Printf("Area: %.2f\n", shape.Area())}cube := Cube{Side: 3}fmt.Printf("Cube Area: %.2f, Volume: %.2f\n", cube.Area(), cube.Volume())
}

运行流程图

+---------------------+
|  计算形状面积      |
+---------------------+|
+----------+----------+
|                     |
|                     |
+                     +
|                     |
+--------+------------+
|  计算立方体体积    |
+---------------------+

2.5 依赖反转原则 (DIP)

定义:高层模块不应依赖于低层模块,二者应依赖于抽象(接口)。抽象不应依赖于细节,细节应依赖于抽象。

示例代码

package mainimport "fmt"// 数据库接口
type Database interface {Query() string
}// MySQL 数据库实现
type MySQL struct{}func (m MySQL) Query() string {return "Query from MySQL"
}// PostgreSQL 数据库实现
type PostgreSQL struct{}func (p PostgreSQL) Query() string {return "Query from PostgreSQL"
}// 数据库服务
type DatabaseService struct {db Database
}func (ds *DatabaseService) Execute() {fmt.Println(ds.db.Query())
}func main() {mysqlService := &DatabaseService{db: MySQL{}}mysqlService.Execute()  // 输出: Query from MySQLpostgresService := &DatabaseService{db: PostgreSQL{}}postgresService.Execute() // 输出: Query from PostgreSQL
}

运行流程图

+---------------------+
|  DatabaseService    |
+---------------------+|
+----------+----------+
|                     |
|                     |
+                     +
|                     |
+-------+-------------+
|  执行 Query 方法    |
+---------------------+

3. 架构设计的最佳实践

  • 模块化设计:将代码分为多个模块,每个模块负责特定功能,这提升了可读性和可维护性。
  • 高内聚低耦合:模块内部结构应保持高度一致性,而不同模块之间应保持低耦合,以便于代码的修改和重用。
  • 使用设计模式:设计模式有助于解决特定的架构问题,提升代码质量。
  • 自动化测试:通过单元测试和集成测试确保代码质量和系统可靠性。
  • 持续重构:在开发过程中保持代码质量,定期重构代码以适应新需求。

4. 示例代码的整体运行

以上代码展示了各种设计原则的实现方式。进行这些示例时,您可以在 Go 环境中逐一运行这些代码,并观察输出结果,帮助理解每个原则的应用。

代码的运行流程图展示了每个主要方法的调用路径,以及如何通过不同模块进行交互,体现了架构设计原则的有效性。

5. 运行流程图总结

每个示例中的运行流程图清晰地展示了不同组件之间的交互关系,帮助开发者理解各个设计原则如何有效整合,从而构成一个良好的软件架构。

6. 总结

熟练掌握架构设计原则是软件开发过程中的关键因素。这些原则不仅能够提升软件的质量和可维护性,同时也提高了团队的开发效率。通过实际案例的学习与实践,可以更好地理解和应用这些原则,为构建高质量的系统打下坚实的基础。


怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

相关文章:

15分钟学 Go 第 56 天:架构设计基本原则

第56天:架构设计基本原则 学习目标 理解和掌握基本的架构设计原则,以提升软件系统的可维护性、可扩展性和可重用性。 内容提纲 架构设计原则概述常见架构设计原则 单一职责原则 (SRP)开放/封闭原则 (OCP)里氏替换原则 (LSP)接口分离原则 (ISP)依赖反…...

HTML5 Video(视频)

HTML5 Video(视频) HTML5视频是现代网页设计中不可或缺的一部分,它允许开发者在网页中嵌入视频内容,为用户提供丰富多样的媒体体验。本文将深入探讨HTML5视频的各个方面,包括其基本用法、支持的格式、自定义播放器、浏览器兼容性以及最佳实践。 一、HTML5视频的基本用法 …...

开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-tool usage入门-串行调用多个tools(三)

一、前言 Qwen-Agent 是一个利用开源语言模型Qwen的工具使用、规划和记忆功能的框架。其模块化设计允许开发人员创建具有特定功能的定制代理,为各种应用程序提供了坚实的基础。同时,开发者可以利用 Qwen-Agent 的原子组件构建智能代理,以理解和响应用户查询。 本篇将介绍如何…...

MySQL:表设计

表的设计 从需求中获得类,类对应到数据库中的实体,实体在数据库中表现为一张一张的表,类中的属性就对应着表中的字段(也就是表中的列) 表设计的三大范式: 在数据库设计中,三大范式&#xff0…...

173. 二叉搜索树迭代器【 力扣(LeetCode) 】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 173. 二叉搜索树迭代器 一、题目描述 实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器: BSTIterato…...

大三学生实习面试经历(1)

最近听了一位学长的建议,不能等一切都准备好再去开始,于是就开始了简历投递,恰好简历过了某小厂的初筛,开启了线上面试,记录了一些问题: (通过面试也确实了解到了自己在某些方面确实做的还不够…...

【论文复现】STM32设计的物联网智能鱼缸

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀STM32设计的物联网智能鱼缸 【1】项目功能介绍【2】设计需求总结【3】项目硬件模块组成 1.2 设计思路【1】整体设计思路【2】ESP8266工作模式…...

常见长选项和短选项对应表

长选项和短选项的等效形式 在命令行工具中,这种长选项(如--delete)和短选项(如-d)等效的情况很常见。例如--verbose和-v(用于输出详细信息),--quiet和-q(用于安静模式&a…...

Ubuntu24 上安装搜狗输入法

link 首先在终端中依次输入以下代码 sudo apt update sudo apt install fcitx 找到语言支持 在终端中依次输入 sudo cp /usr/share/applications/fcitx.desktop /etc/xdg/autostart/ sudo apt purge ibus 进入网页 搜狗输入法linux-首页​ shurufa.sogou.com/linux 找到刚才下…...

【AI图像生成网站Golang】JWT认证与令牌桶算法

AI图像生成网站 目录 一、项目介绍 二、雪花算法 三、JWT认证与令牌桶算法 四、项目架构 五、图床上传与图像生成API搭建 六、项目测试与调试(等待更新) 三、JWT认证与令牌桶算法 在现代后端开发中,用户认证和接口限流是确保系统安全性和性能的两大关键要素…...

关于强化学习的一份介绍

在这篇文章中,我将介绍与强化学习有关的一些东西,具体包括相关概念、k-摇臂机、强化学习的种类等。 一、基本概念 所谓强化学习就是去学习:做什么才能使得数值化的收益信号最大化。学习者不会被告知应该采取什么动作,而是必须通…...

Python3.11.9+selenium,获取图片验证码以及输入验证码数字

Python3.11.9+selenium,获取图片验证码以及输入验证码数字 1、遇到问题:登录或修改密码需要验证码 2、解决办法: 2.1、安装ddddocr pip install ddddocr 2.2、解析验证码函数 import ddddocr def get_capcha_text():#获取验证码图片ele_pic = driver.find_element(By.XPAT…...

Flutter:事件队列,异步操作,链式调用。

Flutter分2种队列 1、事件队列:异步的处理,按顺序执行 import package:flutter/material.dart; main(){testFuture1();testFuture2(); }// 按顺序执行处理A->B->C testFuture1() async {Future((){return 任务A;}).then((value){print(按顺序执行&…...

从零开始学习 sg200x 多核开发之 eth0 自动使能并配置静态IP

前文提到 sophpi 默认没有使能有线网络,需要手工配置: [rootsg200x]~# ifconfig eth0 up [rootsg200x]~# udhcpc -i eth0 [rootsg200x]~# ifconfig eth0 Link encap:Ethernet HWaddr EA:BD:18:08:1E:87 inet addr:192.168.188.142 Bcast:192.1…...

《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信

《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信 《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信进程间通信的基本概念通过管道实现进程间通信通过管道进行进程间双向通信 运用进程间通信习题(1)什么是进程间通信&…...

开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-tool usage入门-集成心知天气(二)

一、前言 Qwen-Agent 是一个利用开源语言模型Qwen的工具使用、规划和记忆功能的框架。其模块化设计允许开发人员创建具有特定功能的定制代理,为各种应用程序提供了坚实的基础。同时,开发者可以利用 Qwen-Agent 的原子组件构建智能代理,以理解和响应用户查询。 本篇将介绍如何…...

通过声纹或者声波来切分一段音频

通过声纹识别或基于声波特征的模型,确实可以帮助切分一段音频并区分出不同讲话者的语音片段。这种技术被称为 基于声纹的语音分割 或 基于说话人识别的音频分割。其核心原理是利用每个说话者的 声纹特征(即每个人独特的语音特征)来识别和切分…...

sql专场练习(二)(16-20)完结

第十六题 用户登录日志表为user_id,log_id,session_id,visit_time create table sql2_16(user_id int,log_id int,session_id int,visit_time string );没有数据 visit_time 时间格式为2024-11-15 用sql查询近30天每天平均登录用户数量 with t1 as (select visit_time,coun…...

[ 网络安全介绍 2 ] 网络安全发展现状

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

《基于Oracle的SQL优化》读书笔记

查看执行计划set autotrace traceonly explain在当前session中将优化器模式改为RULE。alter session set optimizer_modeRULE;统计信息存储在oracle的数据字典里,且从多个维度描述了oracle数据库里相关对象的实际数据量,实际数据分布等详细信息。 -- 对…...

Vulkan与OpenGL深度解析——现代图形渲染的技术演进

1. 从OpenGL到Vulkan:图形渲染的进化之路 还记得我第一次接触图形编程时,OpenGL就像一位和蔼的老教授,把复杂的GPU操作封装成简单的API调用。但随着项目复杂度提升,我逐渐发现这位"老教授"的教学方式有些过时——它隐藏…...

如何快速掌握React Email Editor:深入理解拖拽邮件编辑器的实现原理

如何快速掌握React Email Editor:深入理解拖拽邮件编辑器的实现原理 【免费下载链接】react-email-editor Drag-n-Drop Email Editor Component for React.js 项目地址: https://gitcode.com/gh_mirrors/re/react-email-editor React Email Editor是一个功能…...

华为MateBook D14安装Ubuntu16避坑指南:WiFi/蓝牙/触控板驱动一键搞定

华为MateBook D14安装Ubuntu 16.04驱动优化全攻略 华为MateBook D14作为一款高性价比轻薄本,在安装Ubuntu 16.04时可能会遇到WiFi、蓝牙和触控板驱动不兼容的问题。这主要源于硬件迭代速度远超Linux内核更新周期——你的笔记本搭载了新一代无线网卡和输入设备&#…...

嵌入式软件架构设计:硬件抽象层实践

嵌入式软件架构设计:建立硬件抽象层的工程实践 1. 嵌入式软件架构概述 1.1 架构设计的必要性 在嵌入式系统开发中,软件架构设计直接影响产品的可维护性、可扩展性和可移植性。良好的架构设计能够: 减少不必要的返工 建立宏观层面的开发规…...

LFM2.5-1.2B-Thinking-GGUF应用场景:智能硬件说明书问答机器人落地实践

LFM2.5-1.2B-Thinking-GGUF应用场景:智能硬件说明书问答机器人落地实践 1. 项目背景与需求 在智能硬件领域,产品说明书往往存在以下痛点: 内容专业术语多,普通用户难以理解纸质说明书查找信息效率低不同型号产品差异导致用户混…...

Matlab散点图进阶:如何用颜色、大小和形状搞定六维数据可视化(附完整代码)

Matlab散点图进阶:如何用颜色、大小和形状搞定六维数据可视化(附完整代码) 在数据分析领域,我们常常需要处理包含多个维度的复杂数据集。传统的二维或三维图表已经无法满足这类数据的可视化需求。本文将深入探讨如何利用Matlab的s…...

基于粒子群优化算法的永磁同步电机PMSM参数辨识:‘粒子群迭代‘至‘再次循环或结束

基于粒子群优化算法的永磁同步电机PMSM参数辨识 关键词:永磁同步电机 粒子群优化算法 参数辨识 ① 粒子群迭代 ②更新速度并对速度进行边界处理 ③更新位置并对位置进行边界处理 ④进行自适应变异 ⑤进行约束条件判断并计算新种群各个个体位置的适应度 ⑥新适应度与…...

VirtualBox虚拟机磁盘空间分配技巧:如何用动态分配40G空间玩转Debian 12

VirtualBox磁盘空间动态分配实战:以Debian 12为例的40GB高效配置指南 在虚拟化技术日益普及的今天,VirtualBox作为一款开源免费的虚拟化工具,凭借其跨平台特性和易用性,成为众多开发者和技术爱好者的首选。然而,许多用…...

别再手动折腾了!用Docker一键部署Oracle 11g开发环境(附阿里云镜像地址)

告别繁琐配置:Docker容器化Oracle 11g开发环境实战指南 每当新项目需要搭建Oracle开发环境时,开发者们总会面临相同的困境——数小时的安装配置、复杂的系统依赖、难以复现的环境问题。传统安装方式不仅消耗宝贵时间,更可能因系统差异导致团…...

如何5分钟构建专业级黑苹果EFI?OpCore Simplify让复杂配置一键搞定

如何5分钟构建专业级黑苹果EFI?OpCore Simplify让复杂配置一键搞定 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 副标题:告别…...