复杂度分析
复杂度分析 https://blog.csdn.net/Baron_ND/article/details/115492059 从广义上讲,数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。 如何分析、统计算法的执行效率和资源消耗?大 O 复杂度表示法算法的执行效率,粗略地讲,就是算法代码执行的时间。但是,如何在不运行代码的情况下,用“肉眼”得到一段代码的执行时间呢? 这里有段非常简单的代码,求 1,2,3…n 的累加和。现在,我就带你一块来估算一下这段代码的执行时间。 1234567func cal(n int) int { sum := 0 for i := 1; i < n; i++ { sum = sum + i } return sum} 从 CPU 的角度来看,这段代码的每一行都执行着类似的操作:读数据-运算-写数据。尽管每行代码对应的 CPU 执行的个数、执行的时间都不一样,但是,我们这里只是粗略估计,所以可以假设每行代码执行的时间都一样,为 unit_time。在这...
GitHub Actions入门教程
GitHub Actions入门教程 https://www.ruanyifeng.com/blog/2019/09/getting-started-with-github-actions.html https://www.cnblogs.com/i-code/p/12869046.html https://segmentfault.com/a/1190000022360769 一、GitHub Actions 是什么?大家知道,持续集成由很多操作组成,比如抓取代码、运行测试、登录远程服务器,发布到第三方服务等等。GitHub 把这些操作就称为 actions。 很多操作在不同项目里面是类似的,完全可以共享。GitHub 注意到了这一点,想出了一个很妙的点子,允许开发者把每个操作写成独立的脚本文件,存放到代码仓库,使得其他开发者可以引用。 如果你需要某个 action,不必自己写复杂的脚本,直接引用他人写好的 action 即可,整个持续集成过程,就变成了一个 actions 的组合。这就是 GitHub Actions 最特别的地方。 GitHub 做了一个官方市场,可以搜索...
图解设计模式
图解设计模式 http://tigerb.cn/2021/03/07/patterns-picture/ 前言常常听别人说设计模式不太容易理解,以及学习设计模式到底能帮我们解决什么问题,今天我们就用几张图来看看: 设计模式到底是什么? 为什么我们需要学习设计模式? 我也写过烂代码是的,没什么,我也写过烂代码,刚毕业时业务逻辑也会一个函数干到底,只知道能实现功能就可以了。 12345package demo func YourFunc() { // 所有的逻辑代码一股脑写完......} 知道了拆分函数自然而然知道了需要合理拆分函数。 然后把各个函数组织起来。 面临新的困境某一天产品的需求需要支持新的场景,发现某一处的代码逻辑有变动需要支持新的场景,怎么办? 整个代码拷贝一份?不会有人这么干吧?(其实我还真见过,你们呢😏) 把绿色变动的代码块,复制成一个新的函数,修改为新场景使用的函数? 把变动的代码再提为两个新函数,一个绿色为老代码,一个蓝色为新场景代码? 上面这种解决问题的方式就是面向过程的编程思想。 我们都在变优秀随着我们不断的学习,...
面向对象的设计过程
面向对象的设计过程 http://tigerb.cn/2019/10/11/oop/ 前言我一直认为分享的目的不是炫技。 一是,自我学习的总结。 二是,降低他人的学习成本。 三是,别人对自己学习结果的审核。 同时,本次分享有下面四个要素: 观点 本次分享的观点是一个软件工程中的思维方法,不限于编程语言 探讨 我可能理解错的,或者大家没理解的,欢迎大家积极评论,尽可能多互动,目的增加理解 理解 真的希望大家能理解 运用 最重要的,如果你觉着有帮助,一定要去在实际业务中实战 背景工作中,几乎大家经常抱怨别人写的代码: 没法改 耦合高 无法扩展 今天就来探讨如何克服上面的问题~ 场景首先问个问题: 平常工作中来了一个业务需求,我们是如何开始写代码的? 我推测大多数人可能: 1、梳理业务 2、设计数据库、接口、缓存 3、评审 4、于是就开始了 怎么怎么样...如果怎么怎么样...怎么怎么样...愉快的码代码的过程 此处有人觉着有啥问题么? 1备注:说出来问题的,本次分享就可以略过了~ 一个简单的业务场景123456789101112比如...
工厂模式 | Go设计模式实战
http://tigerb.cn/ 我的代码没有else系列-简单工厂 结合实际业务谈设计模式 业务场景 12调用一个服务生成静态页面不同的页面拥有不同的模块 不同的页面的数据结构不一样生成不同的页面对象 正常代码 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667package mainimport "fmt"const ( // CartConst 购物车列表页面 CartConst = "cart/list" // ProductConst 商品列表页面 ProductConst = "product/list")// Context 请求上下文type Context struct { URI string}// PageInterface PageInterfacetype PageInt...
并发组件 | Go设计模式实战
并发组件 | Go设计模式实战 嗯,Go设计模式实战系列,一个设计模式业务真实使用的golang系列。 http://tigerb.cn/ 前言本系列主要分享,如何在我们的真实业务场景中使用设计模式。 本系列文章主要采用如下结构: 什么是「XX设计模式」? 什么真实业务场景可以使用「XX设计模式」? 怎么用「XX设计模式」? 本文主要介绍「组合模式」结合Go语言天生的并发特性,如何在真实业务场景中使用。 之前文章《代码组件 | Go设计模式实战》已经介绍了「组合模式」的概念,以及在业务中的使用。今天我们结合Go语言天生的并发特性,升级「组合模式」为「并发组合模式」。 我们先来简单回顾下「组合模式」的知识,详细可以查看上篇文章《代码组件 | Go设计模式实战》 什么是「并发组合模式」?组合模式的概念: 一个具有层级关系的对象由一系列拥有父子关系的对象通过树形结构组成。 并发组合模式的概念: 一个具有层级关系的对象由一系列拥有父子关系的对象通过树形结构组成,子对象即可被串行执行,也可被并发执行 并发组合模式的优势: 原本串行的业务(存在阻塞的部分,比如网络IO等)可以...
状态变换 | Go设计模式实战
状态变换 | Go设计模式实战 嗯,Go设计模式实战系列,一个设计模式业务真实使用的golang系列。 http://tigerb.cn/ 前言本系列主要分享,如何在我们的真实业务场景中使用设计模式。 本系列文章主要采用如下结构: 什么是「XX设计模式」? 什么真实业务场景可以使用「XX设计模式」? 怎么用「XX设计模式」? 本文主要介绍「状态模式」如何在真实业务场景中使用。 「状态模式」比较简单,就是算法的选取取决于于自己的内部状态。相较于「策略模式」算法的选取由用户决策变成内部状态决策,「策略模式」是用户(客户端)选择具体的算法,「状态模式」只是通过内部不同的状态选择具体的算法。 什么是「状态模式」? 不同的算法按照统一的标准封装,根据不同的内部状态,决策使用何种算法 「状态模式」和「策略模式」的区别 策略模式:依靠客户决策 状态模式:依靠内部状态决策 什么真实业务场景可以用「状态模式」? 具体算法的选取是由内部状态决定的 首先,内部存在多种状态 其次,不同的状态的业务逻辑各不相同 我们有哪些真实业务场景可以用「状态模式」呢? 比如,发送短信接口、限流等等...
客户决策 | Go设计模式实战
客户决策 | Go设计模式实战 嗯,Go设计模式实战系列,一个设计模式业务真实使用的golang系列。 http://tigerb.cn/ 前言本系列主要分享,如何在我们的真实业务场景中使用设计模式。 本系列文章主要采用如下结构: 什么是「XX设计模式」? 什么真实业务场景可以使用「XX设计模式」? 怎么用「XX设计模式」? 本文主要介绍「策略模式」如何在真实业务场景中使用。 什么是「策略模式」?「策略模式」比较简单,大家平常工作中应该经常使用到,所以本文作为复习,帮助大家温故知新。我们先来看下定义: 不同的算法按照统一的标准封装,客户端根据不同的场景,决策使用何种算法。 上面的概念的关键词: 算法:就是行为 标准:就是interface 客户端:客户端是相对的,谁调用谁就是客户端 场景:判断条件 决策:判断的过程 概念很容易理解,不多说。 「策略模式」的优势: 典型的高内聚:算法和算法之间完全独立、互不干扰 典型的松耦合:客户端依赖的是接口的抽象方法 沉淀:每一个封装好的算法都是这个技术团队的财富,且未来可以被轻易的修改、复用 什么真实业务场景可以用「策略模式...
订阅通知 | Go设计模式实战
订阅通知 | Go设计模式实战 嗯,Go设计模式实战系列,一个设计模式业务真实使用的golang系列。 http://tigerb.cn/ 前言本系列主要分享,如何在我们的真实业务场景中使用设计模式。 本系列文章主要采用如下结构: 什么是「XX设计模式」? 什么真实业务场景可以使用「XX设计模式」? 怎么用「XX设计模式」? 虽然本文的题目叫做“订阅通知”,但是呢,本文却主要介绍「观察者模式」如何在真实业务场景中使用。是不是有些不理解?解释下: 原因一,「观察者模式」其实看起来像“订阅通知” 原因二,“订阅通知”更容易被理解 什么是「观察者模式」? 观察者观察被观察者,被观察者通知观察者 我们用“订阅通知”翻译下「观察者模式」的概念,结果: “订阅者订阅主题,主题通知订阅者” 是不是容易理解多了,我们再来拆解下这句话,得到: 两个对象 被观察者 -> 主题 观察者 -> 订阅者 两个动作 订阅 -> 订阅者订阅主题 通知 -> 主题发生变动通知订阅者 观察者模式的优势: 高内聚 -> 不同业务代码变动互不影响 可复用 -...
代码组件 | Go设计模式实战
代码组件 | Go设计模式实战 嗯,Go设计模式实战系列,一个设计模式业务真实使用的golang系列。 http://tigerb.cn/ 前言本系列主要分享,如何在我们的真实业务场景中使用设计模式。 本系列文章主要采用如下结构: 什么是「XX设计模式」? 什么真实业务场景可以使用「XX设计模式」? 怎么用「XX设计模式」? 本文主要介绍「组合模式」如何在真实业务场景中使用。 什么是「组合模式」? 一个具有层级关系的对象由一系列拥有父子关系的对象通过树形结构组成。 组合模式的优势: 所见即所码:你所看见的代码结构就是业务真实的层级关系,比如Ui界面你真实看到的那样。 高度封装:单一职责。 可复用:不同业务场景,相同的组件可被重复使用。 什么真实业务场景可以用「组合模式」?满足如下要求的所有场景: Get请求获取页面数据的所有接口 前端大行组件化的当今,我们在写后端接口代码的时候还是按照业务思路一头写到尾吗?我们是否可以思索,「后端接口业务代码如何可以简单快速组件化?」,答案是肯定的,这就是「组合模式」的作用。 我们利用「组合模式」的定义和前端模块的划分去构建后端业...
链式调用 | Go设计模式实战
链式调用 | Go设计模式实战 嗯,Go设计模式实战系列,一个设计模式业务真实使用的golang系列。 http://tigerb.cn/ 前言本系列主要分享,如何在我们的真实业务场景中使用设计模式。 本系列文章主要采用如下结构: 什么是「XX设计模式」? 什么真实业务场景可以使用「XX设计模式」? 怎么用「XX设计模式」? 本文主要介绍「责任链模式」如何在真实业务场景中使用。 什么是「责任链模式」? 首先把一系列业务按职责划分成不同的对象,接着把这一系列对象构成一个链,然后在这一系列对象中传递请求对象,直到被处理为止。 我们从概念中可以看出责任链模式有如下明显的优势: 按职责划分:解耦 对象链:逻辑清晰 但是有一点直到被处理为止,代表最终只会被一个实际的业务对象执行了实际的业务逻辑,明显适用的场景并不多。但是除此之外,上面的那两点优势还是让人很心动,所以,为了适用于目前所接触的绝大多数业务场景,把概念进行了简单的调整,如下: 首先把一系列业务按职责划分成不同的对象,接着把这一系列对象构成一个链,直到“链路结束”为止。(结束:异常结束,或链路执行完毕结束) 简单的...
代码模板 | Go设计模式实战
代码模板 | Go设计模式实战 嗯,Go设计模式实战系列,一个设计模式业务真实使用的golang系列。 http://tigerb.cn/ 前言本系列主要分享,如何在我们的真实业务场景中使用设计模式。 本系列文章主要采用如下结构: 什么是「XX设计模式」? 什么真实业务场景可以使用「XX设计模式」? 怎么用「XX设计模式」? 本文主要介绍「模板模式」如何在真实业务场景中使用。 什么是「模板模式」?抽象类里定义好算法的执行步骤和具体算法,以及可能发生变化的算法定义为抽象方法。不同的子类继承该抽象类,并实现父类的抽象方法。 模板模式的优势: 不变的算法被继承复用:不变的部分高度封装、复用。 变化的算法子类继承并具体实现:变化的部分子类只需要具体实现抽象的部分即可,方便扩展,且可无限扩展。 什么真实业务场景可以用「模板模式」?满足如下要求的所有场景: 算法执行的步骤是稳定不变的,但是具体的某些算法可能存在变化的场景。 怎么理解,举个例子:比如说你煮个面,必然需要先烧水,水烧开之后再放面进去,以上的流程我们称之为煮面过程。可知:这个煮面过程的步骤是稳定不变的,但是在不同的环...
访问者和双分派
https://refactoringguru.cn/design-patterns/visitor-double-dispatch 访问者和双分派让我们看看下面几何图形类的层次结构 (注意伪代码): 123456789101112131415161718192021222324252627interface Graphic is method draw()class Shape implements Graphic is field id method draw() // ...class Dot extends Shape is field x, y method draw() // ...class Circle extends Dot is field radius method draw() // ...class Rectangle extends Shape is field width, height method draw() // ...class CompoundGraphic...
工厂模式比较
https://refactoringguru.cn/design-patterns/factory-comparison 工厂模式比较本文将对下列概念之间的差异进行说明: 工厂 构建方法 静态构建 (或工厂) 方法 简单工厂 工厂方法 抽象工厂 你可以在网上找到这些术语的参考信息。 尽管它们看上去相似, 但其含义都不一样。 许多人没有意识到这一点, 从而出现了混淆和误解。 因此让我们搞清楚其中的不同之处, 一劳永逸地解决这个问题。 1. 工厂工厂是一个含义模糊的术语, 表示可以创建一些东西的函数、 方法或类。 最常见的情况下, 工厂创建的是对象。 但是它们也可以创建文件和数据库记录等其他东西。 例如, 下面这些东西都可以非正式地被称为 “工厂”: 创建程序 GUI 的函数或方法; 创建用户的类; 以特定方式调用类构造函数的静态方法。 一种创建型设计模式。 当某人说到 “工厂” 这个词时, 其具体含义通常可以根据上下文来确定。 但如果你有疑问, 可以直接提问。 毕竟作者本人有时候也没有搞清楚。 2. 构建方法构建方法在 《重构与模式》 中被定义为 “创建对象的方法”。...
行为模式-解释器模式
行为模式-解释器模式亦称: interpreter 介绍解释器模式:定义一种方法和对应的解释器,使用解释器解释此方法的语句来执行; 解释器模式需要上下文类来定义和存储上下文,解释器类用来将语句来翻译成可执行程序; 解释器扩展和改变文化非常简单,构建完成后可以很方便地数据格式; 解释器模式会将非终结表达式递归解释,直到解释为终结符表达式; 场景 解释器模式适用于数据结构不规则,但数据要素相同的情况; 语法不能太复杂,复杂的最好使用解释形语言来实现以降低复杂性; golangjava12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061package mainimport "strings"//意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。//主要解决:对于一些固定文法构建一个解释句子的解释器。//何时使用:如果一种特定类型的问题发生的频...
行为模式-访问者模式
https://refactoringguru.cn/design-patterns/visitor 行为模式-访问者模式亦称: Visitor 意图访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。 问题假如你的团队开发了一款能够使用巨型图像中地理信息的应用程序。 图像中的每个节点既能代表复杂实体 (例如一座城市), 也能代表更精细的对象 (例如工业区和旅游景点等)。 如果节点代表的真实对象之间存在公路, 那么这些节点就会相互连接。 在程序内部, 每个节点的类型都由其所属的类来表示, 每个特定的节点则是一个对象。 一段时间后, 你接到了实现将图像导出到 XML 文件中的任务。 这些工作最初看上去非常简单。 你计划为每个节点类添加导出函数, 然后递归执行图像中每个节点的导出函数。 解决方案简单且优雅: 使用多态机制可以让导出方法的调用代码不会和具体的节点类相耦合。 但你不太走运, 系统架构师拒绝批准对已有节点类进行修改。 他认为这些代码已经是产品了, 不想冒险对其进行修改, 因为修改可能会引入潜在的缺陷。 此外, 他还质疑在节点类中包含导出 XML 文...
行为模式-模板方法模式
https://refactoringguru.cn/design-patterns/template-method 行为模式-模板方法模式亦称: Template Method 意图模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 问题假如你正在开发一款分析公司文档的数据挖掘程序。 用户需要向程序输入各种格式 (PDF、 DOC 或 CSV) 的文档, 程序则会试图从这些文件中抽取有意义的数据, 并以统一的格式将其返回给用户。 该程序的首个版本仅支持 DOC 文件。 在接下来的一个版本中, 程序能够支持 CSV 文件。 一个月后, 你 “教会” 了程序从 PDF 文件中抽取数据。 一段时间后, 你发现这三个类中包含许多相似代码。 尽管这些类处理不同数据格式的代码完全不同, 但数据处理和分析的代码却几乎完全一样。 如果能在保持算法结构完整的情况下去除重复代码, 这难道不是一件很棒的事情吗? 还有另一个与使用这些类的客户端代码相关的问题: 客户端代码中包含许多条件语句, 以根据不同的处理对象类型选择合适的处...
行为模式-策略模式
https://refactoringguru.cn/design-patterns/strategy 行为模式-策略模式亦称: Strategy 意图策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。 问题一天, 你打算为游客们创建一款导游程序。 该程序的核心功能是提供美观的地图, 以帮助用户在任何城市中快速定位。 用户期待的程序新功能是自动路线规划: 他们希望输入地址后就能在地图上看到前往目的地的最快路线。 程序的首个版本只能规划公路路线。 驾车旅行的人们对此非常满意。 但很显然, 并非所有人都会在度假时开车。 因此你在下次更新时添加了规划步行路线的功能。 此后, 你又添加了规划公共交通路线的功能。 而这只是个开始。 不久后, 你又要为骑行者规划路线。 又过了一段时间, 你又要为游览城市中的所有景点规划路线。 尽管从商业角度来看, 这款应用非常成功, 但其技术部分却让你非常头疼: 每次添加新的路线规划算法后, 导游应用中主要类的体积就会增加一倍。 终于在某个时候, 你觉得自己没法继续维护这堆代码了。 ...
行为模式-状态模式
https://refactoringguru.cn/design-patterns/state 行为模式-状态模式亦称: State 意图状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。 问题状态模式与有限状态机的概念紧密相关。 其主要思想是程序在任意时刻仅可处于几种有限的状态中。 在任何一个特定状态中, 程序的行为都不相同, 且可瞬间从一个状态切换到另一个状态。 不过, 根据当前状态, 程序可能会切换到另外一种状态, 也可能会保持当前状态不变。 这些数量有限且预先定义的状态切换规则被称为转移。 你还可将该方法应用在对象上。 假如你有一个 文档Document类。 文档可能会处于 草稿Draft 、 审阅中Moderation和 已发布Published三种状态中的一种。 文档的 publish发布方法在不同状态下的行为略有不同: 处于 草稿状态时, 它会将文档转移到审阅中状态。 处于 审阅中状态时, 如果当前用户是管理员, 它会公开发布文档。 处于 已发布状态时, 它不会进行任何操作。 状态机通...
行为模式-观察者模式
https://refactoringguru.cn/design-patterns/observer 行为模式-观察者模式亦称: 事件订阅者、监听者、Event-Subscriber、Listener、Observer 意图观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。 问题假如你有两种类型的对象: 顾客和 商店 。 顾客对某个特定品牌的产品非常感兴趣 (例如最新型号的 iPhone 手机), 而该产品很快将会在商店里出售。 顾客可以每天来商店看看产品是否到货。 但如果商品尚未到货时, 绝大多数来到商店的顾客都会空手而归。 另一方面, 每次新产品到货时, 商店可以向所有顾客发送邮件 (可能会被视为垃圾邮件)。 这样, 部分顾客就无需反复前往商店了, 但也可能会惹恼对新产品没有兴趣的其他顾客。 我们似乎遇到了一个矛盾: 要么让顾客浪费时间检查产品是否到货, 要么让商店浪费资源去通知没有需求的顾客。 解决方案拥有一些值得关注的状态的对象通常被称为目标, 由于它要将自身的状态改变通知给其他对象, 我们也将其...






















