http://www.nowamagic.net/librarys/veda/detail/1897在做项目的时候,有些同事总是提前考虑性能优化,需求变更又是一大堆的重写,让我想起了Donald Knuth 提到的:对软件的过早地优化是万恶的根源。这里就简单的说几条重要的软件名人哲学。

软件中唯一不变的就是变化

在软件开发过程中需求是不停的变化的,随着客户对系统的认识,和现有开发功能和软件的认识,也许一开始他提出的需求就是背离的。记得网上有一句笑话,是说需求变化的:

程序员XX遭遇车祸成植物人,医生说活下来的希望只有万分之一,唤醒更为渺茫。可他的Lead和亲人没有放弃,他们根据XX工作如命的作风,每天都在他身边念:“XX,需求又改了,该干活了,你快来呀!”,奇迹终于发生了,XX醒来了,第一句话:“啊?需求又改了?”

在设计和架构中,凡事无绝对,作为架构师或者项目负责人你必须永远的清晰认识到没有完美的架构和设计,没有万能的软件。只存在当前环境,需求方案,团队人员素质,物理环境,安全等综合因素下的合适方案,由于种种原因你的解决方案可能不是某一个单一因素下的最优解。站在这个位置你需要做的是找到这个综合下的最优解,作出权衡。不要只从表面说某个人某个团队的解决方案怎么差怎么不好,或者这就是当时综合因素的最优解,站在同样的位置环境你不一定做得更好。在架构设计和人生,在我看来很相似,总是有一堆抉择,每一次的抉择都会带来得和失,权衡得失取舍。

KISS:(Keep It Simple,Stupid)

保持简单,但不过于太简单。在《UNIX下的编程哲学》中提到很多次保持设计简单,我们能清晰看到这条原则。现在视觉设计,都崇尚简约设计,简单而不庸俗,而不是一大堆的豪华奢侈打造。VB编程开始的可视化设计,可见即可得,google的首页,商业风格。在我们的软件设计中也需要简洁的设计,用户需要的是可见可量化的功能的正确性,而不是你运用了多牛b的技术模式,但绝不是一味的太过于简单。你想把意见简单的事情做复杂化是很容易的事情,但是把一件复杂的事情简单化却不那么容易。简单的人生就是幸福。但是这里需要说明的是简单是优秀的,但简单是有底线边界的,超过底线的简单也有变得稚幼。比如事务性脚本模式比其他3中常见模式都简单,但往往复杂的需求它不是最优解,因为他太过于简单了。

面向抽象编程

在设计模式,架构模式,OO中都是一条完全的主线,作为oo第一原则存在。我记不起哪个软件牛人曾说过:请牢记没有接口的话就不要开始实现。这句话也许过于偏激,但是如果你接口理解为不变或者不易变的话,理解或契约(公司和你的合同)更贴切些吧(可能是一个不变的类,如果你能肯定的说出你的这个实现在以后,在项目开发维护中是不会变的,我觉得这也是接口,接口在于不变和不易变),你也许会同意这句话。对于目前的需求你肯定能够没有抽象没够接口完全写出完美的代码,但是第一条中我们说明的软件中唯一不变的就是变化,在未来的需求中你能够很好的一样的优秀吗?如果不能,那么我认为面对当前需求就该为以后提供扩展延伸。

我个人理解23种设计模式中大多数基本都是围绕着这个Program to an interface, not an implementation(依赖接口而不是实现)第一原则为目的。当然我们也不能不说还有第二原则:组合优先于继承。以后的什么DIP(依赖倒置,IOC的原则),LSP(里氏替换),OCP(开闭原则)等等都是他们的延伸和扩展。在追溯的话这一些列都是为了软件系统“高内聚,低耦合”(可以简叙述为:功能完备(高内聚)的对象之间是靠接口(低耦合)通讯交互的),内聚是描述的功能性完备程度,耦合是表述模块间的依赖程度。这里插一句话某同事给我说依赖接口不是还有依赖嘛,我希望的是没有耦合,我的回答是:计算机二八原则说明了这一切,既然事物出现在一起了,那绝不是偶然情况,所以他们之间必定存在依赖,在软件设计中我们所能做的就是引入中间对象使其变为间接依赖,而减少他们之间的依赖,而我们希望这个中间对象是个相对稳定的,设计中一切都是一个词:间接,分层,mvc,mvp,soa,中间件等等都是体现直接依赖变为间接依赖。说这个话题的原因是引出我们“高内聚,低耦合”行之有效的方法SOC(分离关注点),这不只是OO的任然对面向过程编程行之有效,他是在20年前 SP(结构化编程)中提出来的。

首先考虑可维护,延伸性,事后优化

