蘭陵N梓記

一指流沙,程序年华


  • 首页

  • 归档

  • 关于

  • 搜索
close

软件设计原则

时间: 2016-03-06   |   分类: 技术     |   阅读: 3047 字 ~7分钟

软件也像人一样,具有生命力,从出生到死亡,会经历多种变化。软件架构设计也不是一蹴而就的,是不断地演进发展。但为了能较好的发展,在软件设计时需要考虑一些原则。

清晰原则:使用简洁接口,简单部件组合

  • 编程的本质就是要控制复杂度,后期维护会占用大部分的时间。
  • 降低整体复杂度,用清晰的接口把若干简单模块组合成一个复杂的系统。
  • 对外隐藏细节,“不要与陌生人说话”。
  • 多数问题局限天一个局部,不要影响到全局。

小结:本质是分而治之,复杂问题简单化,抽象框架,有序组全。

清晰原则:清晰胜于机巧

  • 代码直白易懂,代码是给人看的,不是给机器看的。
  • 维护代码的人,其中也你包括你自己,善待代码,就是善待自己。
  • 不要了一点性能提升而引入复杂的算法,不要为了炫耀技能而编写晦涩难懂的代码。
  • 复杂晦涩的代码是Bugs的温床,高昂的维护成本将抵消可怜的性能提升。

小结:代码简洁晚懂,谨慎引入复杂度。

简洁原则:设计简洁,降低复杂

  • 复杂问题简单化是一个设计者的能力体现,避免不必要的使用问题复杂化的因素。
  • 在市场导向下,在不良的架构上很容易堆砌花哨无用的新特性,导致软件趋于复杂。
  • 在进度压力下,不会做出各种折中的个性与不和谐的新特性开发。

小结:过滤排序需求,追求稳定简洁。

组合原则:组合,接拼,编排

  • 把复杂问题分解为一条程序处理链条。
  • 程序之间可以通信,前者的输出是后者输入。
  • 通信方式尽量采用简单协议,并且与语言无关。
  • 组合程序之间无内部状态依赖,互相独立,处理链上下游不做假设,可替换。

小结:面向微服务的设计。

透明原则:设计与实现分离可见

  • 设计简单,包括流程、数据结构、接口,在代码级别容易理解。
  • 支行时刻可通过输出信息或者接口查询运行状态,可控制程序是否正确运行。
  • 执行调试链、健康状态可跟踪、可分析。

小结:简单设计,简明实现,状态监控。

吝啬原则:除非别无它法,不要编写庞大的程序

  • 程序庞大包括两个方面:程序体积大与程序复杂而维护困难。
  • 模块和函数尺寸都有一个上限,比如单模板代码10K,单函数100L。
  • 导致程序庞大的因素:先天设计不良,后天维护增加新特性。

小结:合理设计,考虑扩展性,对庞大保护警惕。

吝啬原则:有的放矢,按需分配资源

  • 若可能,当一个事情发生时候再分配资源,而不是预先分配,初始化时静态分配最小资源,随着业务动态增加资源分配。
  • 异步消息环境下,消息通信带来上下文切换,代价高昂。
  • 必要时对消息数据合并,打包发送,减少对网络资源的消耗。
  • 业务处理与消息发送分离,数据组织独立,统一打包发送。
  • 控制并发实例的数据,分批处理,防止下游过载各实例之间的恶性竞争通信资源。

小结:按需分配资源,珍惜消息通信机会。控制并发,避免消息突发。

健壮原则:健壮源于透明与简洁

  • 软件在超过设计者设想的意外场景下也能够运行良好。
  • Bugs是一种异常,复杂性和特殊处理都是Bugs的温床。
  • 逻辑透明,接口简单有助于减少Bugs,即使出现Bugs也容易排除。
  • 软件设计时要考虑异常输入,边界条件,和过载场景。
  • 软件模块之间要处理流程上考虑能务匹配,流控,过载保护。

小结:简单透明,处理能力匹配;考虑异常场景,提升健壮性;匹配上下游处理能力,闭环控制为主,开环控制为辅。

表示原则:把知识叠入数据,简化统一处理逻辑

  • 数据抽象建模,使用数据之间的关联关系来体现业务逻辑,或者领域知识,使得业务处理逻辑代码简单一致稳定。
  • 可通过修改数据模型可以支持新业务,逻辑处理代码不用修改。

小结:领域模型驱动设计,数据数据提练来描述业务本质。

缄默原则:只输出有用的信息

  • 保持沉默,良好的行为是默默地工作,决不唠唠叨叨,碍手碍脚,程序也是如此。
  • 输出大量无用的信息会耗费资源,淹没重要信息,干扰维护人员定位问题。

小结:沉默是金,惜时亦如金。输出的信息是必要的,有用的,不重复的。

