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

这些Coding套路你不会还不知道吧?

对于一名程序员来说,编码进阶是成为优秀工程师非常重要的一步,它可以让我们更加熟练地掌握编程,深入理解数据结构和算法,从而更好地完成复杂的任务,提高工作效率。而我认为熟练使用设计模式就是编码进阶的最好方式之一,下面就用一篇文章来分享下Go开发中常用的设计模式。

  • 1️⃣全局单一实例:单例模式

  • 🚗获取对象超简单:工厂模式

  • 📋重复代码太多?试试:模板方法模式

  • 👻接口对应功能不知道怎么维护?这里有:策略模式

  • 🎈独特好玩的Functional Options模式

What?Why?

从两个问题开始今天的分享:

设计模式是什么?

简单来讲,就两个字:套路,编码的套路,在我们写代码的时候这个套路可以不用,但是不能不知道。

为什么要使用设计模式?

设计模式是一种被反复使用的,针对软件设计中常见问题的可复用解决方案。它们提供了一种经过验证的方式来解决复杂的设计问题,并帮助开发人员编写更加清晰、可维护和可扩展的代码

使用设计模式的好处包括:

  1. 提高代码的可读性和可维护性。通过使用设计模式,开发人员可以将复杂的问题分解成更小、更易于管理的部分,并且可以将这些部分组织成一致的、易于理解的代码结构。
  2. 提高代码的可重用性。设计模式提供了一种标准化的解决方案,可以让相同的功能代码在多个地方重复使用,从而避免了重复编写相同的代码,减少了开发时间和成本。
  3. 提高代码的灵活性和扩展性。设计模式允许开发人员在不改变现有代码的情况下,轻松地添加新的功能或修改现有的功能。

常见的设计模式实践

1 全局单一实例:单例模式

首先,单例模式一般用于以下业务场景:

(1)整个程序的运行中只允许有一个类的实例。

(2)创建对象时耗时过多或者耗资源过多,但又经常用到的。

(3)需要全局访问并保证线程安全的对象。

(4)需要保持状态的对象。

具体场景:

数据库连接对象。我们在具体的项目中往往每种数据库驱动只会使用它的一个实例,因此在这里我们就能够使用单例模式。

代码:

import "sync"type MysqlConn struct {Addr string
}var (mysqlConn *MysqlConnonce = sync.Once{}
)func GetMySQLConn() *MysqlConn {once.Do(func() {mysqlConn = &MysqlConn{Addr: "127.0.0.1"}})return mysqlConn
}

2 获取对象超简单:工厂模式

工厂模式通常应用于以下场景:

(1)当一个系统需要灵活地配置一组对象,并且需要动态地选择其中的一个时。

(2)当一个类需要频繁地创建和销毁时,可以使用工厂模式来提高性能。

具体场景:

简单来讲就是想要获取一个实例,但是这个实例的属性可能会随着参数的变化而具有不同的形态,还可以用数据库连接来举例,我们有多个服务器可以进行连接,但是每次只能连接一个,而且连接的时候可以填写自己的认证账密。

代码:

type DB struct {Addr, UserName, Passwd string
}func NewMysqlConn(addr, userName, passwd string) *DB {return &DB{Addr:     addr,UserName: userName,Passwd:   passwd,}
}

3 重复代码太多?试试:模板方法模式

模板方法模式通常应用于以下场景:

(1)当一个算法的步骤中有一部分是不变的,而另一部分是需要根据不同的条件进行变化时,可以使用模板方法模式来实现。

(2)当一个类的子类需要实现一个接口的不同版本时,可以使用模板方法模式来实现。

具体场景:

做水果酸奶,水果或其他食材是统一的抽象,而火龙果、芒果、饼干都是具体,因为不管用什么水果或食材来做,做法都是如出一辙的,所以做法也是一个抽象,这就好比一个模板,对,就是模版方法模式。

代码:

import ("fmt""testing"
)type MakeYogurtTemplate interface {CreateYogurt() //准备好酸奶CutFruit()     //切水果Merge()        //放在一起搅拌Optimize()     //调制味道Eating()       //开吃Do()
}type DragonFruit struct {
}func (d *DragonFruit) CreateYogurt() {fmt.Println("用鲜奶和乳酸菌发酵好酸奶")
}func (d *DragonFruit) CutFruit() {fmt.Println("把火龙果切成块块")
}func (d *DragonFruit) Merge() {fmt.Println("放在一起进行搅拌")
}func (d *DragonFruit) Optimize() {fmt.Println("调制出自己喜欢的味道")
}func (d *DragonFruit) Eating() {fmt.Println("开吃")
}func (d *DragonFruit) Do() {d.CreateYogurt()d.CutFruit()d.Merge()d.Optimize()d.Eating()
}func TestDragonFruit(t *testing.T) {d := &DragonFruit{}d.Do()
}type Mango struct {
}func (m *Mango) CreateYogurt() {fmt.Println("用鲜奶和乳酸菌发酵好酸奶")
}func (m *Mango) CutFruit() {fmt.Println("把芒果切成块块")
}func (m *Mango) Merge() {fmt.Println("放在一起进行搅拌")
}func (m *Mango) Optimize() {fmt.Println("调制出自己喜欢的味道")
}func (m *Mango) Eating() {fmt.Println("开吃")
}func (m *Mango) Do() {m.CreateYogurt()m.CutFruit()m.Merge()m.Optimize()m.Eating()
}func TestMango(t *testing.T) {m := &Mango{}m.Do()
}

4 接口对应功能不知道怎么维护?这里有:策略模式

策略模式通常在一个系统中需要多个算法,并且这些算法需要在不同的时间或条件下使用不同的算法时,可以使用策略模式来实现。

具体场景:

对于新手程序员同学经常会有这样的选择,到底是学Go还是学Java,这显然是两种不同的策略选择,但是不管是学习哪一个的基本流程都是差不多的,比如都是先准备学习资料,然后在学习和实践,因此可以基于此使用策略模式来形容。

代码:

策略抽象

type Learn interface {PrepareData()DoLearn()Play()
}func LearnLang(l Learn) {l.PrepareData()l.DoLearn()l.Play()
}

策略1

import "fmt"type LikeGo struct {
}func (g *LikeGo) PrepareData() {fmt.Println("准备Go资料")
}func (g *LikeGo) DoLearn() {fmt.Println("学习Go")
}func (g *LikeGo) Play() {fmt.Println("玩转Go语言")
}

策略2

import "fmt"type LikeJava struct {
}func (g *LikeJava) PrepareData() {fmt.Println("准备Java资料")
}func (g *LikeJava) DoLearn() {fmt.Println("学习Java")
}func (g *LikeJava) Play() {fmt.Println("玩Java")
}

执行策略

import "testing"func TestLearn(t *testing.T) {likeGo := &LikeGo{}LearnLang(likeGo)
}

5 独特好玩的Functional Options模式

Functional Options模式通常在当一个对象或函数具有多个参数时,这些参数可能会有不同的默认值或取值范围。通过将它们作为函数的选项传递,可以更灵活地控制函数的行为

具体场景:

gRPC服务进行实例化的时候有些参数可以不同填,即选填,之后在源码内部会使用默认的值,于是我们就可以使用以下的方式进行处理。

代码:

import "time"type RpcServer struct {Name    stringMaxConn intAddress []stringTimeOut time.Duration
}type RpcServerOption func(server *RpcServer)func WithName(name string) RpcServerOption {return func(server *RpcServer) {server.Name = name}
}func WithMaxConn(max int) RpcServerOption {return func(server *RpcServer) {server.MaxConn = max}
}func WithAddress(addr []string) RpcServerOption {return func(server *RpcServer) {server.Address = addr}
}func WithTimeOut(timeout time.Duration) RpcServerOption {return func(server *RpcServer) {server.TimeOut = timeout}
}func NewRpcServer(opts ...RpcServerOption) *RpcServer {server := &RpcServer{}for _, opt := range opts {opt(server)}return server
}

