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

第 42 章 - Go语言 设计模式

在Go语言中,设计模式是一种被广泛接受的解决常见问题的最佳实践。这些模式可以分为三类:创建型模式、结构型模式和行为型模式。下面我将结合案例以及源代码对这三种类型的设计模式进行详细讲解。

创建型模式

创建型模式主要关注对象的创建过程,使系统独立于如何创建、组合和表示对象。

1. 单例模式 (Singleton Pattern)

单例模式确保一个类只有一个实例,并提供一个全局访问点。

package singletonimport "sync"type Singleton struct {// 可以添加其他字段
}var instance *Singleton
var once sync.Oncefunc GetInstance() *Singleton {once.Do(func() {instance = &Singleton{}})return instance
}
2. 工厂方法模式 (Factory Method Pattern)

工厂方法定义了一个创建对象的接口,但让子类决定实例化哪一个类。

package factorytype Product interface {Use()
}type ConcreteProductA struct{}func (p *ConcreteProductA) Use() {fmt.Println("Using Product A")
}type ConcreteProductB struct{}func (p *ConcreteProductB) Use() {fmt.Println("Using Product B")
}type Factory interface {CreateProduct() Product
}type ConcreteFactoryA struct{}func (f *ConcreteFactoryA) CreateProduct() Product {return &ConcreteProductA{}
}type ConcreteFactoryB struct{}func (f *ConcreteFactoryB) CreateProduct() Product {return &ConcreteProductB{}
}

结构型模式

结构型模式涉及如何组合类和对象以形成更大的结构。

1. 适配器模式 (Adapter Pattern)

适配器模式允许不同接口的对象通过适配器一起工作。

package adaptertype Target interface {Request() string
}type Adaptee struct{}func (a *Adaptee) SpecificRequest() string {return "Specific request from Adaptee"
}type Adapter struct {adaptee *Adaptee
}func (a *Adapter) Request() string {return a.adaptee.SpecificRequest()
}
2. 装饰器模式 (Decorator Pattern)

装饰器模式允许动态地给一个对象添加新的功能。

package decoratortype Component interface {Operation() string
}type ConcreteComponent struct{}func (c *ConcreteComponent) Operation() string {return "Base operation"
}type Decorator struct {component Component
}func (d *Decorator) Operation() string {return d.component.Operation() + " with additional functionality"
}

行为型模式

行为型模式关注对象之间的责任分配。

1. 观察者模式 (Observer Pattern)

观察者模式定义了对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。

package observertype Subject interface {Register(Observer)Deregister(Observer)NotifyAll()
}type Observer interface {Update(string)
}type ConcreteSubject struct {observers []Observer
}func (s *ConcreteSubject) Register(o Observer) {s.observers = append(s.observers, o)
}func (s *ConcreteSubject) Deregister(o Observer) {for i, obs := range s.observers {if obs == o {s.observers = append(s.observers[:i], s.observers[i+1:]...)break}}
}func (s *ConcreteSubject) NotifyAll() {for _, observer := range s.observers {observer.Update("New message from subject")}
}type ConcreteObserver struct{}func (o *ConcreteObserver) Update(message string) {fmt.Println("Received:", message)
}

以上是几种常见的设计模式及其在Go语言中的实现示例。每种模式都有其特定的应用场景和优势,在实际开发中合理使用可以帮助提高代码质量和可维护性。

当然,我们可以继续探讨更多设计模式及其在Go语言中的实现。接下来我将介绍几种额外的设计模式。

结构型模式 (续)

3. 组合模式 (Composite Pattern)

组合模式允许你以一致的方式处理单个对象和对象组。

package compositetype Component interface {Operation() string
}type Leaf struct{}func (l *Leaf) Operation() string {return "Leaf operation"
}type Composite struct {children []Component
}func (c *Composite) Add(child Component) {c.children = append(c.children, child)
}func (c *Composite) Remove(child Component) {for i, comp := range c.children {if comp == child {c.children = append(c.children[:i], c.children[i+1:]...)break}}
}func (c *Composite) Operation() string {var result stringfor _, child := range c.children {result += child.Operation()}return result
}

行为型模式 (续)

2. 策略模式 (Strategy Pattern)

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互换。

package strategytype Strategy interface {AlgorithmInterface()
}type ConcreteStrategyA struct{}func (s *ConcreteStrategyA) AlgorithmInterface() {fmt.Println("Algorithm A")
}type ConcreteStrategyB struct{}func (s *ConcreteStrategyB) AlgorithmInterface() {fmt.Println("Algorithm B")
}type Context struct {strategy Strategy
}func (c *Context) SetStrategy(strategy Strategy) {c.strategy = strategy
}func (c *Context) ExecuteStrategy() {c.strategy.AlgorithmInterface()
}
3. 命令模式 (Command Pattern)

