第 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语言中应用各种行为型设计模式。每种模式都针对特定的问题提供了优雅的解决方案,有助于提高代码的质量和可维护性。希望这些信息对您有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/61336.shtml

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

相关文章

深度学习编译器

目录 深度学习编译器 深度学习编译器的原理 举例说明 深度学习编译器 在提高并行训练可编程性方面扮演着至关重要的角色,尤其是在面对大规模智能算法开发时。下面,我将简单解释深度学习编译器的原理,并通过一个例子来说明其重要性。 深度学习编译器的原理 深度学习编译…

wordpress网站首页底部栏显示网站备案信息

一、页脚文件footer.php 例如&#xff0c;wordpress主题使用的是simple-life主题&#xff0c;服务器IP为192.168.68.89,在wordpress主题文件中有个页脚文件footer.php&#xff0c;这是一个包含网站页脚代码的文件。 footer.php 路径如下&#xff1a; /www/wwwroot/192.168.68…

使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件

前言 记录一下使用 Vite 创建 Vue3TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件。 一、使用 Vite 创建 Vue3TS 项目 1.新建一个 temp 文件夹 &#xff08;1&#xff09;在桌面新建一个 temp 文件夹&#xff0c;然后在 VS Code 中打开此文件夹&…

【sqlcipher】pc端sqflite使用过程中遇到的问题

在flutter中使用sqlcipher时 Mac上如果通过flutter带的文件管理api&#xff08;即File的delete()方法&#xff09;删除数据库文件&#xff0c;再创建同名的数据文件的话&#xff0c;必现readonly问题&#xff0c; 这里需要注意的一点是 DatabaseFactory 在Mac上直接使用全局的…

Dubbo的RPC泛化调用

目录 一、RPC泛化调用的应用场景 二、Dubbo RPC泛化调用的实现原理 三、Dubbo RPC泛化调用的实现步骤 四、示例代码 五、泛化调用怎么发现提供该接口的服务及服务的IP和端口&#xff1f; Dubbo的RPC泛化调用是一种在调用方没有服务方提供的API的情况下&#xff0c;对服务方…

使用uni-app进行开发前准备

使用uni-app进行开发&#xff0c;需要遵循一定的步骤和流程。以下是一个详细的指南&#xff0c;帮助你开始使用uni-app进行开发&#xff1a; 一、开发环境搭建 安装Node.js&#xff1a; 首先&#xff0c;从Node.js的官方网站&#xff08;https://nodejs.org/&#xff09;下载并…

ssh的隧道连接(端口映射)

SSH 隧道&#xff08;SSH tunneling&#xff09;的命令&#xff1a;用于将本地计算机的端口与远程服务器上的端口进行映射 命令&#xff1a; ssh -L 本地端口:localhost:服务器端口 -p 22 用户名服务器ip ssh: 表示使用 SSH 协议连接远程服务器。 -L 8501:localhost:8501: 这部…

AI需求条目化全面升级!支持多格式需求,打破模板限制!

AI需求条目化全面升级&#xff01;支持多格式需求&#xff0c;打破模板限制&#xff01; 一、多格兼济 标准立成 1、功能揭秘 预览未来 平台需求板块的AI需求条目化功能迎来全面升级。它支持多种需求格式&#xff0c;不再受限于模板文件&#xff0c;能够一键自动快速且灵活地生…

SSM相关面试题01

目录 1.何为Spring Bean容器?Spring Bean容器与Spring IOC 容器有什么不同吗? 2.Spring IOC 如何理解? 3.Spring DI 如何理解? 4.Spring 中基于注解如何配置对象作用域?以及如何配置延迟加载机制? 5.Spring 工厂底层构建Bean对象借助什么机制?当对象不使用了要释放…

【c++篇】:解读Set和Map的封装原理--编程中的数据结构优化秘籍

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;c篇–CSDN博客 文章目录 前言一.set和map的初步封装1.树的节点封装修改2.Find()查找函数3.红…