实例化:

import ("fmt""testing""time"
)func TestCreateRpcServerByOptions(t *testing.T) {rpcServer := NewRpcServer(WithAddress([]string{"127.0.0.1"}),WithName("rpcServer"),WithMaxConn(1),WithTimeOut(time.Second),)fmt.Println(*rpcServer)
}

小总结

本文主要介绍了Go开发中常用的设计模式,包括全局单一实例:单例模式、工厂模式、模板方法模式、策略模式和Functional Options模式。这些设计模式可以帮助我们更好地组织代码,提高代码的可读性和可重用性。

总之,掌握这些设计模式对于提高Go程序员的编码能力非常有帮助,可以让我们在编写代码时更加得心应手,同时也能提高代码的质量和可维护性。

相关文章:

这些Coding套路你不会还不知道吧?

对于一名程序员来说,编码进阶是成为优秀工程师非常重要的一步,它可以让我们更加熟练地掌握编程,深入理解数据结构和算法,从而更好地完成复杂的任务,提高工作效率。而我认为熟练使用设计模式就是编码进阶的最好方式之一…...

Spring Boot深度解析:快速开发的秘密

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

mysql数据库备份(mysqldump)

mysqldump命令备份数据 mysqldump -u root -p --databases 数据库1 数据库2 > xxx.sqlmysqldump常用操作示例 1. 备份全部数据库的数据和结构 mysqldump -uroot -p123456 -A > /data/mysqlbackup/mydb.sql2. 备份全部数据库的结构(加 -d 参数) …...

linux Nginx+Tomcat负载均衡、动静分离

linux NginxTomcat负载均衡、动静分离 1、Tomcat的基本介绍1.1Tomcat是什么?1.2Tomcat的构成组件1.3Tomcat的核心功能1.4Tomcat请求过程 2、Tomcat部署2.1安装tomcat2.2优化tomcat启动速度2.4主要目录说明 3、Tomcat 虚拟主机配置3.1创建fsj和mws项目目录和文件3.2修…...

ts 枚举类型原理及其应用详解

ts 枚举类型介绍 TypeScript的枚举类型是一种特殊的数据类型,它允许开发者为一组相关值定义一个共同的名称,使我们可以更清晰、更一致地使用这些值。 枚举类型在TypeScript中用enum关键字定义,每个枚举值默认都是数字类型,从0开…...

腾讯mini项目-【指标监控服务重构】2023-08-23

今日已办 进度和问题汇总 请求合并 feature/venus tracefeature/venus metricfeature/profile-otel-baserunner-stylebugfix/profile-logger-Syncfeature/profile_otelclient_enable_config 完成otel 开关 trace-采样metrice-reader 已经都在各自服务器运行,并接入…...

C- ssize_t size_t

size_t 和 ssize_t 都是在 C 和 C 的标准库中定义的数据类型,它们通常用于表示大小和长度。然而,它们有关键的区别。 size_t: 定义:size_t 是一个无符号整数类型,它是适合表示对象的大小的类型。在 POSIX 中,它也用于…...

ubuntu20.04 Supervisor 开机自启动脚本一文配置

前言: 最近发现一种非常好的开机启动服务方式,不光可以开机自启动,而且还可以进行开机节点的进程守护,这样大大确保了线程的稳定情况,这种服务甚至可以守护开机的进程,所以比之前设置 rc.local 开机自启动脚本一文配置节点好出很多,它甚至可以使用网页登录监管我开机自启…...

【面试刷题】——函数指针和指针函数

“函数指针”(function pointer)和 “指针函数”(pointer to function)是两个不同的概念,它们涉及到指针和函数的结合使用。 函数指针(Function Pointer): 函数指针是指向函数的指…...

目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)

目标分类 一、目标分类介绍1.1 二分类和多分类的区别1.2 单标签和多标签输出的区别 二、代码获取三、数据集准备四、环境搭建4.1 环境测试 五、模型训练六、模型测试6.1 多标签训练-单标签输出结果6.2 多标签训练-多标签输出结果 一、目标分类介绍 目标分类是一种监督学习任务…...