命令模式将请求封装成对象,从而让你可以用不同的请求、队列或者日志来参数化其他对象。

package commandtype Command interface {Execute()
}type Receiver struct{}func (r *Receiver) Action() {fmt.Println("Action performed by receiver")
}type ConcreteCommand struct {receiver *Receiver
}func (c *ConcreteCommand) Execute() {c.receiver.Action()
}type Invoker struct {command Command
}func (i *Invoker) SetCommand(command Command) {i.command = command
}func (i *Invoker) Invoke() {i.command.Execute()
}

这些例子展示了如何使用Go语言实现不同的设计模式。每种模式都有其特定的适用场景,选择合适的模式能够帮助开发者构建更灵活、可扩展且易于维护的应用程序。

4. 状态模式 (State Pattern)

状态模式允许对象在其内部状态改变时改变其行为,看起来就像是改变了它的类一样。

package statetype State interface {Handle(context *Context)
}type Context struct {state State
}func (c *Context) SetState(state State) {c.state = state
}func (c *Context) Request() {c.state.Handle(c)
}type ConcreteStateA struct{}func (s *ConcreteStateA) Handle(context *Context) {fmt.Println("Handling in State A")// 过渡到另一个状态context.SetState(&ConcreteStateB{})
}type ConcreteStateB struct{}func (s *ConcreteStateB) Handle(context *Context) {fmt.Println("Handling in State B")// 可以过渡回State A或保持不变
}
5. 迭代器模式 (Iterator Pattern)

迭代器模式提供了一种方法来访问一个容器对象中的元素,而无需暴露其底层表示。

package iteratortype Iterator interface {HasNext() boolNext() interface{}
}type Aggregate interface {CreateIterator() Iterator
}type ConcreteAggregate struct {items []interface{}
}func (a *ConcreteAggregate) Add(item interface{}) {a.items = append(a.items, item)
}func (a *ConcreteAggregate) CreateIterator() Iterator {return &ConcreteIterator{items: a.items, index: 0}
}type ConcreteIterator struct {items []interface{}index int
}func (i *ConcreteIterator) HasNext() bool {return i.index < len(i.items)
}func (i *ConcreteIterator) Next() interface{} {if i.HasNext() {item := i.items[i.index]i.index++return item}return nil
}
6. 访问者模式 (Visitor Pattern)

访问者模式让你可以在不修改已有类的情况下添加新的操作。

package visitortype Visitor interface {VisitConcreteElementA(element *ConcreteElementA)VisitConcreteElementB(element *ConcreteElementB)
}type Element interface {Accept(visitor Visitor)
}type ConcreteElementA struct{}func (e *ConcreteElementA) Accept(visitor Visitor) {visitor.VisitConcreteElementA(e)
}type ConcreteElementB struct{}func (e *ConcreteElementB) Accept(visitor Visitor) {visitor.VisitConcreteElementB(e)
}type ConcreteVisitor1 struct{}func (v *ConcreteVisitor1) VisitConcreteElementA(element *ConcreteElementA) {fmt.Println("ConcreteVisitor1 visits ConcreteElementA")
}func (v *ConcreteVisitor1) VisitConcreteElementB(element *ConcreteElementB) {fmt.Println("ConcreteVisitor1 visits ConcreteElementB")
}type ConcreteVisitor2 struct{}func (v *ConcreteVisitor2) VisitConcreteElementA(element *ConcreteElementA) {fmt.Println("ConcreteVisitor2 visits ConcreteElementA")
}func (v *ConcreteVisitor2) VisitConcreteElementB(element *ConcreteElementB) {fmt.Println("ConcreteVisitor2 visits ConcreteElementB")
}

这些例子进一步展示了Go语言中如何使用设计模式来解决特定问题。每一种模式都有其独特的优势和适用场景,选择合适的模式对于构建高效、可维护的软件系统至关重要。

7. 中介者模式 (Mediator Pattern)

中介者模式定义了一个封装了一系列对象交互的对象,使得这些对象不再直接相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

package mediatortype Mediator interface {Notify(sender string, event string)
}type ConcreteMediator struct {colleague1 *Colleague1colleague2 *Colleague2
}func (m *ConcreteMediator) Notify(sender string, event string) {if sender == "Colleague1" && event == "A" {m.colleague2.React()} else if sender == "Colleague2" && event == "B" {m.colleague1.React()}
}type Colleague interface {SetMediator(mediator Mediator)React()
}type Colleague1 struct {mediator Mediator
}func (c *Colleague1) SetMediator(mediator Mediator) {c.mediator = mediator
}func (c *Colleague1) React() {fmt.Println("Colleague1 reacts")c.mediator.Notify("Colleague1", "A")
}type Colleague2 struct {mediator Mediator
}func (c *Colleague2) SetMediator(mediator Mediator) {c.mediator = mediator
}func (c *Colleague2) React() {fmt.Println("Colleague2 reacts")c.mediator.Notify("Colleague2", "B")
}
8. 备忘录模式 (Memento Pattern)

