Bill Venners与Martin Fowler的对话(进化型设计)

马丁·福勒探讨了计划型设计与进化型设计的区别,强调通过重构等实践不断改进设计的重要性。他认为,良好的设计不仅能够提高代码质量,还能提升工作效率。

对话马丁·福勒(Martin Fowler)——第三部分:进化型设计
简介

在连载的第三部分,福勒讨论了计划型设计和进化型设计的区别,揭示了着眼于解决表象问题可以使开发者发现本质问题,并主张好的设计工作不会降低工作效率。


第三部分:进化型设计

在连载的第三部分,福勒讨论了计划型设计和进化型设计的区别,揭示了着眼于解决表象问题可以使开发者发现本质问题,并主张好的设计工作不会降低工作效率。


计划型设计和进化型设计

比尔:在你的论文《设计是否已死》(Is Design Dead)一文中,谈到了计划型设计。那么什么是计划型设计?
马丁:我将设计区分为计划型设计和进化型设计。当开发者着手实施一个软件时,他首先需要做设计,然后再按照这个设计进行编 码实现软件,这就是我所说的计划型设计。计划型设计可能借助 UML;或者把整个系统分为若干子系统,定义这些子系统间的接口。在计划型设计中,在设计和代码实现这二者之间存在明确的切换。而这二者又往往由不同的人 来完成。架构师构思设计,开发者编码实现。做好的设计并不是说一点都不能改变,但基本上是固定的。你可能会说,设计做得越好,在编码的时候,就会越少对设 计做出改动。
而在进化型设计中,开发者在编程实践的过程中逐渐完善设计。刚开始的时候并没有设计,而是先实现一些小的功能。随着实现的功能越来越多,设计才逐渐成型。
我在《设计是否已死》一文中想要强调的是,很多人在尝试进化型设计时,往往是在一种无约束无原则的环境里,最终的设计必然很蹩脚。这是人们之所以倾向于计划型设计的原因之一。
但是,在我看来,极限编程实践中,通过持续不断的集成、测试和重构,进化型设计能够做到比计划型设计更有效。计划型设计的弱点就是,要想做出一个好的设计非常难。
比尔:为什么?
马丁:我解释不清楚。这就跟解释不清楚为什么谱一曲交响乐会如此困难一样。世界上能把这些工作做好的人可以说是凤毛麟角。我想,我认为预先设计(upfront design)就属于这类工作。要做好这类工作实在是太难了。
有趣的是,很多进化型设计的倡导者,比如肯特·贝克和沃德·坎宁安,都是非常出色的设计师。但正是他们,最后认识到自己所做的预先设计往 往不够好。他们容易把一些事情过于工程化,在不需要灵活性的地方设计灵活性,而在需要灵活性的地方又未予以考虑。因此,他们最终采用了进化型设计,并通过 运用一套规则,保证了设计效果。其结果是,不但最终的设计更加出色,并且速度也加快了。拿我自己来说,80%左右的时间里,进化型设计会得到不错的结果。 而不客气地说一句,我认为我的设计水平要比一般人高。因此,我认为进化型设计应该可以适用于更广泛的人群。


重构与预先设计

比尔:重构如何改变了预先设计的地位?
马丁:人们之所以采用计划型设计,是因为他们认为改动代码是件很麻烦的事情。因为当你改变代码时,有可能破坏了一些东西并造成许多漏洞。可是,如果你既有单元测试,又有在测试基础上建立起来的有条理的重构技术,那么你就能十分快速有效地改动代码,并且不太会引起什么问题。
比尔:预先设计在重构和其他可行的实践中有什么作用?你现在还会做一些预先设计吗?
马丁:我认为一些地方还是可以用到预先设计的,不过不会很多。一些人——像肯特·贝克和罗恩·杰弗里斯——认为预先设计已 经消亡了。从某种意义上来说,他们是对的,因为你可以借助进化型设计搭建更复杂的系统。但在某些情况下,预先设计可能让你的进度加快一些。比如说,我不赞 同在架设数据库之前就讨论数据库的进化问题。我可能会对数据库的存在有一个初步的判断,然后以此作为起点。当然,我仍会用进化的方式完成大部分设计。
比尔:构造良好的(well-factored)程序和设计良好的(well-designed)程序之间有区别吗?
马丁:它们在本质上并没有什么区别,但侧重点有所不同。设计强调的是构造——将程序划分为若干分割清晰的部分。对我来说,“构造良好的”一词表达了更多对于设计的感觉,也即当你审视或使用这个设计时的感觉。


代码中的“坏味道”