这里也是本文的起因,正如开篇所说,Donald Knuth 提到的:对软件的过早地优化是万恶的根源。在开发的时候我们不需要进行任何性能的优化,即使你认为这里可能存在性能的瓶颈,你需要考虑的更多的是设计的扩展和延伸性,以后的继续添加新功能和维护。对于用户需话要的需求,性能优化很多时候只是作为一个更好的体验存在。只有当真正出现性能瓶颈的时候,你才需要做性能的优化。一个可延伸可扩展,层次分明,代码清晰的模块,对于你的优化也是件容易的事情,在对项目后期对于项目的总体需求明白下你也有得到更多的优化方案。在重构模式中同样也提倡时候优化。过早的优化导致你的项目会越陷越深,到最后才知道用户其实根本不需要这么高的需求,或者是用户根本不常用的功能模块。优化也需要有标准,多少时间是用户能忍受的,目前是多少时间。往往用户对性能要求的只有那个少量常用的操作,而对于功能性需求的变更却是无止境的,维护成本却是高昂的。

最后说一句,经常有人说反射性能低下,对我们必须承认反射比其他方案性能是不好,但是我们有解决方案:缓存。在则说性能低下,是以什么什么标准?用户的接受程度?反射我们可以有其替代方案Emit,Expression tree。从反射,Expression tree,Emit的选择,其使用难度在提升,开发效率在增加,性能在改善。本人一般却倾向于Expression tree,两种居中吧。

继承是为了多态而不是重用

OOP中可以编写一个类,然后我可以不断的继承重用去扩展新需求。这是类的重用,是全部的重用?重用这个词看上去也许更加的微妙。多态是面向对象的核心特征之一,也不记不清那里听到的:重用只是继承的附带功能。在我们的继承体系中不宜庞大如果一个拥有4,5层的继承体系,对你的理解也增加难度,而且集成体系必须是个干净的继承体系,满足LSP(里氏替换原则):在所有用到父类的地方都可以替换为子类,还能正常准确工作。这就要求你继承更多的是修改扩展父类的行为,尽量避免状态。继承只是不要为了重用的为目的,在恰当的时机更好的办法是实现一个完全的类来替换不能满足现有需求的类。这也是oo原则第二原则吧,组合优先于继承。组合比如设计模式中的策略模式,你得到的是一个算法组合功能个数是一个笛卡尔积。但也是绝对的组合,只是优先,不是取代,软件和现实世界都是充满了矛盾的,就如开篇第一条“软件中唯一不变的就是变化”就是最大的矛盾,来自辩证唯物主义,你要做的是权衡。组合表述的是整体的替换,如策略模式模式的算法整体替换。继承是部分的少量的扩展修改行为,比如设计模式中的模版方案,在父类的流程控制下,部分步骤的修改,数据,事务的流转控制权在父类。这条在最后说一句:设计模式不是万能的,只是前人的优秀经验,是依赖于场景存在的,了解设计模式我觉得更重要的是其使用场景,在遇见同类场景的时候知道可以有这种模式作为解决方案或许更好,仅作为供你选择的解决问题方案。

用户的一切输入都是万恶的

用户的输入是属于我们系统之外的,是无法控制的,是不可罗列的。对于用户来说软件只是一个黑盒子,不需要,也没必要了解具体内在实现。对于汽车销售人员不需要了解发动机螺栓是怎么上的一样,他了解宣传的是能有什么优势,能给用户带来那些方面的满足,价格?性能?速度?豪华?….对于门户网站来说你对应的用户不仅是可信任的用户,可能还有竞争对手黑客攻击行为。如果你的系统信任于用户的输入,早晚一天总会“纸包不住火的”,用户有意无意的一次输入就可能导致你系统的功能性的全盘崩溃,你不应该限制用户的操作,你是不能命令用户该输入什么不能输入什么,比如某天某人使用用户可能降工资了或者挨批了,心情不好,你也许会潜意思的对你的系统进行挑战。

说到这里随便说一句,以前项目组有人层提过由于自动化测试服务器运行时间太长了,把部分验证等逻辑移到单元测试中保证。对于我的理解来说自动化测试近似于集成测试吧,功能性测试,应该是黑盒子。在单元测试中我们总是假设输入是正确的,某个依赖也是正确的,验证输出的正确。而集成测试重点在于这一些都是层次的组合,贯通,不存在假设的正确性,只有来自测试人员的测试用例得到预期的输出。

今天就写到这里吧,还有很多但是一下想不起来,后续有机会的话对于重要的也会继续补上。

现实是矛盾的,没有完美的设计,也没有绝对的简单。生活也是如此就如:简单就是幸福,快乐就是幸福。那么简单的标准是什么?怎样才是快乐?这在于你自己的抉择,权衡。想起了某次面试和小公司面试官谈话,面试官说ORM存在性能问题,而且一直在纠结的说反对DDD,反对模式。本人现说了如果存在了性能问题有什么解决方案,首先怎么做如果不能满足在怎么做,从索引缓存到分表服务集群,再总结性的一句话:架构如人生,总是要面临得到取舍。