备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复对象到先前的状态。

package mementotype Memento struct {state string
}type Originator struct {state string
}func (o *Originator) CreateMemento() *Memento {return &Memento{state: o.state}
}func (o *Originator) RestoreFromMemento(m *Memento) {o.state = m.state
}func (o *Originator) ChangeState(newState string) {o.state = newState
}func (o *Originator) ShowState() {fmt.Printf("Current State: %s\n", o.state)
}type Caretaker struct {mementos []*Memento
}func (c *Caretaker) AddMemento(m *Memento) {c.mementos = append(c.mementos, m)
}func (c *Caretaker) GetMemento(index int) *Memento {if index < len(c.mementos) {return c.mementos[index]}return nil
}
9. 解释器模式 (Interpreter Pattern)

解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

package interpretertype Expression interface {Interpret(context string) bool
}type TerminalExpression struct{}func (te *TerminalExpression) Interpret(context string) bool {return context == "terminal"
}type OrExpression struct {expr1, expr2 Expression
}func (oe *OrExpression) Interpret(context string) bool {return oe.expr1.Interpret(context) || oe.expr2.Interpret(context)
}type AndExpression struct {expr1, expr2 Expression
}func (ae *AndExpression) Interpret(context string) bool {return ae.expr1.Interpret(context) && ae.expr2.Interpret(context)
}

通过上述例子,你可以看到如何在Go语言中应用各种行为型设计模式。每种模式都针对特定的问题提供了优雅的解决方案,有助于提高代码的质量和可维护性。希望这些信息对您有所帮助!

相关文章:

第 42 章 - Go语言 设计模式

在Go语言中&#xff0c;设计模式是一种被广泛接受的解决常见问题的最佳实践。这些模式可以分为三类&#xff1a;创建型模式、结构型模式和行为型模式。下面我将结合案例以及源代码对这三种类型的设计模式进行详细讲解。 创建型模式 创建型模式主要关注对象的创建过程&#xf…...

【机器学习】---大语言模型

引言&#xff1a;开启大语言模型的奇幻旅程 近年来&#xff0c;人工智能&#xff08;AI&#xff09;领域正在经历一场前所未有的技术革命&#xff0c;而其中最耀眼的明星莫过于大语言模型&#xff08;Large Language Models, LLMs&#xff09;。这些模型&#xff0c;犹如现代科…...

挑战用React封装100个组件【002】

项目地址 https://github.com/hismeyy/react-component-100 组件描述 组件适用于需要展示图文信息的场景&#xff0c;比如产品介绍、用户卡片或任何带有标题、描述和可选图片的内容展示 样式展示 代码展示 InfoCard.tsx import ./InfoCard.cssinterface InfoCardProps {t…...

MarkDown-插入图片-图片url地址的生成获取方法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、url地址是什么二、如何获取图片的url地址1.了解图床2.使用图床获取图片URL地址2.1进入网站后&#xff0c;点击右下角“Select Image.”按钮&#xff0c;即可…...

插值、拟合和回归分析的相关知识

目录 0 序言 1 分段线性插值 2 多项式插值 3 样条插值 4 最小二乘拟合 5 多元线性回归 0 序言 在生产实践和科学研究中&#xff0c;常常有这些问题: 插值问题&#xff1a;由实验或测量得到变量间的一批离散样点&#xff0c;要求得到变量之间的函数关系或得到样点之外的…...

【小白学机器学习42】进行多次抽样,样本的分布参数和总体的分布参数的关系

目录 1 进行多次抽样&#xff0c;样本的分布参数和总体的分布参数的关系 2 样本容量越大&#xff0c;多次抽样的样本的分布参数和总体的分布参数的关系 3 随着样本容量增大&#xff0c;多次抽样均值的 平均值&#xff0c;方差的变化 4 随着样本容量增大&#xff0c;多次抽…...

链动星海 质引未来|中信银行加码科技金融 “接力式”服务助力“新质生产力”释放

11月26日&#xff0c;第二届中国国际供应链促进博览会&#xff08;以下简称链博会&#xff09;在北京中国国际展览中心开幕。中信集团以“链动星海 质引未来”为主题&#xff0c;亮相先进制造链展区。此次布展由中信金控主办、中信银行承办&#xff0c;携手中信证券、中信建投证…...

黑马2024AI+JavaWeb开发入门Day02-JS-VUE飞书作业

视频地址&#xff1a;哔哩哔哩 讲义作业飞书地址&#xff1a;飞书 一、作业1 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">&l…...

云计算基础-期末复习