机器学习实战:泰坦尼克号乘客生存率预测(数据处理+特征工程+建模预测)

项目描述 任务&#xff1a;根据训练集数据中的数据预测泰坦尼克号上哪些乘客能生存下来 数据源&#xff1a;csv文件&#xff08;train.csv&#xff09; 目标变量&#xff1a;Survived&#xff08;0-1变量&#xff09; 数据集预览&#xff1a; 1、英文描述&#xff1a; 2、…

Linux自动化部署方法(Linux Automated Deployment Method)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

C++软件设计模式之组合模式与其他模式的协作举例

组合模式&#xff08;Composite Pattern&#xff09;、装饰器模式&#xff08;Decorator Pattern&#xff09;、享元模式&#xff08;Flyweight Pattern&#xff09;、迭代器模式&#xff08;Iterator Pattern&#xff09;和访问者模式&#xff08;Visitor Pattern&#xff09;…

2686694 - 操作方法:MSEG - DBSQL_REDIRECT_INCONSISTENCY

2686694 - 操作方法&#xff1a;MSEG - DBSQL_REDIRECT_INCONSISTENCY SAP Note, Version: 4, 审批日期: 24.04.2023 显示更改 组件MM-IM-GF对象状态 优先级建议/附加信息对象状态 类别咨询对象状态 审批状态已发布至客户对象状态 更正0对象状态 手动活动0对象状态已成…

嵌入式 FPGA开发

目录 一、引言 二、当前嵌入式 FPGA 开发的现状 三、嵌入式 FPGA 开发的优势 四、嵌入式 FPGA 的应用领域 1. 通信系统 2. 数字信号处理 3. 视频图像处理 4. 高速接口设计 5. 人工智能 6. IC 设计与 PCB 设计类比 五、嵌入式 FPGA 未来发展趋势 六、结论 一、引言 …

工业AI质检 AI质检智能系统 尤劲恩(上海)信息科技有限公司

来的现代化工厂&#xff0c;将逐步被无人化车间取代&#xff0c;无人工厂除了产线自动化&#xff0c;其无人质检将是绕不开的话题。尤劲恩致力于帮助工业制造领域上下游工厂减员增效、提高品质效率&#xff0c;真正实现无人质检IQC/IPQC/OQC的在线质检系统。分析生产环节真实品…

Angular v19 (三):增量水合特性详解 - 什么是水合过程?有哪些应用场景?与 Qwik 相比谁更胜一筹?- 哪个技术好我就学哪个,这就是吸心大法吧

Angular在其最新版本 v19 中引入了增量水合&#xff08;Incremental Hydration&#xff09;这一特性。这一更新引发了开发者们广泛的讨论&#xff0c;特别是在优化首屏加载速度和改善用户体验方面。本文将详解水合过程的概念、增量水合的应用场景&#xff0c;以及它与类似框架如…

[STM32]从零开始的STM32 FreeRTOS移植教程

一、前言 如果能看到这个教程的话&#xff0c;说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗&#xff1f;是的&#xff0c;我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS&#xff0c;再到最…

Vivado程序固化到Flash

在上板调试FPGA时&#xff0c;通常使用JTAG接口下载程序到FPGA芯片中&#xff0c;FPGA本身是基于RAM工艺的器件&#xff0c;因此掉电后会丢失芯片内的程序&#xff0c;需要重新烧写程序。但是当程序需要投入使用时不能每一次都使用JTAG接口下载程序&#xff0c;一般FPGA的外围会…

医疗废物检测

3809总图像数 数据集分割 训练组80&#xff05; 3030图片 有效集20&#xff05; 779图片 测试集&#xff05; 0图片 标签 预处理 自动定向&#xff1a; 已应用 调整大小&#xff1a; 拉伸至 640x640 增强 未应用任何增强。 注射器 手术刀 输液管 医用手套 医用口罩 血渍 数据集…