原生态旅游网站开发需求分析建立门户网站多少钱
2026/4/17 2:44:46 网站建设 项目流程
原生态旅游网站开发需求分析,建立门户网站多少钱,邯郸市教育公共服务平台,吉安建设网站大家好#xff0c;我是Tony Bai。“Go 的哲学强调避免不必要的抽象。”这句话我们听过无数次。当你试图引入 ORM、泛型 Map/Reduce 、接口或者复杂的设计模式时#xff0c;往往会收到这样的反馈。这句话本身没有错#xff0c;但难点在于#xff1a;到底什么是“不必要”的我是Tony Bai。“Go 的哲学强调避免不必要的抽象。”这句话我们听过无数次。当你试图引入 ORM、泛型 Map/Reduce 、接口或者复杂的设计模式时往往会收到这样的反馈。这句话本身没有错但难点在于到底什么是“不必要”的函数是抽象吗汇编是抽象吗如果不加定义地“避免抽象”我们最终只能对着硅片大喊大叫。在 GopherCon UK 2025 上John Cinnamond 做了一场与众不同的演讲。他没有展示任何炫酷的并发模式而是搬出了马丁·海德格尔Martin Heidegger和伊曼努尔·康德Immanuel Kant试图用哲学的视角为我们解开关于 Go 抽象的终极困惑。注海德格尔与《存在与时间》马丁·海德格尔Martin Heidegger是 20 世纪最重要的哲学家之一。他在 1927 年的巨著《存在与时间》(Being and Time) 中深入探讨了人此在如何与世界互动。John Cinnamond 在演讲中引用的核心概念——“上手状态” (Ready-to-hand)和 “在手状态” (Present-at-hand)正是海德格尔用来描述我们与工具如锤子之间关系的术语。这套理论极好地解释了为什么优秀的工具或代码抽象应该是“透明”的而糟糕的工具则会强行占据我们的注意力。我们都在使用的“必要”抽象首先让我们承认一个事实编程本身就是建立在无数层抽象之上的。泛型这是对类型的抽象。虽然 Go 曾长期拒绝它但在技术上它是必要的否则我们将充斥着重复代码。接口这是对行为的抽象。io.Reader让我们不必关心数据来自文件还是网络。函数这是对指令序列的抽象。没有它我们只能写长长的main函数。汇编语言这是对机器码的抽象。所以当我们说“避免不必要的抽象”时我们真正想表达的其实是——避免“不恰当” (Inappropriate) 的抽象。那么如何判断一个抽象是否“恰当”何为抽象—— 一场有目的的“细节隐藏”在深入探讨“正确”的抽象之前我们必须先回到最基本的定义。John Cinnamond 在演讲中给出了一个精炼而深刻的定义“抽象是一种表示 (Representation)但它是一种刻意移除被表示事物某些细节的表示。”让我们拆解这个定义抽象是一种“表示”而非事物本身 它不是代码的实体而是代码的地图或模型。例如一辆模型汽车是真实汽车的表示但 Gopher 吉祥物是地鼠的抽象——它刻意省略了真实地鼠的所有细节只保留了核心特征。抽象是“有目的的”细节移除 这与仅仅是“不精确”或“粗糙”不同。抽象是有意为之的它不试图精确描绘所有方面而是只关注某个特定维度。抽象在编程中具有动态性不确定引用 (Indefinite Reference)一个抽象如io.Reader通常可以指代许多不同的具体实现。开放引用 (Open Reference)抽象的内容或它所指代的事物可以随着时间而改变。为什么要刻意移除细节John 总结了几个核心动机避免重复代码将重复的逻辑提取到抽象中。统一不同的实现允许以统一的方式处理本质上不同的数据结构如所有实现了Read方法的类型。推迟细节隐藏那些当下不重要、或开发者不关心的细节例如你坐火车参会不需要知道每节车厢的编号。揭示领域概念用抽象来更好地表达业务领域中的核心概念。驾驭复杂性这是最核心的理由——没有抽象我们无法在大脑中一次性处理所有细节也就无法解决复杂的问题。但请记住并非所有抽象都是一样的。John 将它们分为三类基于“它是如何工作的” (How it works) 这是为了代码复用而提取的抽象。例如你发现两处代码都在做“检查用户是否是管理员”的逻辑于是将其提取为一个函数。这种抽象关注的是内部机制。(这类抽象通常比较脆弱一旦实现细节变化抽象可能就会失效。)基于“它做了什么” (What it does) 这是 Go 语言中接口Interface最典型的用法。例如io.Reader我们不关心它是文件还是网络连接我们只关心它能“读取字节”。这是一种行为抽象。基于“它是什么” (What it is) 这是基于领域模型的抽象。例如一个User结构体它代表了系统中的一个实体。这种抽象关注的是本质属性。在现实中好的抽象往往是这三者的混合体但在设计时明确你是在抽象“行为”还是“实现”对于判断抽象的质量至关重要。理解了抽象的本质我们可能会觉得既然抽象能驾驭复杂性那是不是越多越好且慢。在急于评判一个抽象是否“恰当”之前我们必须先意识到一个常被技术人员忽略的现实抽象不仅存在于代码中更存在于人与人的互动里。这将我们引向了一个更现实的考量维度。抽象的代价 —— 代码是写给人看的John 提醒我们软件开发本质上是一项社会活动 (Social Activity)。“除非你是为了自己写着玩否则你的代码总是写给别人看的。团队是一个微型社会它有自己的习俗、信仰和‘传说’(Lore)。”引入一个新的抽象本质上是在向这个微型社会引入一种新的文化或规则。这意味着你需要支付“社会成本”如果这个抽象与团队现有的习惯Lore相悖——比如在一个从未用过函数式编程的 Go 团队里强推 Monad——你将遭遇巨大的阻力。团队的保守性成熟的团队往往趋于保守改变既定习惯需要巨大的能量。你不能仅仅因为一个抽象在理论上很美就引入它你必须证明它的收益足以覆盖它带来的社会摩擦成本。认知负担是共享的一个抽象对你来说可能很清晰但如果它让队友感到困惑那就是在消耗团队的整体智力资源。因此当我们评判一个抽象是否“恰当”时不能只看代码本身还必须看它是否“合群”。这正是我们接下来要引入海德格尔哲学的现实基础。锤子哲学 —— “上手状态” vs. “在手状态”John 引用了海德格尔在《存在与时间》中的一个著名概念Ready-to-hand (上手状态)与 Present-at-hand (在手状态*。上手状态 (Ready-to-hand)当你熟练使用一把锤子钉钉子时你的注意力完全在钉钉子这件事上锤子本身在你意识中是“透明”的。你感觉不到它的存在它只是你身体的延伸。在手状态 (Present-at-hand)当锤子突然坏了比如锤头掉了或者你拿到一把设计奇特的陌生工具时你的注意力被迫从“钉钉子”转移到了“锤子”本身。你开始审视它的构造、重量和用法。这对代码意味着什么好的抽象是“上手状态”的比如for循环。作为经验丰富的开发者你使用它时是在思考“我要遍历数据”而不是“这个循环语法是怎么编译的”。它透明、顺手让你专注于解决问题。坏的抽象是“在手状态”的比如一个复杂的、过度设计的 ORM 或者一个晦涩的 Monad 库。当你使用它时你的思维被迫中断你需要停下来思考“这个函数到底在干什么这个参数是什么意思”如果一个抽象让你频繁地从“解决业务问题”中抽离出来去思考“工具本身”那么它很可能是一个坏的抽象。注通过学习和实践在手状态 (Present-at-hand)的抽象可以转换为 上手状态 (Ready-to-hand)的抽象。真理的检验 —— “本质真理” vs. “巧合真理”接着John 又搬出了康德关于真理的分类引导我们思考抽象的持久性。分析真理 (Analytic Truth)由定义决定的真理。比如“所有单身汉都没结婚”。在代码中这就像unnecessary abstractions are unnecessary虽然正确但没啥用。综合真理 (Synthetic Truth)由外部事实决定的真理。比如“外面在下雨”。它的真假取决于环境随时可能变。本质真理 (Essential Truth)虽然不是由定义决定但反映了世界的本质规律。比如“物质由原子构成”。这对抽象意味着什么当你提取一个抽象时问问自己它代表的是代码的“本质真理”还是仅仅是一个“巧合”举个例子你有一段过滤商品的代码可以按“价格”过滤也可以按“库存”过滤。你提取了一个Filter(Product) bool的抽象。如果未来所有的过滤需求如颜色、大小都能用这个签名解决那么你发现了一个本质真理。这个抽象是稳固的。但如果突然来了一个需求“过滤掉重复的商品”这个需求需要知道所有商品的状态而不仅仅是单个商品。原本的Filter(Product) bool签名瞬间失效。如果你提取的抽象仅仅是因为几段代码“长得像”巧合而不是因为它们“本质上是一回事”那么当需求变更时这个抽象就会崩塌变成一种负担。由此可见好的抽象不是被创造出来的而是被发现Recognized出来的。它们是对代码中某种本质结构的捕捉。实战指南 —— 如何引入抽象最后John 给出了一个评估抽象是否“恰当”的五步清单明确收益 (Benefit)你到底是为了解决重复、隐藏细节还是仅仅因为觉得它“很酷”考虑社会成本 (Social Cost)编程是社会活动。这个抽象符合团队的习惯吗引入它是否需要消耗大量的团队认知成本比如在 Go 里强推 Monad等函数式编程的范式。是否处于“上手状态” (Ready-to-hand)它能融入开发者的直觉吗还是会成为注意力的绊脚石是否本质 (Essential)它是否捕捉到了问题的核心结构能经得起未来的变化是否涌现 (Emergent)它是你从现有代码中“识别”出来的模式还是你强加给代码的枷锁小结保持怀疑但别放弃好奇Go 社区的“避免不必要的抽象”文化本质上是对认知负担的防御。我们见过太多为了抽象而抽象的烂代码。但 John 提醒我们不要因此走向另一个极端——恐惧抽象。正确且必要的抽象是强大的武器它能让我们驾驭巨大的复杂性。只要我们能像海德格尔审视锤子那样审视我们的代码区分“上手”与“在手”区分“本质”与“巧合”我们就能在 Go 的简约哲学中找到属于自己的那条“正确”道路。资料链接https://www.youtube.com/watch?voP_-eHZSaqc你的“锤子”顺手吗用海德格尔的视角审视代码确实别有一番风味。在你现在的项目中有哪些抽象是让你感觉“如臂使指”的上手状态又有哪些抽象经常让你 “出戏”迫使你不得不去研究它内部的构造在手状态欢迎在评论区分享你的“哲学思考”让我们一起寻找那个最本质的代码真理。如果这篇文章带给你一次思维的“脑暴”别忘了点个【赞】和【在看】并转发给那些喜欢深究技术的伙伴点击下面标题干货- 读懂Go的设计哲学为什么说它是“恰到好处”的80/20语言- 为什么说 Go 的设计哲学是一场“逆行”- Go 的“显式哲学”为何在接口上“食言”了—— 探秘隐式接口背后的设计智慧- 【Go系统编程】01 文件I/O从文件描述符到 io.Reader/Writer 的抽象- 【Go开发者的数据库设计之道】05 落地篇Go 语言四种数据访问方案深度对比- Go语言的“灵魂拷问”接口只关乎行为还是也应拥抱数据- 像构建 Claude Code 一样构建应用揭秘 Agent-native 架构的 5 大核心原则 还在为“复制粘贴喂AI”而烦恼我的新极客时间专栏《AI原生开发工作流实战》将带你告别低效重塑开发范式驾驭AI Agent(Claude Code)实现工作流自动化从“AI使用者”进化为规范驱动开发的“工作流指挥家”扫描下方二维码开启你的AI原生开发之旅。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询