第一章&#xff1a;云计算概论 一、云计算的定义与特征 1. 定义&#xff1a; 云计算是一种通过网络以按需、可扩展的方式获取计算资源和服务的模式。它将计算资源视为一种公用事业&#xff0c;用户可以根据需求动态获取和释放资源&#xff0c;而无需了解底层基础设施的细节。…...

Java GET请求 请求参数在Body中使用Json格式传参

业务需要调个三方接口 使用GET请求方式 但是&#xff01;请求参数不在Query中&#xff0c;竟然在Body中&#xff0c;使用Json格式传参 在API调试工具里面可以调通 在java代码里&#xff0c;死活调不通 网上搜了搜&#xff0c;找到一个靠谱的&#xff0c;记录一下 import o…...

AI数据分析工具(一)

Looker Studio&#xff08;谷歌&#xff09;-免费 优点 免费使用&#xff1a;对于中小型企业和个人用户来说&#xff0c;没有任何费用压力&#xff0c;可以免费享受到数据可视化和报表创建的功能。与Google服务集成&#xff1a;特别适合使用Google产品生态的企业&#xff0c;…...

go结构体匿名“继承“方法冲突时继承优先顺序

在 Go 语言中&#xff0c;匿名字段&#xff08;也称为嵌入字段&#xff09;可以用来实现继承的效果。当你在一个结构体中匿名嵌入另一个结构体时&#xff0c;嵌入结构体的方法会被提升到外部结构体中。这意味着你可以直接通过外部结构体调用嵌入结构体的方法。 如果多个嵌入结…...

【049】基于51单片机语音录放【Proteus仿真+Keil程序+报告+原理图】

☆、设计硬件组成&#xff1a;51单片机最小系统ISD4004语音芯片LM386音频放大器喇叭LCD1602液晶显示按键控制LED灯。 1、本设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片&#xff0c;LCD1602液晶显示屏实时显示&#xff1b; 2、系统具有两种模式&#xff1a;录音…...

《软件项目管理》期末-复习题及参考答案

&#xff08;1&#xff09;赶工一个任务时&#xff0c;你应该关注&#xff08; C &#xff09; A. 尽可能多的任务 B. 非关键任务 C. 加速执行关键路径上的任务 D. 通过成本最低化加速执行任务 &#xff08;2&#xff09;下列哪个不是项目管理计划的一部分&#xff1f;&#x…...

milvus 通俗易懂原理

向量值如何生成的 Milvus 是一个开源的向量数据库&#xff0c;专门用于处理高维向量的存储、搜索和分析。向量值本身通常来自于某些机器学习或深度学习模型的输出&#xff0c;尤其是在自然语言处理&#xff08;NLP&#xff09;、计算机视觉&#xff08;CV&#xff09;、推荐系…...

什么是撞库、拖库和洗库?

“撞库”是黑客通过收集互联网已泄露的用户和密码信息&#xff0c;生成对应的字典表&#xff0c;尝试批量登陆其他网站后&#xff0c;得到一系列可以登录的用户。 很多用户在不同网站使用的是相同的帐号密码&#xff0c;因此黑客可以通过获取用户在A网站的账户从而尝试登录B网…...

安卓-碎片的使用入门

1.碎片(Fragment)是什么 Fragment是依赖于Activity的&#xff0c;不能独立存在的,是Activity界面中的一部分&#xff0c;可理解为模块化的Activity,它能让程序更加合理和充分地利用大屏幕的空间&#xff0c;因而在平板上应用得非常广泛. Fragment不能独立存在&#xff0c;必须…...

华为IPD流程学习之——深入解读123页华为IPD流程体系设计方法论PPT

该方案全面介绍了华为IPD流程体系设计方法论&#xff0c;包括流程体系建设的背景、理念、架构、核心特征、构建模型、与组织和战略的关系、运营机制、数字化转型以及流程管理组织等内容&#xff0c;旨在为企业提供一套系统的流程体系建设指导&#xff0c;以提升运营效率、质量和…...

DriveMLLM:一个专为自动驾驶空间理解任务设计的大规模基准数据集

2024-11-20&#xff0c; 由武汉大学、中国科学院自动化研究所、悉尼科技大学、牛津大学等合创建了DriveMLLM数据集&#xff0c;该数据集是自动驾驶领域首个专为评估多模态大型语言模型&#xff08;MLLMs&#xff09;空间理解能力而设计的基准&#xff0c;对于推动自动驾驶技术的…...

高效处理 iOS 应用中的大规模礼物数据:以直播项目为例(1-礼物池)

引言 在现代iOS应用开发中&#xff0c;处理大规模数据是一个常见的挑战。尤其实在直播项目中&#xff0c;礼物面板作为展示用户互动的重要部分&#xff0c;通常需要实时显示海量的礼物数据。这些数据不仅涉及到不同的区域、主播的动态差异&#xff0c;还需要保证高效的加载与渲…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...