比尔:在你的《重构》一书中,关于何时应用重构,你是这样阐述的:“与其去追求一些很模棱两可的编程美学原则(坦率地说,这是我们咨询师们最喜欢做的事情),还不如来点儿更实际的。”
我很好奇,你是怎么看待美学的?我的经历中有很多次都是跟已有的代码打交道。这些代码的设计很烂,因此处理起来非常痛苦。如果这些设计能做得好些,让我不那么痛苦的话,我会非常感激。所以,对我来说,美学至少还是有些意义的,它可以使我的工作轻松些。
马丁:嗯,在讨论何时应用重构时,我的确是这样谈论美学的。从某种意义上说,我在重构准则中所给的那些条条框框也是一种模 棱两可的美学原则。不过,我试着给出更多的说明,而不是仅仅说“当你的代码看上去很丑陋的时候就需要做重构。”比如说,重复的代码是一种“坏味道”,再比如 说,很长的方法是一种“坏味道”,或者很臃肿的类也是一种“坏味道”。
很多“坏味道”是很容易嗅出来的。令人惊奇的是,当你审视你的程序时,往往一些很明显的现象,像是某个方法长达100行,就能引导你改进你的设计。
在重构这个长达100行的方法时,你可能会发现一些诸如责任分配(responsibility allocation)不合理这样的设计问题。像这样的问题,你是不可能光凭扫一眼代码就发现的;但是,一个长达100行的方法,却是一眼就能看出来的。 所以说,很表象的问题能够把你带向更深层的问题。
比尔:我参与过的一个项目竟然有一个长达11页的 while 循环。
马丁:这太不可思议了。
比尔:我们苦干了六个月试图让这个软件稳定运行,可是我们不敢动这个11页的循环。
马丁:这恰恰从另一个侧面说明了这个长达11页的循环是个糟糕的设计。如果你对改动某处代码心存顾虑的话,那它显然是一个蹩脚的设计。


良好的设计与效率

比尔:我想,人们不注重设计的一个原因是由于工作的流动性。那个最初编写11页 while 循环的程序员在我们接手项目的时候已经离开了公司。我认为,程序员因为自己的糟糕设计而自食其果的情况很少发生,因此他们没有足够的动因去注重设计。此 外,即便他们注重,但设计毕竟是一项费力不讨好的工作,好的设计需要时间,而开发中的时间压力往往很大。
马丁:我不同意“好的设计需要更长的时间”这样的说法。
比尔:为什么?
马丁:这是很有意思的一件事。在软件业,我们似乎普遍认为,慢工出细活。但当我回顾我自己的经历时,却发现保持代码的良好构造以及编写测试反而使我的工作加快了。
我想,人们把改进设计所花的时间看作是“失去”的时间,但却没有看到将来对代码的改动会容易得多,往往只需要几分钟的时间,否则可能要花上两三个小时。
人们往往还低估了在调试上所花的时间,低估了他们用来追踪一个“潜伏”很久的漏洞所花的时间。我在写代码的时候可以立即察觉产生的漏洞, 这使得我能在它潜伏下来之前就解决它。没有几件事比调试更花时间和更令人沮丧的了。假如我们一开始就能避免产生漏洞,那效率岂不是要提高很多?

本指南详细阐述基于Python编程语言结合OpenCV计算机视觉库构建实时眼部状态分析系统的技术流程。该系统能够准确识别眼部区域,并对眨眼动作持续闭眼状态进行判别。OpenCV作为功能强大的图像处理工具库,配合Python简洁的语法特性丰富的第三方模块支持,为开发此类视觉应用提供了理想环境。 在环境配置阶段,除基础Python运行环境外,还需安装OpenCV核心模块dlib机器学习库。dlib库内置的HOG(方向梯度直方图)特征检测算法在面部特征定位方面表现卓越。 技术实现包含以下关键环节: - 面部区域检测:采用预训练的Haar级联分类器或HOG特征检测器完成初始人脸定位,为后续眼部分析建立基础坐标系 - 眼部精确定位:基于已识别的人脸区域,运用dlib提供的面部特征点预测模准确标定双眼位置坐标 - 眼睑轮廓分析:通过OpenCV的轮廓提取算法精确勾勒眼睑边缘形态,为状态判别提供几何特征依据 - 眨眼动作识别:通过连续帧序列分析眼睑开合度变化,建立动态阈值模判断瞬时闭合动作 - 持续闭眼检测:设定更严格的状态持续时间闭合程度双重标准,准确识别长时间闭眼行为 - 实时处理架构:构建视频流处理管线,通过帧捕获、特征分析、状态判断的循环流程实现实时监控 完整的技术文档应包含模块化代码实现、依赖库安装指引、参数调优指南及常见问题解决方案。示例代码需具备完整的错误处理机制性能优化建议,涵盖图像预处理、光照补偿等实际应用中的关键技术点。 掌握该技术体系不仅有助于深入理解计算机视觉原理,更为疲劳驾驶预警、医疗监护等实际应用场景提供了可靠的技术基础。后续优化方向可包括多模态特征融合、深度学习模集成等进阶研究领域。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值