补救原则:异常时候,干净退出,输出详细信息

  • 当程序出现异常时,输出必要信息,使用简单方法结束。
  • 宽容地接受,严格地发送,提升程序的容错能力。
  • 程序要么正确执行,要么响亮倒塌。

小结:看待这个问题一分为二,选择异常恢复方法要保证对用户的业务逻辑影响最小为基本原则。因此并不是说所有的异常都是进程退出重启,有时可以告警,事件通知,让管理员来处理,给出明确的修复方案说明。

经济原则:宁花机器一分钟,不花程序员一秒

  • 对于一个问题,选择算法的时候宁愿选择一个简单,但可能是效率低一些的算法,也不要选择一个性能好但复杂度很高的算法。
  • 硬件的进步来弥补性能的下降,换来的是程序简单可靠,维护成本低。

小结:辩证地看问题,选择简单,把复杂留给机器,解放程序员。

生成原则:避免手工Hack,让程序去生成代码

  • 人最不适合干大量重复细致的工作,或多或少都会出错,因此导致Bugs。
  • 与此相反,计算机最适合干规则明确,重复枯燥的工作,而且不会出错。
  • 对于一个规则明确的工作,一种可行的办法就是编写一个我程序,根据输入规则生成代码,让生成的代码去解决问题。

小结:分析规则,能按照规则生成代码,可检查发现问题。

优化原则:雕琢前先有原型,跑之前先学会走

  • 90%的功能能够实现,比100%功能永远不能实现要好得多。
  • 先求可行,再求正确,最后求快。
  • 原型可能有效地解决关键技术,保证系统是可以实现的。
  • 让客户看到可以执行的原型,对需求的理解更为准确,防止做无用功。
  • 过早优化是万恶之源,过早地优化会破坏程序结构,代码与数据结构杂乱无章;过早优化不清晰系统瓶颈,局部优化破坏整体优化。

小结:性能是设计出来,不是优化来出来。

多样原则:拒绝封闭和唯一

  • 系统开放,只有开放,才能进步,才能得到最为广泛的验证。
  • 开放,可扩展,用户可定制,符合实际需求和获到高可靠性。

小结:系统开发,留给用户定制空间,毕竟需求具体多样性,我们不能穷尽,最终只有用户才能准确理解自己的需求。

同源原则:避免重复,数据同源

  • 重复的代码不仅仅是浪费,也是Bugs的滋生之地。
  • 出现大段代码重复,说明开发者缺少对代码控制与抽象提炼能务,优秀的工程轻易不会在进度压力下让步。
  • 数据重复危害更大,一则浪费存储空间,二则容易出现不一致。
  • 在性能允许的情况下,尽量共享数据或者按需订阅,避免全量订阅。
  • 如果上述条件不具备,那么采用数据同源技术和一致性校验来保证数据的一致性。

小结:拒绝重复,必须重复的时候考虑通过工具同源和一致性校验。

扩展原则:设计时着眼未来,未来总比想象来得快

  • 对于一个一次性的程序来讲,架构和设计只会带来成本上升,复杂度提高,与性能的下降。
  • 当开发一个支持多种产品的软件平台,其生命周期可能是十年以上。用户的需求是不断地变化,硬件环境也是不断地变化。
  • 只有适应变化,不能拒绝变化,可扩展性是软件非功能属性中,在大部分情况下排在可靠性,高性能之前

小结:不对外界进行假设,这些假设在时间面前都是脆弱的。

扩展原则:给雪球寻找一个核心

  • 雪球都有一个内核,尽管可能是一粒不起眼的小石头。
  • 常说软件要内聚,内聚需要核心。
  • 微内核,插件化机制。框架即核心,框架之上定制好插件,构建系统。
  • 从问题知识域发现稳定部分进行抽象提升,成为系统的框架。

小结:从框架的角度来看系统,框架之间的有机组合构建系统,系统的演化就是在框架稳定情况下增加替换相关的插件。

扩展原则:扩展就是少修改

  • 软件可扩展性是有前提和应用场景的,不存在可以随意扩展的软件。
  • 增加新功能做到不修改既有软件,代码无需修改,通过修改数据模型或者重新配置获得新特性。
  • 修改集中在新增加的软件之上,也就是说在增加新特性时,对老代码封闭,对新代码新特性开放。

小结:系统开闭原则,修改对系统稳定不构成影响。


注:以上内容参考了公司设计原则。

#软件设计# #软件架构# #设计原则#
Grub引导Win10
使用tmux
微信扫一扫交流

标题:软件设计原则
作者:兰陵子
关注:lanlingthink(览聆时刻)
声明:自由转载-非商用-非衍生-保持署名(创作共享3.0许可证)

兰陵子

兰陵子

Programmer & Architect

164 日志
4 分类
57 标签
GitHub 知乎
© 2009 - 2022 蘭陵N梓記
Powered by - Hugo v0.101.0
Theme by - NexT
0%