【100天精通Python】Day61:Python 数据分析_Pandas可视化功能:绘制饼图,箱线图,散点图,散点图矩阵,热力图,面积图等(示例+代码)

目录 1 Pandas 可视化功能 2 Pandas绘图实例 2.1 绘制线图 2.2 绘制柱状图 2.3 绘制随机散点图 2.4 绘制饼图 2.5 绘制箱线图A 2.6 绘制箱线图B 2.7 绘制散点图矩阵 2.8 绘制面积图 2.9 绘制热力图 2.10 绘制核密度估计图 1 Pandas 可视化功能 pandas是一个强大的数…...

2023华为产品测评官-开发者之声 | 华为云CodeArts征文活动,多重好礼邀您发声!

"2023华为产品测评官-开发者之声"活动激发了众多开发者和技术爱好者的热情,他们纷纷递交了精心编写的产品测评报告。活动社群充满活力,参与者们热衷于交流讨论,互相帮助解决问题,一起探索云技术的无限可能。…...

Python 图形化界面基础篇:获取文本框中的用户输入

Python 图形化界面基础篇:获取文本框中的用户输入 引言 Tkinter 库简介步骤1:导入 Tkinter 模块步骤2:创建 Tkinter 窗口步骤3:创建文本框步骤4:获取文本框中的用户输入步骤5:启动 Tkinter 主事件循环 完整…...

【驱动开发】实现三盏灯的控制,编写应用程序测试

head.h #ifndef __HEAD_H__ #define __HEAD_H__//LED1:PE10 //LED2:PF10 //LED3:PE8#define LED_RCC 0X50000A28 //使能GPIO#define LED_MODER 0X50006000 //设置输出模式 #define LED_ODR 0X50006014 //设置输出高低电平#define LED2_MODER 0X50007000 …...

Vue3+ElementUI使用

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><meta name"viewport" content"initial-scale1.0,maximum-scale1.0,minimum-scale1.0,user-scalable0, widthdevice-width"/><!-- 引入样式 --><lin…...

MySQL 和 MariaDB 版本管理的历史背景及差异

目录 MariaDB MySQL 差异 关于 SQLE SQLE 获取 ​ 了解更多 需要说明的是 MySQL 和 MariaDB 都有社区版和企业版。对于 MySQL&#xff0c;这两个版本都是由同一家公司&#xff08;Oracle&#xff09;提供&#xff0c;遵循相同的版本编号体系&#xff0c;企业版包含更丰富…...

linux驱动开发--day4(字符设备驱动注册内部流程、及实现备文件和设备的绑定下LED灯实验)

一、字符设备驱动注册的内部过程 1.分配struct cdev对象空间 2.初始化struct cdev对象 3.注册cdev对象 二、注册字符设备驱动分步实现 1.分配字符设备驱动对象 2.字符设备驱动对象初始化 3.设备号的申请 4.根据申请的设备号和驱动对象注册驱动 三、open函数回调驱动中…...

elasticsearch5-RestAPI操作

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…...

数据结构与算法(一)

文章目录 数据结构与算法(一)1 位运算、算法是什么、简单排序1.1 实现打印一个整数的二进制1.2 给定一个参数N,返回1!+2!+3!+4!+...+N!的结果1.3 简单排序算法2 数据结构大分类、前缀和、对数器2.1 实现前缀和数组2.2 如何用1\~5的随机函数加工出1\~7的随机函数2.3 如何把不…...

Matlab--微积分问题的计算机求解

目录 1.单变量函数的极限问题 1.1.公式例子 1.2.对应例题 1 2.多变量函数的极限问题 3.函数导数的解析解 4.多元函数的偏导数 5.Jacobian函数 6.Hessian矩阵 7.隐函数的偏导 8.不定积分问题的求解 9.定积分的求解问题 10. 多重积分的问题求解 1.单变量函数的极限问题 …...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

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

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

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...