前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用map实现策略模式

利用map实现策略模式

原创
作者头像
有财君
发布2023-06-16 08:54:21
4101
发布2023-06-16 08:54:21
举报
文章被收录于专栏:我的编码学习笔记

1. 代码实现

手上有一个工作,要做一个数据库类型转换工具,比如MySQL转ClickHouse,那么这个工具大部分的工作就是在做映射关系的比对。

最初写的代码大概是这个样子的:

代码语言:go
复制
switch (mysqlType) {
case MySQLInt:
	if column.IsUnsigned {
		col.Type = UInt32
	}
	col.Type = UInt32
	// 省略大部分逻辑
}

这样的代码可想而知,会有很多个case分支,存在下面几个问题:

  • 代码丑陋,大量的逻辑放在一个代码块中,极为丑陋难以阅读理解
  • 难于扩展,每次都需要在这个代码块中增删

而这种映射关系最好的保存结构一定是map,所以我用map做了一定的改造。首先,引入了一个struct类型,来保存column的信息:

代码语言:go
复制
type myType struct {
	colType ColumnType
	isUnsigned bool
}

接下来改造map:

代码语言:go
复制
var dict1 = map[myType]ColumnType {
	myType{colType: MySQLInt, isUnsigned: false}:Int32,
	myType{colType: MySQLInt, isUnsigned: true}:UInt32,
}

这样一来,逻辑代码就变得很简约了,一行代码就能搞定逻辑判断:

代码语言:go
复制
col.Type = dict1[myType{colType:mysqlType, isUnsigned: column.IsUnsigned}]

不过类型里还有一类硬茬,就是带精度的类型,如Decimal(m, n),处理的时候还需要把精度拿出来,然后构造新的类型,代码如下:

代码语言:go
复制
switch (mysqlType) {
case MySQLDecimal:
	col.Type = ColumnType(fmt.Sprintf("%s%s", Decimal, column.Precision))
	// 省略大部分逻辑
}

这就很恼火了,我不能无限制的改造struct用来适配,代码会变得很难看和难以维护,而且冗余的东西太多。所以我想到了用函数类型去做这个事情:

代码语言:go
复制
type transformer func(column Column) ColumnType

利用这个函数类型对Decimal这种进行改造,最后的效果是这样的:

代码语言:go
复制
type transformer func(column Column) ColumnType

var dict2 = map[ColumnType]transformer{
	MySQLInt: func(col Column) ColumnType {
		if col.isUnsigned {
			return UInt32
		}
		return Int32
	},
	MySQLDecimal: func(col Column) ColumnType {
		return ColumnType(fmt.Sprintf("%s%s", ChDecimal, column.Precision))
	}
}

这样的几次改造后,我的代码里终于消灭了所有的switch-case。回过头来看,这次改造还是一次策略模式的应用,目的就是利用策略模式消灭掉if-else,或者说过多的if-else。

而这次改造后的代码,无论后面加类型还是删除类型,都不需要改动业务逻辑代码,只要在dict2里增加就可以了,基本符合开闭原则。

本来学习GoF的设计模式的时候,总是拘泥于面向对象的实现,每次还得先画类图,总之改造起来很累。

后来发现Spring框架里可以轻松的用map实现,就开始感觉其实策略模式的实现不需要拘泥于一种方式,只要思路对,那一定可以实现。

2. 参考资料

用SpringBoot实现策略模式

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 代码实现
  • 2. 参考资料
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档