热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

软件架构设计中要注意的六个方面

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

1:软件中唯一不变的就是变化。



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


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


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


2:KISS:(Keep It Simple,Stupid):


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


3:面向抽象编程。


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


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


如果你想对设计原则有更多的了解,可以参见这里面向设计原则理解和一些软件设计的原则。


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


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


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


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


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


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


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


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


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


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

推荐阅读
  • 【Java编码规范】《阿里巴巴Java开发手册(正式版)》发布!
    2019独角兽企业重金招聘Python工程师标准2017年开春之际,诚意献上重磅大礼:阿里巴巴Java开发手册,首次公开阿里官方Ja ... [详细]
  • Java工程师书单(初级,中级,高级)
    简介怎样学习才能从一名Java初级程序员成长为一名合格的架构师,或者说一名合格的架构师应该有怎样的技术知识体系,这是不仅一个刚刚踏入职场的初级程序员也是工作一两年之后开始迷茫的程序 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Spring MVC 浅谈
    大学时写的的文章,当时文章水平略差,大家见谅。MVC这个词儿,最早的定义应该是作为一种软件架构设计模式出现在软工里面的,即使用model、view、controller来设计及定 ... [详细]
  • 出现_史上最大漏洞出现,你的安卓iPhone电脑都不安全了!
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了史上最大漏洞出现,你的安卓iPhone电脑都不安全了!相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 从高级程序员到CTO的4次能力跃迁!如何选择适合的技术负责人?
    本文讲解了从高级程序员到CTO的4次能力跃迁,以及如何选择适合的技术负责人。在初创期、发展期、成熟期的每个阶段,创业公司需要不同级别的技术负责人来实现复杂功能、解决技术难题、提高交付效率和质量。高级程序员的职责是实现复杂功能、编写核心代码、处理线上bug、解决技术难题。而技术经理则需要提高交付效率和质量。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 软件测试工程师,需要达到什么水平才能顺利拿到 20k+ 无压力?
    前言最近看到很多应届生晒offer,稍有名气点的公司给出的价格都是一年30多W或者月薪20几k,相比之下工作几年的自己薪资确实很寒酸.根据我自己找工作经历,二线城市一般小公司招聘 ... [详细]
author-avatar
飞扬8989_100
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有