登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
博客
发1篇日志+1圆
记录
发1条记录+2圆币
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
VIP网盘
VIP申请
网盘
联系我们
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
别让理论成为“紧箍咒”!打破开发教条主义做正确的软件 ...
别让理论成为“紧箍咒”!打破开发教条主义做正确的软件
[ 复制链接 ]
古修蟑
2025-6-26 09:15:15
“要是看到你在模板中写这种代码,很多人会怒不可遏。别理他们——他们都是教条主义的受害者。在模板里写代码没有任何不对,只要别写太多(尤其是别把业务逻辑放进模板)。”
—— David Heinemeier Hansson 评论 MVC 模式中,V 中带有少量逻辑判断,摘自《应用 Rails 进行敏捷 Web 开发》中文版 第343页。
David Heinemeier Hansson 这句直击灵魂的话,撕开了软件开发领域教条主义的虚伪面纱。在追求高效、规范开发的今天,开发模式和理论,本是助力我们的 “利器”,但却逐渐异化成了束缚开发者手脚的 “紧箍咒”。
软件开发的现实困局
当我们撕开行业光鲜的表象,会发现当代开发者正置身于一个充满矛盾的环境。
- 需求沼泽
在需求变更中艰难跋涉 需求冻结成为奢望,用户在模糊认知中不断迭代诉求,仿佛让建筑师在施工过程中反复修改蓝图。产品决策链中,缺乏技术背景的决策者以直觉驱动方案,那些违背工程逻辑的设计如同沙上筑塔,开发者在 "专业判断" 与 "执行指令" 的夹缝中进退维谷。
- 效率绞肉机
内卷化下的工期压缩 行业正陷入 "跑马圈地" 的狂热,人效考核将开发周期压缩至极限。当竞品以 "单机部署非事务架构" 的粗糙方案抢占市场,我们不得不面对一个残酷现实:在资本竞速中,完善的技术架构往往让位于快速交付和低廉的成本。
- 人才断层
经验传承的时代之殇 35岁职场红线造就年轻化开发团队,知识传承脱节,项目经验严重不足。视频教程催生的 "速成开发者" 虽降低入门门槛,却导致知识体系碎片化,让代码质量的根基悄然松动。很多人都沉迷于视频教程的快餐式知识投喂,鲜少真正触碰键盘敲下一行代码。这类伪专业人士,将大量时间消耗在观摩别人的技术实战,热衷于用精美架构包装空洞概念,动辄抛出 “微服务架构升级”、“AI 驱动转型” 等术语,却连最基础的代码都写不好。
- AI 冲击
效率革命与职业焦虑的双刃剑 编程助手已能胜任 70% 的常规开发工作,在代码补全、注释生成等场景展现惊人效率。这把双刃剑既为项目提效注入强心剂,也让基础编码岗位面临重构压力,开发者被迫在 "工具依赖" 与 "核心竞争力构建" 之间寻找新平衡点。
不要为了架构而架构
TDD:国内项目我不想再看见它
大约是2012年,我负责的一个外企的项目,约定使用 TDD 方式开发,并满足高测试覆盖率和交付相应代码和文档。这是我第一次接触 TDD,之前虽然也了解过但没有真正实操过。因为有甲方公司的业务顾问全程参与,需求变更较少,TDD 开发也算顺利。TDD 本身并不复杂,无非是一种开发方式和思维。借助 VS 的重构和单元测试工具进行 TDD 方式开发的过程很丝滑。该项目使我收获了相当宝贵的 TDD 实战经验。但那也是我唯一个没被 TDD 折磨的项目。
之后的很多年,虽然用 TDD 项目的公司很罕见,但是,还是让我遇到了两家家向 TDD 开发模式转型的公司,两者均以失败告终。太痛苦了!测试用例的变化速度,完全跟不上需求的变更速度。而且,根本不会给你足够的时间设计测试用例、完善文档和单元测试,最终得到的就是——一堆对不齐需求的测试用例,大量无用的单元测试,开发为了测试构建的无用代码,以及项目大幅度延期和海量加班后的疲惫团队。
TDD 存在以下弊端:
- 额外提高工作量
TDD 要求在编码前完成测试用例设计,这对简单功能可能产生30%-50% 的额外开发时间。
- 小型项目的投入产出失衡
在小微项目(如单页面应用、工具类程序)中,TDD 的测试架构搭建成本可能超过功能开发本身。
- 需求变更时的维护噩梦
测试用例、单元测试代码、业务逻辑代码的连锁修改成本很高。
- 对开发者技能的高要求
TDD 需要掌握单元测试框架、Mock 工具、重构等。
- 僵化的设计约束
TDD 要求提前定义接口和行为,这在需求快速迭代的场景中往往导致测试用例成为 “设计枷锁”,限制架构调整,开发者为兼容旧测试而保留过时逻辑,堆积“屎山”
- 过度设计与代码膨胀风险
为测试而牺牲的代码简洁性,引入不必要的接口(仅为便于 Mock),拆分过细的类(仅为便于测试)等。
- 维护中的隐性成本
当项目迭代加快时,会出现“需求-测试用例-单元测试-业务逻辑”不同步的情况,逐步失去质量保障作用。
TDD 的核心价值在于长期的代码质量保障,但其弊端提醒我们:技术实践需与项目特性、团队能力、业务节奏相匹配,盲目追求 “全TDD” 可能适得其反。
DDD:落地它的思想,抛弃它是束缚
DDD 的本质是帮助开发者理解业务的思维工具,而非用设计模式堆砌的技术秀场。DDD 被炒作的有点神话了,DDD 立了很多规矩,这些规矩正在束缚我们。
- 聚合根的神圣性
为满足 "聚合内强一致性",把简单的 "实体" 拆成多个聚合,本来一个方法内就能实现的需求,却要分散到多个方法调用实现,代码量暴增,性能却和可维护性下降。
- 属性、无参构造器的私有化
DDD 强调 “数据与行为绑定”,聚合根的属性变更必须通过其领域方法(而非直接修改属性)完成,因此,就会将属性的 set 方法设为私有。为了不创建 “不完整” 的聚合根(如属性未初始化),就要将无参构造器私有化。私有化属性 set 方法和无参构造器,是实现 “数据只能通过行为变更” 的技术手段。这种做法在 DDD 上很严肃,但现实中真的感觉很难用。首先,代码复杂度增加,需要为每个聚合根设计工厂或领域方法,对简单业务可能 “过度设计”。其次,部分 ORM 框架存在兼容性问题,对私有构造函数支持不佳,需额外配置。
- 通用语言的偏执
要求数据库表名、API 接口与领域术语完全对齐,会议上对命名争论不休。
- 充血模型的神化
盲目的相信充血模型,在非复杂核心业务域强行套用充血模型,增加复杂度。在软件项目的“快节奏+高变更”战场中,“贫血模型+服务层”的务实架构反而更具生存力。
- 领域层与服务层的腐化
领域逻辑与服务层逻辑的混淆是常见问题,两者职责边界模糊会导致系统架构混乱、维护成本激增。不同开发者对方法的具体实现位置存在争议是常见问题,开发过程中很难让全员达成共识。随着业务迭代、赶工,这种腐化会加剧,让“业务逻辑”分散和混乱。
- 过细的限界上下文
过细领域割据引入了更多的功能划分、防腐层、领域事件问题,开发和调试时像剥洋葱一样痛苦,时常在不同上下文间迷路。
- 设计文档的成本过高
往往前期需要投入大量的时间和精力完成 DDD 的设计文档,后期开发时间不足,在频繁变更和新需求加持下,前期的设计最终脱离最终现实,成为华丽的废纸。
总之,能在预算内交付正确功能的系统,比完美却延期的领域模型更有价值。当你学会 "用 DDD 的眼睛看业务,用 CRUD 的手敲代码",就会发现:实现它的思想,抛弃它的束缚,才是对领域驱动最真诚的致敬。毕竟,能在预算内交付并应对变化的系统,才是复杂业务的真正赢家。
前后端分离:不是唯一的选择
早期的 Web 开发采用 “前后端耦合” 模式,ASP.NET 等技术将页面逻辑与业务逻辑混杂在同一代码文件中。开发人员既要编写 HTML 样式,又要处理数据库查询和业务计算,代码臃肿且难以维护。随着互联网应用规模扩大,用户体验要求提升,这种模式的弊端愈发明显。
2010 年后,随着 JavaScript 技术的成熟、SPA(单页应用)框架( AngularJS、React、Vue.js等)的兴起,以及 RESTful API 规范的普及,前后端分离迎来了爆发期。前端专注于用户界面渲染和交互逻辑,通过 API 接口与后端通信;后端则负责业务逻辑处理、数据存储与 API 接口提供,两者各司其职,由此开启了 Web 开发的新篇章。
前后端分离通过技术栈的专业化,让 UI 具备更好的用户体验,更丰富的功能,更高效的交互,更快的刷新速度等。
思考这样一个常见的场景,写一个后台管理系统,而不使用前后端分离。如果是一名 .NET 后端开发者,可以使用 Razor + 开源的 UI 模板(比如 Layuimini 这类)的方式实现。此时,开发速度将是极快的,后端开发页面的时间是短到可以忽略不计的(模板和样式是现成的,只需 CV 操作)。这样做,无需前后端对齐数据结构和接口,无需前后端联调,加快了开发速度。由后端统一处理校验、安全性、多语言、个性化逻辑等,维持了技术栈的一致性。
会有哪些缺点呢?会因为缺少组件化损失复用性,还会损失一部分性能,但对于大多数简单 Web 项目,这些并不是关注的重点。
可见当使用 “传统后端渲染” 时,会带来巨大的开发效率提升,让项目已更短的周期,更低的成本上线。因此,我认为前后端分离并不是唯一选择。
- 对于复杂交互的页面(流程设计器、策略设计器、表单设计器、聊天窗口等),需要产品化的组件(大屏组件、仪表盘、地图、设备接口、多维度表格、画布等),有分工明确的团队支持,注重前端性能与用户体验的项目,适合“前后端分离”。
- 对于以表单交互为主的项目(官网、博客、后台管理等),需求简单,需要快速上线的项目,对 SEO 强依赖场景,安全性要求高的项目,团队规模小或资源紧张时,适合“传统后端渲染”。
单纯依赖 “前后端分离” 或 “传统后端渲染” 易陷入技术局限性 。前者增加开发成本和开发周期,对 SEO 不友好,后者不适合开发复杂交互的页面。最优解是根据模块特性动态组合两种模式,以“前后端分离”+“传统后端渲染”结合的方式开发系统的不同部分,在可复用性、用户体验、开发成本、开发效率之间寻找最优解。
需要特别说明的是——微服务架构并非必须采用前后端分离模式,两者并无强制依赖关系,微服务架构仍可采用传统后端渲染模式。
在实际项目中,建议根据业务场景选择适度分离的方案,而非盲从“前后端分离”模式。
打破 N 层架构的 "链式" 困局:从职责分化到极简建模
在软件架构演进中,N 层设计催生了 PO、DO、BO、DTO、VO 等数据对象类型,本意是通过职责分离提升系统可维护性。但现实中,过度追求 "完美分层" 常导致对象的链式转换、层层包装,反而引发代码膨胀、性能损耗等问题。回归建模本质,我们需要在解耦需求与工程效率间寻找平衡。
- PO(Persistent Object,持久化对象) PO 主要与数据持久化相关,它对应数据库中的表结构,用于实现对象与数据库表之间的映射。
- DO(Domain Object,领域对象) DO 起源于领域驱动设计(DDD)思想。DDD 强调对业务领域进行深入分析和建模,DO 就是对业务领域中核心概念的抽象。它包含领域的属性和行为,具有业务语义和完整性约束。在复杂业务系统开发中,DO 能帮助开发者更好地理解和表达业务需求,构建出更符合业务本质的软件系统。
- BO(BusinessObject,业务对象) 随着业务逻辑复杂度的增加,为了更好地组织和管理业务规则,BO 逐渐形成。它封装了具体的业务逻辑和业务规则,是业务领域的核心对象。
- DTO(Data Transfer Object,数据传输对象) 起源于分布式系统和远程调用场景。在跨系统、跨服务的数据交互中,为避免直接传输实体对象带来的性能损耗和不必要数据传输,开发者需要一种专门用于数据传输的对象,DTO 应运而生,它只包含需要传输的数据,能有效提升数据传输效率。随着前后端分离架构的流行,DTO 也常用于前后端数据交互,将后端数据处理结果封装成适合前端展示的格式进行传输。
- VO(View Object,视图对象) VO 主要用于视图展示,它的产生是为了将业务数据转换为适合视图呈现的格式。在 Web 开发中,页面展示的数据可能需要对业务数据进行加工、组合或过滤,VO 就负责承担这一职责,比如常见的 Model 和 ViewModel。
传统 N 层架构中,对象按层级进行转换,虽然符合分层设计的理论初衷,但在实际工程中会引发一系列复杂性问题:
- 多层转换的资源开销增加 GC 开销,有一定的性能损耗。
- 需要处理转换逻辑,且容易引入 bug 而且不易察觉。
- 字段变更连锁反应使变更成本呈指数级增长。
- 分层边界模糊导致职责混乱。
- 代码复杂度激增,可读性与可维护性下降。
N 层架构中对象的多层转换本质是 "过度工程化" 的产物,其引发的性能损耗、开发膨胀等问题是否超过解耦收益需要谨慎评估。务实的解决方案是:
中小型项目:用单一模型替代多层对象,以“极简”方式建模,通过特性标记(如[Required])定义业务校验、ORM 映射、序列化、字段权限、导入导出等,统一到单一位置定义,方便扩展和修改。
大型系统:仅在需要时保留必要转换,并用自动化转换(如 AutoMapper)代替手动转换,减少人工代码,避免引入 bug。
最终,架构设计应服务于 "以最小成本实现业务价值",而非追求理论上的分层完美。
线程安全:只有并发场景下才真正需要线程安全代码
只有在真实的并发场景中,线程安全代码才具有不可替代的价值。我们既要警惕因忽视线程安全引发的数据一致性问题,也要避免盲目添加同步机制造成的性能损耗。
部分追求 "代码洁癖" 的开发者,可能会对线程安全过度苛责。需要明确的是:线程安全机制虽能有效解决多线程环境下的资源竞争,但并非所有场景都需强制应用。若在单线程环境或无共享资源的场景中强行使用线程安全代码,犹如 "无病服药",徒增资源消耗与代码复杂度。
唯有当业务逻辑确实面临并发访问时,才需引入线程安全策略——这既是对性能的保护,也是对代码简洁性的维护。
过度设计:不用把“弹弓”设计成“上帝之杖”
在软件设计领域,"为架构而架构" 的过度设计现象屡见不鲜。典型表现为:用重型方案解决轻量需求,将简单问题复杂化,徒增成本却背离实用价值。
比如,用户需求仅是高可用,结果设计成了一个多租户的云原生 SaaS;比如,总用户数和数据量都不大,但非要按照200并发和单表1500w数据做设计;再比如,一个三层架构足以支撑的业务,偏要叠加领域驱动、微服务等多层框架。
中小型项目本可通过简单架构快速落地,却因盲目追求 "完美设计" 陷入开发泥潭。过度架构不仅推高编码与维护成本,更会因系统复杂度激增导致迭代效率暴跌。现实中,许多开发者并非不懂轻量级原则,而是困于 "怕被质疑专业度" 的心态,在 "技术优越感" 与 "业务实效性" 间选择了前者。对轻量级需求而言,能跑通的简单架构远优于 "看起来厉害" 的复杂方案 ,正如“杀鸡焉用牛刀”。真正的架构能力,体现在用最小成本解决实际问题,而非用技术炫技。
小结
AI 编程的强势崛起,正重塑软件开发者的价值体系。市场竞争的本质始终指向商业价值——当 AI 能在数秒内完成代码编写,传统设计模式所追求的复杂度控制、模块解耦与复用性,正面临效率维度的重新审视。曾被奉为圭臬的架构美学,在 AI 编程的降维打击下,其工程价值正逐渐让位于 "性价比三角":廉价实现、稳定运行与功能完整性。
这一变革揭示了残酷的现实:过度沉溺于设计模式的 "表现欲",执意构建 "看起来高级" 的架构,本质是对业务本质的背离。任何开发范式都不应沦为教条——它们是解决问题的工具,而非彰显技术优越感的图腾。架构选择必须基于用户需求、项目规模、团队能力与业务场景,让 "合适" 取代 "完美" 成为新的评判标准。
软件开发没有“银弹”。当 AI 重构代码的效率颠覆传统认知,开发者的核心竞争力正从 "代码审美" 转向 "业务洞察力"—— 聚焦于构建 "正确的软件",而非 "看起来高深的代码"。跳出教条主义的桎梏,让开发模式为我们所用,而不是我们为模式所困,才能真正释放代码的力量,打造出高效、优质的软件产品。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
古修蟑
2025-6-26 09:15:15
关注
0
粉丝关注
11
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9986
背竽
9992
猷咎
9990
4
凶契帽
9990
5
里豳朝
9990
6
处匈跑
9990
7
黎瑞芝
9990
8
恐肩
9988
9
终秀敏
9988
10
杭环
9988
查看更多