谈谈对一些软件架构设计箴言的理解 对软件的过早地优化是万恶的根源 反设计模式案例简介...相关推荐

  1. 软件架构设计箴言理解 (转自博客园)

    软件架构设计箴言理解 http://www.cnblogs.com/whitewolf/archive/2012/06/02/2532244.html 2012-06-02 21:30 by 破狼, ...

  2. 软件架构设计箴言理解

    假设你对项目管理.系统架构有兴趣.请加微信订阅号"softjg",增加这个PM.架构师的大家庭 今天和师弟聊天聊到他们项目开发,有些同事总是提前考虑性能优化.需求变更又是一大堆的重 ...

  3. 软件架构设计总结和理解

    1. 软件架构设计的What & Why ● 啥是软件架构(Software Architecture)? 软件架构是指在一定的设计原则基础上,从不同角度对组成系统的各部分进行搭配和安排,形成 ...

  4. 软件架构设计系列总结—7—设计箴言理解

    今天和师弟聊天聊到他们项目开发,有些同事总是提前考虑性能优化,需求变更又是一大堆的重写,让我想起了Donald Knuth 提到的:对软件的过早地优化是万恶的根源.这里就简单的说几条重要的软件名人哲学 ...

  5. 软件架构设计系列总结

    架构引用维基百科:软件体系结构是构建计算机软件实践的基础.与建筑师设定建筑项目的设计原则和目标,作为绘图员画图的基础一样,一个软件架构师或者系统架构师陈述软件构架以作为满足不同客户需求的实际系统设计方 ...

  6. 《软件架构设计.第二版解析软件架构概念》阅读笔记——到底什么是软件架构?...

    2019独角兽企业重金招聘Python工程师标准>>> 我的经历及对软件架构的理解 我个人从事软件开发8年,大大小小软件做过不计其数,做过企业应用的架构设计,也做过全新的互联网在线S ...

  7. 西工大软件学院软件架构设计复习

    软件架构设计复习 前言 本复习文档,是对于<软件建模与设计:UML.用例.模式和软件体系结构>一书的总结归纳. 面向软件架构(体系结构)设计,以UML语言为基础,从基于用例的需求建模.基于 ...

  8. 系统架构师—软件架构设计(一)概述、构建、视图、基本架构风格

    1.软件架构概述 从需求分析到软件设计之间的过渡过程称为软件架构.只要软件架构设计好了,整个软件就不会出现坍塌性的错误,即不会崩溃. 架构设计就是需求分配,将满足需求的职责分配到组件上. 软件架构为软 ...

  9. 软件架构(5)---软件架构设计的一些总结和理解

    1. 软件架构设计的What & Why ● 啥是软件架构(Software Architecture)? 软件架构是指在一定的设计原则基础上,从不同角度对组成系统的各部分进行搭配和安排,形成 ...

最新文章

  1. 图灵新浪微博赠书活动
  2. 清华自动驾驶前沿报告!解密六大关键技术,全球人才分布【附下载】| 智东西内参...
  3. 解决ubuntu无法修改分辨率为1920*1080问题
  4. php基于新浪ip库获取城市,PHP基于新浪IP库获取IP详细地址的方法
  5. java struts2 excel上传_文件上传方法,使用Struts2,实现Excel文件读取并写入数据库技术...
  6. faster rcnn论文_【论文解读】精读Faster RCNN
  7. STC8PROG - Linux下的 STC8G STC8H 烧录工具
  8. ​说了你可能不信,这是一份王者荣耀接口文档
  9. gitlab上创建新的分支并发布代码
  10. 问题:oracle id自增 insert语句如何写?
  11. 关于NorFlash的一点总结
  12. 网络安全定义和安全威胁
  13. 推流yasea遇到问题,即调转摄像头算法
  14. NX机电概念设计学习笔记(3)铰链副 齿轮 速度控制
  15. 集成产品开发(IPD)简介
  16. 为什么在网络的最后用average pooling layer 代替FC
  17. Android 7.0 行为变更
  18. srm供应商关系管理系统
  19. 2022电工(初级)考试模拟100题及答案
  20. PPTX双重预防体系风险四色图制作(34页)(附下载)

热门文章

  1. matlab错误dparsfa,用dparsfa做功能连接时报错
  2. python中flush什么意思,Python的file.flush()到底在做什么?
  3. c++ 返回空对象_python中file对象的常用方法
  4. 联想微型计算机怎么进入bios,详细教你联想电脑怎么进入bios
  5. python强制转型,python2--python3如何转型
  6. java 防御编程_用Java编程。实现两个人对决。有血量有防御。有攻击力
  7. 电脑右下,电脑右下图标怎么显示出来怎么办
  8. redis一般用来干嘛_谈谈redis的热key问题如何解决
  9. python语言的特点强制可读_python程序语言设计第二讲(笔记)
  10. DSP之外部设备连接接口之HPI