"动态"编程逻辑:这种灵活性的合理性有多大

229 天前
 ZekeChin

reddit 刷到的一个帖子发现 原来大家都有一样的烦恼,V 站的朋友们怎么看 https://www.reddit.com/r/AskProgramming/comments/1cmkf0m/dynamic_logic_in_code_is_this_flexibility_worth_it/

译文如下

在我最近的一份工作中,我注意到我们的代码库中有大量的"动态"逻辑。例如,我们通过动态提取列名来管理具有不同模式的多个 SQLite 文件,而不是为每个模式进行版本控制。基本上,用户查询可以在不同的数据库上执行,而我们并不需要提前知道数据库上有哪些表格/列。这样的优点是我们不需要为每个数据库写新的逻辑,创建这些数据库的团队也不需要与我们(后端)同步,API 可以"直接"透明地访问数据库内容。所以这种策略被认为是"更灵活的"。

然而,我发现这使得理解、测试和编写代码文档变得更加困难。向后兼容性的提供也变得更困难,或者在必要时定制后端的行为也更为复杂。例如,假设我们在数据库上有一个user.full_name列,但 API 必须返回两个分开的字段(first_namelast_name)。现在的情况是,代码被修改以添加大量的if语句(例如:if column_name == "full_name": ...),向后兼容性变得非常困难。

我有一种感觉,所有这些"动态"的代码在理论上听起来很聪明、很酷,但实际上它变成了一个负担。这是一个众所周知的问题,还是我理解错了?我想向我的团队阐述我为什么认为这是一个问题,但我缺乏参考文献。你能提供一些我可以用来分享我的观点的信息吗?这种做法有一个名字吗?有关代码"动态性"的最佳实践是什么?

3942 次点击
所在节点    程序员
28 条回复
InkStone
229 天前
这就是“复杂性不会消失,只会转移”。

最佳实践应该就是不要盲目追求灵活性,像数据格式这种东西就应该老老实实约定好固定下来……API 和 DAO 中间还是需要中间层做解耦,不要搞什么 API 的字段直接对应到数据库的飞机。
yexian
229 天前
不如在字段里存 json ?
dddd1919
229 天前
eval 一时爽
codehz
229 天前
说明抽象程度还不够,无法对整个事情进行建模(就像写代码使用动态类型,很多时候只是因为类型系统不够完善,无法在类型层面上描述具体项目的约束)
zhtyytg
229 天前
一个最简单的外行指导内行逻辑就是:万物皆可动态 以及 万物皆需封装
前者会让所有本来简单直接的设计变成一个臃肿的怪物
后者会让开发进程无限拉长直至项目失败
shunia
229 天前
不是很懂,除非有工具能自动映射数据库表结构为代码,否则不都是动态查表的吗?不管你是写 SQL 查询还是用了什么高级工具或者流程,最终数据库表字段一改,你查询代码或者 DAO 层就是得跟着变化吧。只是说这个动态的过程是反映在业务代码层,还是反映在数据库中间层部分而已?

另外如果帖主提到的这种情况,不是落在每一处业务代码中,而是也分层做了隔离呢?那还算动态吗?
james122333
229 天前
事实上提到的也并不动态 只有静态的才会一直在那边 if 一个一个判别
james122333
229 天前
动态只做半套说累不是其来有自吗
murmur
229 天前
光批判不贴代码不是跟耍流氓一样么

原文也没贴

他的例子完全不懂是什么意思

按我的理解,国内的低代码写法他看到要骂娘,尤其是要兼容各种数据库,还得能切换的
meeop
229 天前
项目经验上来看,大多数“动态”xx 的功能是不合理的过度设计

动态的意思是某些逻辑无法在开发时确定,或者需要支持开发好后灵活变更

绝大多数场景,就是单纯的没想好系统模型设计而导致的
除非确实是一个需要支持灵活变化的部分才需要动态话(典型场景是一个动态表单,运营可以灵活配置创建,免开发)
iOCZS
229 天前
得到自由的同时,就会陷入自由的混乱
blackmirror
229 天前
这种就是自己轻松一点,只能苦一苦别人了
wclssdn
229 天前
也分实际场景吧,如果是提供的云数据库的业务,那就是无法提前知道用户会创建什么样的数据结构。 但还要提供 API 去操作数据库。
如果要针对特定用户的数据表做处理,例如拆分姓名,那就应该让用户自行的创建一个数据前置、后置处理器去处理。
如果场景中没有这个“用户”,那就应该由业务自行的来抽象一个,哪个是这个“用户”,例如 A 业务、B 业务。

总结一下:运用领域思维去设计总是无往不利,比如这个场景:总得有人知道数据结构吧? 谁知道谁处理就不会有这种疑问了。
leonshaw
229 天前
合理性在于能把复杂逻辑甩给别人。
tool2dx
229 天前
@murmur “他的例子完全不懂是什么意思”

中文译文不太好理解,英文原文还是容易理解的。

就是把一个 user.full_name 字段拆分成两个 api, 单独返回 first_name 和 last_name 。
ny562kPWNJK9g86f
229 天前
避免过度设计,该踢正步就踢正步,该跑步时就应该跑步,在技术上不要太过于迂腐了。
crz
229 天前
按例子是 '数据库 -> 访问层 -> 应用层' 的抽象,访问层处理具体数据已经超出设计了,另外 full_name 的设计看起来是一开始把脑袋拍响了?
lujiaxing
229 天前
动态到头了, 其实就是 IDE 跟编程语言...
我什么都不写就是最灵活的.
zhazi
229 天前
赞同 7 楼所说的
可能是这个提出问题的人抽象的不到位,所以写出了不灵活的代码
打个比方
你们是一家做平台的公司,
要与客户来对接,
你的第一个客户定义了的名称需要用 user.full_name
你的第二个客户定义了的名称需要用 user.first_name 和 last_name
你的建模是客户如何描述他的业务字段,而不是判断客户的字段
你的建模定义为

客户 1
field:'name'
column_name:name_str
type: string
value:'zhangsan'

客户 2
field:'name'
column_name:name_obj
type: object
value:{'first_name':'zhang','last_name':'san'}
通过 type 统一了两个客户对象的建模,不需要写出 if column_name == full_name 这种代码
bojue
229 天前
我们是参考 critical 开发的一套,会基于表和表关系抽取两套核心对象 Entity 和 Query ,动态绑定一套事件机制 Create,Delete,update,getObjectByName,ByFilter,ById 类似的架构,底层很灵活,前段应用层通过抽象的 API 屏蔽掉 SQL 层

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1038960

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX