当前位置: 首页 > 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数据库里相关对象的实际数据量,实际数据分布等详细信息。 -- 对…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...