Go中的控制反转 IoC

以嵌入组合的方式实现控制反转 IoC:

控制反转是一种解耦思想,将原本耦合在业务逻辑中的控制逻辑单独拆出来实现,不再让业务逻辑在处理业务的同时还要去实现控制逻辑,而是专注处理业务。在业务逻辑代码中耦合进控制逻辑,会导致在编写业务逻辑时需要处理业务之外的事,而且控制逻辑耦合进业务中,只适用于当前业务逻辑,无法被复用

// 以嵌入组合的方式实现控制反转 IoC
package mainimport ("errors""fmt"
)// 2.被要求:新增一 'undo 后悔' 功能。
// 3.解决办法:定义单独(通用的)控制逻辑,别的数据结构也可能会用到
//   即:控制逻辑封装在 Undo 中,业务逻辑 IntSet 只关心处理整型数据
type Undo []func() // 函数切片func (undo *Undo) Add(fn func()) { //undo入栈*undo = append(*undo, fn)
}func (undo *Undo) Undo() error {functions := *undoif len(functions) == 0 {return errors.New("No functions to undo")}index := len(functions) - 1if fn := functions[index]; fn != nil {fn()functions[index] = nil  // 垃圾回收}*undo = functions[:index] // undo出栈操作return nil
}// ----------------------------------------------
type IntSet struct {data map[int]bool  // 1.原本的处理整形数据的结构undo Undo // 3.解决办法:并在此处嵌入一个 Undo 结构,间接实现 undo 功能
}func NewIntSet() IntSet {return IntSet{data: make(map[int]bool)}
}func (set *IntSet) Add(x int) {// set.data[x] = true  //原来逻辑// 改为if !set.Contains(x) {set.data[x] = trueset.undo.Add(func() { set.Delete(x) })} else {set.undo.Add(nil)}
}func (set *IntSet) Delete(x int) {// delete(set.data, x) //原来逻辑//改为if set.Contains(x) {delete(set.data, x)set.undo.Add(func() { set.Add(x) })} else {set.undo.Add(nil)}
}func (set *IntSet) Contains(x int) bool {return set.data[x]
}// 3.新增
func (set *IntSet) Undo() error {return set.undo.Undo()
}// ----------------------------------------------
func main() {a := NewIntSet()for i := 1; i < 11; i++ {a.Add(i)}fmt.Printf("%v\n", a) //map[1:true 2:true 3:true 4:true 5:true 6:true 7:true 8:true 9:true 10:true]fmt.Printf("%v\n", a.Contains(2))a.Delete(2)fmt.Printf("%v\n", a) //map[1:true 3:true 4:true 5:true 6:true 7:true 8:true 9:true 10:true]fmt.Printf("%v\n", a.Contains(2))a.Undo()fmt.Printf("%v\n", a) //map[1:true 2:true 3:true 4:true 5:true 6:true 7:true 8:true 9:true 10:true]fmt.Printf("%v\n", a.Contains(2))fmt.Printf("%v\n", a.Contains(4))a.Delete(4)fmt.Printf("%v\n", a) //map[1:true 2:true 3:true 5:true 6:true 7:true 8:true 9:true 10:true]fmt.Printf("%v\n", a.Contains(4))a.Delete(7)fmt.Printf("%v\n", a) //map[1:true 2:true 3:true 5:true 6:true 8:true 9:true 10:true]fmt.Printf("%v\n", a.Contains(7))a.Undo()fmt.Printf("%v\n", a) //map[1:true 2:true 3:true 5:true 6:true 7:true 8:true 9:true 10:true]fmt.Printf("%v\n", a.Contains(7))a.Undo()fmt.Printf("%v\n", a) //map[1:true 2:true 3:true 4:true 5:true 6:true 7:true 8:true 9:true 10:true]fmt.Printf("%v\n", a.Contains(4))
}

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

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

相关文章

window搭建本地mongo数据库并导入数据

1 window下载mongo数据库 官网&#xff1a;www.mongodb.com 选择 Products > Community Edition 就能进入社区版 在这里下载 windows 版对应的安装包 注意&#xff1a;6.0.1 版本的 MongoDB 配置环境变量有问题&#xff0c;并且我不知道怎么解决&#xff0c;如果想要避免出…

算法学习05:离散化、区间合并

算法学习05&#xff1a;离散化、区间合并 文章目录 算法学习05&#xff1a;离散化、区间合并前言需要记忆的模版&#xff1a;一、离散化1.例题&#xff1a;离散化 区间和&#xff1a;拓展: 二、区间合并&#xff08;贪心&#xff09;1.例题&#xff1a; 总结 前言 需要记忆的模…

基于FastAPI构造一个AI模型部署应用

前言 fastapi是目前一个比较流行的python web框架&#xff0c;在大模型日益流行的今天&#xff0c;其云端部署和应用大多数都是基于fastapi框架。所以掌握和理解fastapi框架基本代码和用法尤显重要。 需要注意的是&#xff0c;fastapi主要是通过app对象提供了web服务端的实现代…

tidyverse提取MergedGenes列包含“sss“字符的行

要使用tidyverse包在R中提取包含特定字符串“sss”字符的MergedGenes列的行&#xff0c;可以使用dplyr包中的filter()函数和str_detect()函数来实现。这里的str_detect()函数来自stringr包&#xff0c;它是tidyverse的一部分&#xff0c;用于检测字符串是否符合给定的模式。以下…

基于php的用户登录实现(v1版)(持续迭代)

目录 版本说明 数据库连接 登录页面&#xff1a;login.html 登录处理实现&#xff1a;login.php 用户欢迎页面&#xff1a;welcome.php 用户注册页面&#xff1a;register.html 注册执行&#xff1a;DoRegister.php 版本说明 v1实现功能&#xff1a; 数据库连接&#x…

SOCKS5代理与网络安全的舞蹈

在这个信息爆炸的时代&#xff0c;网络安全成为了每个网民乃至每个软件工程师的头等大事。今天&#xff0c;我们要聊的是如何使用SOCKS5代理和代理IP来保护我们的网络安全&#xff0c;同时还不失趣味性。这听起来可能有点枯燥&#xff0c;但别担心&#xff0c;我们会用一种轻松…

自定义限流注解

自定义注解 /*** 速率限制注解** author: 张定辉* date: 2024/3/5 21:29* description: 速率限制注解*/ Target({ElementType.TYPE,ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) public interface RateLimit {/*** SPEL表达式* <p>* 1.使用方法的基本类型参…

SpringAOP面向切面编程-代理

目录 1.静态代理 2.动态代理 代理在开发中实现的方式具体有两种&#xff1a;静态代理&#xff0c;[动态代理技术] 1.静态代理 主动创建代理类 public class CalculatorStaticProxy implements Calculator {// 将被代理的目标对象声明为成员变量private Calculator target;…

面试问答之MySQL数据库进阶

文章目录 &#x1f412;个人主页&#xff1a;信计2102罗铠威&#x1f3c5;JavaEE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380; MySQL架构&#x1f415;数据库引擎&#x1f415; InnoDB存储存储引擎&#x1f415;MYISAM &#x1f3e8;索引&#x1f415;哪些情况需要创建…

vue3+element-plus el-input 自动获取焦点

虽然element有提供input的autofocus属性&#xff0c;但是当我们第二次进入页面就会发现autofocus已经不再生效&#xff0c;需要通过onMounted去触发input的focus解决这个问题。 1.先给el-input绑定一个ref&#xff1a;<el-input ref"inputRef" v-model"inp…

景联文科技:专业提供高质量大语言模型训练数据

2024年&#xff0c;数字经济被再次写入政府工作报告中&#xff0c;报告指出要深化大数据、人工智能等研发应用&#xff0c;打造具有国际竞争力的数字产业集群。 大模型作为生成式人工智能的基础&#xff0c;日益成为国际科技竞争的焦点。人大代表杨剑宇指出&#xff0c;尽管我国…

008-slot插槽

slot插槽 1、插槽 slot 的简单使用2、插槽分类2.1 默认插槽2.2 具名插槽2.3 作用域插槽 插槽就是子组件中的提供给父组件使用的一个占位符&#xff0c;用<slot></slot> 表示&#xff0c;父组件可以在这个占位符中填充任何模板代码&#xff0c;如 HTML、组件等&…

老阳分享:视频号带货的四大技巧

视频号带货作为新兴的电商模式&#xff0c;在微信这个庞大的社交平台上展现出了巨大的潜力。要想在视频号带货领域取得成功&#xff0c;需要掌握一定的技巧。本文将为您详细解析视频号带货的四大技巧&#xff0c;感兴趣的朋友一起去看看吧。 一、内容创新 内容创新是视频号带货…

【深度学习笔记】5_11 残差网络ResNet

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 5.11 残差网络&#xff08;ResNet&#xff09; 让我们先思考一个问题&#xff1a;对神经网络模型添加新的层&#xff0c;充分训练后的…

Express框架的产生

Express框架的产生&#xff0c;解决的痛点是什么&#xff1f; 1.优化Node.js在Web的开发 Express框架是一个基于Node.js的Web应用程序开发框架&#xff0c;它的产生主要是为了解决Node.js在Web开发中的一些痛点。 在Node.js出现之前&#xff0c;Web开发主要是基于传统的后端…

springboot项目集成,项目流程概述

一、项目介绍 二、项目设计原则 2.1整体原则 2.2持久层 2.3业务逻辑层 具体分析 三、实战 3.1项目搭建 <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-crypto</artifactId></dependency>&l…

双链表的实现(数据结构)

链表总体可以分为三大类 一、无头和有头 二、单向和双向 三、循环和不循环 从上面分类得知可以组合成8种不同类型链表&#xff0c;其中单链表最为简单&#xff0c;双联表最为复杂&#xff0c;两种链表都实现后其余链表都不成问题。 我们前期博客已将完成了单向无头不循环链表…

基于PHP的景点数据分析系统设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 关键理论与技术 3 1.1 框架技术 3 1.1.1 QueryList 3 1.1.2 ThinkPHP 3 1.1.3 Amaze UI 3 1.2 数据可视化技术 4 1.3 数据库技术 4 1.4 本章小结 4 2 需求分析 5 2.1 业务流程分析 5 2.2 功能需求分析 5 2.3 用例分析 7 2.4 非功能性需求…

it-tools工具箱

it-tools 是一个在线工具集合&#xff0c;包含各种实用的开发工具、网络工具、图片视频工具、数学工具等 github地址&#xff1a;https://github.com/CorentinTh/it-tools 部署 docker run -d --name it-tools --restart unless-stopped -p 8080:80 corentinth/it-tools:lat…

gradle 相关

aar 不加 aar 以及 transitive true library可以通过多种格式上传到远程仓库&#xff0c;比如大部分情况下用到的.jar或.aar。当没有指定后缀的话&#xff0c;依赖的时候将会下载它的默认格式&#xff08;由上传方定义&#xff0c;如果没有定义则默认为.jar&#xff09;的Lib…