Go 编程模式:Function Options、Builder 和 Rule Loader
date
Aug 19, 2022
slug
go-programming-mode-function-options-builder-rule-loader
status
Published
tags
Code
Design Patterns
summary
Go 语言编程中常用的编程模式
type
Post
Created Time
Oct 28, 2023 01:45 PM
Updated Time
Oct 28, 2023 01:45 PM
AI summary
Status
Funciton Options
首先,让我们看一段 Redis 配置(部分)代码:
假设,我们需要实现一个 NewOptions 方法,可以看到,其中有一部分参数是有默认值的,而有些参数,比如 Addr、Username 就没有默认值。如果是你,会如何实现这个 NewOptions 方法呢?
一种常见的方法是这样的:
但这样,你就需要在每次构建的时候,引用 Options 结构体,如果此时我把 Options 私有,你该怎么办呢?
你说,我可以这样:
想必你也发现了,这样就太不灵活了,这里只是部分配置,就有太多种组合,你不可能把每一种组合都实现吧?即使实现了,调用者使用起来也太麻烦了。一种更好的做法,是使用 Function Options 的方式进行初始化。
完整的实现如下:
使用方式如下:
最后,需要说明的是,这里只是以 Redis 举例,并不是说 Redis 现有的实现不好,更没有“教人做事”,具体的使用场景,还需要大家根据业务场景权衡。
Builder
Builder 又称“构建者模式”,在我看来,就像是 3D 打印的过程,首先,设计好一个“模型”,再将建成的模型“分割”成逐层的截面,最后,指导打印机逐层打印。构建者模式也可以解决上面的问题,但我觉得,这多少有点儿大材小用,构建者模式应该用来解决逻辑更复杂的问题,假设我们现在来打印一幢别墅,代码实现如下:
使用方式如下:
可以看到,在使用方法的最后,我们用一个 Build 方法,对最终的结果进行拆分,外部的使用者完全不用关心内部的结构是如何的,只需要根据需要,拿走想要的结果就好。值得一提的是,构建者模式相对于 Function Options,在控制构建的先后顺序方面,有更好的表现。
Rule Loader
Rule Loader,顾名思义,是根据规则,制定不同的计划,最终得到预期的结果的过程。
假设,我们现在需要为自动化餐厅制定流程,根据用户的输入,即点餐,输出对应的食物,即上菜。简单的实现,可以使用 switch case,每一个 case 对应菜单上的一道菜,但是,这样一来,函数的可读性和扩展性较差,后期的维护也很不方面,下架一道菜,或者上一道新菜,都必须仔细的维护“长函数”。Rule Loader 就是为了解决这样的问题。完整的实现如下:
使用方式如下:
这样看起来是不是清晰多了,每一道菜,可以对应不同的制作方式,菜单的更新只需要在 ruleLoaderMap 上进行维护就可以了。
Rule Loader 还有更多的玩法,比如,我们现在需要增加一个种类,叫做“限时供应”,它必须满足一定内置的条件(拥有 preprocess 方法和 serve 方法),实现起来也很简单。
下面是新增元宵的代码: