前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >战术性编程(Tactical programming )腐蚀系统,我们需战略性编程(Strategic programming)

战术性编程(Tactical programming )腐蚀系统,我们需战略性编程(Strategic programming)

作者头像
崔认知
发布2023-12-26 14:08:50
1500
发布2023-12-26 14:08:50
举报
文章被收录于专栏:nobodynobody

战术性编程(Tactical programming )腐蚀系统


在很多“经验丰富”的服务端工程师看来,实现产品需求的功能非常简单,无非是一系列接口和服务,通过不断地堆代码即可实现,这是一种典型的“战术性编程”思维。

在战术性方法中,您的主要重点是使某些功能正常工作,通过不断地堆代码即可实现,例如新功能或错误修复。乍一看,这似乎是完全合理的:还有什么比编写有效的代码更重要的呢?但是,战术编程几乎不可能产生出良好的系统设计。

战术编程的问题是它是短视的。如果您是战术编程人员,那么您将尝试尽快完成任务。也许您有一个艰难的期限。因此,为未来做计划不是优先事项。您不会花费太多时间来寻找最佳设计。您只想尽快使某件事起作用。您告诉自己,可以增加一些复杂性或引入一两个小错误,如果这样可以使当前任务更快地完成,则可以。(多数人还会自我安慰,如果可以让功能尽快上线的话,提高一些复杂度或者引入一两个小问题不是什么大不了的事情)。

如果您从事大型软件项目的时间很长,我怀疑您在工作中已经看到了战术编程,并且遇到了导致的问题。一旦您沿着战术路线走,就很难改变。

战术性编程(Tactical programming )的特点


几乎每个软件开发组织都有至少一个将战术编程发挥到极致的开发人员:战术龙卷风。

1、快。实施快速功能时,常以腐化系统为代价换取当前最快速的解决方案,几乎没有人能比他们更快地完成任务。在某些组织中,管理层将战术龙卷风视为英雄

2、高产。因为快,所以高产,堪称“卷王”。

3、坑多。他们往往倾向于简单地进行功能堆积,忽视原则和规范,将成本放到未来,由后来人买单。战术龙卷风留下了毁灭的痕迹。他们很少被将来必须使用其代码的工程师视为英雄。通常,其他工程师必须清理战术龙卷风留下的混乱局面,这使得那些工程师(他们是真正的英雄)的进步似乎比战术龙卷风慢

系统复杂化的表现


究竟什么是“复杂性”?您如何判断系统是否过于复杂?是什么导致系统变得复杂?

复杂性与软件系统的结构有关,这使它很难理解和修改系统(复杂性是指那些让系统难以理解或修改的与系统相关的任何事物)。复杂性可以采取多种形式。例如,可能很难理解一段代码是如何工作的。可能需要花费很多精力才能实现较小的改进,或者可能不清楚必须修改系统的哪些部分才能进行改进;如果不引入其他错误,可能很难修复(也可以是不引入额外问题的情况下,很难修复一个bug)。如果一个软件系统难以理解和修改,那就很复杂。如果很容易理解和修改,那就很简单。

复杂的系统通常有一些非常明显的特征:变更放大(ChangeAmplification)、认知负荷(Cognitive Load)和未知的未知(Unknown Unknowns)3大类。当我们的系统出现这3个特征时,说明系统已经开始变得复杂了。

1、变更放大:复杂性的第一个征兆是,看似简单的变更需要在许多不同地方进行代码修改。

2、认知负荷:复杂性的第二个症状是认知负荷,这是指开发人员需要多少知识才能完成一项任务。较高的认知负担意味着开发人员必须花更多的时间来学习所需的信息,并且由于错过了重要的东西而导致错误的风险也更大。

3、未知的未知: 复杂性的第三个症状是,必须修改哪些代码才能完成任务,或者开发人员必须获得哪些信息才能成功地执行任务,这些都是不明显的。

在复杂性的三种表现形式中,未知的未知是最糟糕的。一个未知的未知意味着你需要知道一些事情,但是你没有办法找到它是什么,甚至是否有一个问题。你不会发现它,直到错误出现后,你做了一个改变。更改放大是令人恼火的,但是只要清楚哪些代码需要修改,一旦更改完成,系统就会工作。同样,高的认知负荷会增加改变的成本,但如果明确要阅读哪些信息,改变仍然可能是正确的。对于未知的未知,不清楚该做什么,或者提出的解决方案是否有效。唯一确定的方法是读取系统中的每一行代码,这对于任何大小的系统都是不可能的。甚至这可能还不够,因为更改可能依赖于一个从未记录的细微设计决策。

系统复杂化的原因


既然您已经了解了复杂性的高级症状以及为什么复杂性会使软件开发变得困难,那么下一步就是了解导致复杂性的原因,以便我们设计系统来避免这些问题。复杂性是由两件事引起的:依赖性和模糊性

1、依赖性

依赖关系是软件的基本组成部分,不能完全消除。实际上,我们在软件设计过程中有意引入了依赖性。每次编写新类时,都会围绕该类的 API 创建依赖关系。但是,软件设计的目标之一是减少依赖关系的数量,并使依赖关系保持尽可能简单和明显。

2、模糊性

当重要的信息不明显时,就会发生模糊。一个简单的例子是一个变量名,它是如此的通用,以至于它没有携带太多有用的信息(例如,时间)。或者,一个变量的文档可能没有指定它的单位,所以找到它的唯一方法是扫描代码,查找使用该变量的位置。晦涩常常与依赖项相关联,在这种情况下,依赖项的存在并不明显。例如,如果向系统添加了一个新的错误状态,可能需要向一个包含每个状态的字符串消息的表添加一个条目,但是对于查看状态声明的程序员来说,消息表的存在可能并不明显。不一致性也是造成不透明性的一个主要原因:如果同一个变量名用于两个不同的目的,那么开发人员就无法清楚地知道某个特定变量的目的是什么。

依赖性导致变化放大和高认知负荷。模糊性会产生未知的未知数,还会增加认知负担。如果我们找到最小化依赖关系和模糊性的设计技术,那么我们就可以降低软件的复杂性。

战略性编程(Strategic programming)


成为一名优秀的软件设计师的第一步是要意识到 能跑起来的的代码是不够的。引入不必要的复杂性以更快地完成当前任务是不可接受的。最重要的是系统的长期结构。任何系统中的大多数代码都是通过扩展现有代码库编写的,因此,作为开发人员,最重要的工作就是促进这些将来的扩展。因此,尽管您的代码当然必须工作,但您不应将“工作代码”视为主要目标。您的主要目标必须是制作出出色的设计,并且这种设计也会起作用。这是 战略计划。

战略性编程需要一种投资心态。您必须花费时间来改进系统的设计,而不是采取最快的方式来完成当前的项目。这些投资会在短期内让您放慢脚步,但从长远来看会加快您的速度。

无论您预先投入多少,设计决策中都不可避免地会出现错误。随着时间的流逝,这些错误将变得显而易见。发现设计问题时,不要只是忽略它或对其进行修补。花一些额外的时间来修复它。如果您进行战略性编程,则将不断对系统设计进行小幅改进。这与战术编程相反,在战术编程中,您不断增加一些复杂性,这些复杂性将来会引起问题。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档