当前位置: 首页 > news >正文

苏州做网站价格python 做网站模块

苏州做网站价格,python 做网站模块,怎么是一个网站看起来高大上,怎么做微课网站简介#xff1a;读 A Philosophy of Software Design 有感#xff0c;软件设计与架构复杂度#xff0c;你是战术龙卷风吗#xff1f; 作者 | 聂晓龙#xff08;率鸽#xff09; 来源 | 阿里技术公众号 读 A Philosophy of Software Design 有感#xff0c;软件设计与架…简介读 A Philosophy of Software Design 有感软件设计与架构复杂度你是战术龙卷风吗 作者 | 聂晓龙率鸽 来源 | 阿里技术公众号 读 A Philosophy of Software Design 有感软件设计与架构复杂度你是战术龙卷风吗 一 前言 有一天一个医生和一个土木工程师在一起争论“谁是世界上最古老的职业”。医生说“上帝用亚当的肋骨造出了夏娃这是历史上第一次外科手术所以最古老的职业应该是医生”土木工程师说“在创世纪之前上帝从混沌中创造了天堂与人间这是更早之前的一次土木作业所以最古老的职业应该是土木工程”。这时软件工程师拖着键盘走出来说“那你认为是谁创造了那片混沌” 建筑师不会轻易给100层的高楼增加一个地下室但我们却经常在干这样的事并且总有人会对你说“这个需求很简单”。到土里埋个地雷这确实不复杂但我们往往面临的真实场景其实是“在这片雷区里加一个雷”而雷区里哪里有雷任何人都不知道 。 二 什么是复杂性 我们一直在说系统很复杂那到底什么是复杂性关于复杂的定义有很多种其中比较有代表的是Thomas J. McCabe 在1976提出的理性派的复杂性度量与John Ousterhout 教授提出的感性派的复杂性认知。 1 理性度量 复杂性并不是什么新概念早在上世纪70年代软件就已经极其复杂开发与维护的成本都非常高。1976年McCabeAssociates公司开始对软件进行结构测试并提出了McCabe Cyclomatic Complexity Metric我们也称之为McCabe圈复杂度。它通过多个维度来度量软件的复杂度从而判断软件当前的开发/维护成本。 2 感性认知 复杂度高的代码一定不是好代码但复杂度低的也不一定就是好代码。John Ousterhout教授认为软件的复杂性相对理性的分析可能更偏感性的认知。 Complexity is anything that makes software hard to understand or to modify -- John Ousterhout 《A Philosophy of Software Design》 译所谓复杂性就是任何使得软件难于理解和修改的因素。50年后的今天John Ousterhout教授在 A Philosophy of Software Design 书中提到了一个非常主观的见解复杂性就是任何使得软件难于理解和修改的因素。 模糊性与依赖性是引起复杂性的2个主要因素模糊性产生了最直接的复杂度让我们很难读懂代码真正想表达的含义无法读懂这些代码也就意味着我们更难去改变它。而依赖性又导致了复杂性不断传递不断外溢的复杂性最终导致系统的无限腐化一旦代码变成意大利面条几乎不可能修复成本将成指数倍增长。 三 复杂性的表现形式 复杂的系统往往也有一些非常明显的特征John教授将它抽象为变更放大Change amplification、认知负荷Cognitive load与未知的未知Unknown unknowns这3类。当我们的系统出现这3个特征说明我们的系统已经开始逐渐变得复杂了。 症状1-变更放大 Change amplification: a seemingly simple change requires code modifications in many different places. -- John Ousterhout 《A Philosophy of Software Design》 译看似简单的变更需要在许多不同地方进行代码修改。变更放大Change amplification指得是看似简单的变更需要在许多不同地方进行代码修改。比较典型的代表是Ctrl-CV式代码开发领域模型缺少内聚与收拢当需要对某段业务进行调整时需要改动多个模块以适应业务的发展。 /*** 销售捡入客户*/ public void pick(String salesId, String customerId) { // 查询客户总数 long customerCnt customerDao.findCustomerCount(salesId); // 查询销售库容 long capacity capacityDao.findSalesCapacity(salesId); // 判断是否超额 if(customerCnt capacity) { throws new BizException(capacity over limit);} // 代码省略 do customer pick } 在CRM领域销售捡入客户时需要进行库容判断这段代码也确实可以满足需求。但随着业务的发展签约的客户要调整为不占库容。而客户除了销售捡入还包括主管分发、leads分发、手工录入、数据采买等多个场景如果没对库容域做模型的收拢一个简单的逻辑调整就需要我们在多个场景做适配才能满足诉求。 症状2-认知负荷 Cognitive load: how much a developer needs to know in order to complete a task. -- John Ousterhout 《A Philosophy of Software Design》 译开发人员需要多少知识才能完成一项任务。认知负荷Cognitive load是指开发人员需要多少知识才能完成一项任务。使用功能性框架时我们希望它操作简单部署复杂系统时我们希望它架构清晰其实都是降低一项任务所需的成本。盲目的追求高端技术设计复杂系统增加学习与理解成本都属于本末倒置的一种。 TMF是整个星环的支柱也是业务中台面向可复用可扩展架构的核心。但TMF太过复杂认知与学习成本非常高我们日常中所面临的一些扩展诉求99%或者应该说100%都不适合TMF可能通过一些设计模式或者就是一些if else可能更适合解决我们的问题。 除此之外还包括一些简单搜索场景却用到了blink等流式引擎简单后台系统通过DDD进行构建几个商品发布的状态机转换用上了规则引擎等等都属于认知负荷复杂度的一种。 症状3-未知的未知 Unknown unknowns: it is not obvious which pieces of code must be modified to complete a task -- John Ousterhout 《A Philosophy of Software Design》 译必须修改哪些代码才能完成任务。未知的未知Unknown unknowns是指必须修改哪些代码才能完成任务或者说开发人员必须获得哪些信息才能成功地执行任务。这一项也是John Ousterhout教授认为复杂性中最糟糕的一个表现形式。 当你维护一个有20年历史的项目时这种问题的出来相对而言就没那么意外。由于代码的混乱与文档的缺失导致你无法掌控一个500万行代码的应用并且代码本身也没有明显表现出它们应该要阐述的内容。这时“未知的未知”出现了你不知道改动的这行代码是否能让程序正常运转也不知道这行代码的改动是否又会引发新的问题。这时候我们发现那些“上帝类”真的就只有上帝能拯救了。 四 为什么会产生复杂性 那软件为什么越来越复杂是不是减少一些犯错就能避免一场浩劫呢回顾那些复杂的系统我们可以找到很多因素导致系统腐化。 想简单图省事没有及时治理不合理的内容缺少匠心追求对肮脏代码视而不见技术能力不够无法应对复杂系统交接过渡缺失三无产品几乎无法维护 除了上述内容外还可以想到很多理由。但我们发现他们好像有一个共同的指向点 - 软件工程师似乎所有复杂的源头就是软件工程师的不合格导致所以其实一些罪恶的根因是我们自己 1 统一的中国与分裂的欧洲 欧洲大陆面积大体与中国相当但为什么欧洲是分裂的而中国是统一的。有人说他们文化不一样也有人说他们语言不通是主要原因也有人说他们缺一个秦始皇。其实我们回顾欧洲的历史欧洲还真不缺一个大一统的帝国。罗马帝国曾经让地中海成为自己的内海拿破仑鼎盛时期掌管着1300万平方公里的领地。欧洲也曾出现过伟大的帝国但都未走向统一。 我们再观察地图其实除了中国、俄罗斯以外全世界99%的国家都是小国。分裂才是常态统一才不正常。马老师也曾说过成功都有偶然性只有失败才存在必然。只有极少国家才实现了大一统所以我们不应该问为什么欧洲是分裂的而应该问为什么中国是统一的。类比到我们的软件也同样如此复杂才是常态不复杂才不正常。 2 软件固有的复杂性 The Complexity of software is an essential property, not an accidental one. -- Grady Booch 《Object-Oriented Analysis and Design with Applications》 译软件的复杂性是一个基本特征而不是偶然如此。Grady Booch在 Object-Oriented Analysis and Design with Applications 中提出这样一个观念他认为软件的复杂性是固有的包括问题域的复杂性、管理开发过程的困难性、通过软件可能实现的灵活性与刻画离散系统行为的问题这4个方面来分析了软件的发展一定伴随着复杂这是软件工程这本科学所必然伴随的一个特性。 Everything, without exception, requires additional energy and order to maintain itself. I knew this in the abstract as the famous second law of thermodynamics, which states that everything is falling apart slowly. -- Kevin Kelly 《The Inevitable》 译世间万物都需要额外的能量和秩序来维持自身无一例外。这就是著名的热力学第二定律即所有的事务都在缓慢地分崩离析。Kevin Kelly在 The Inevitable 也有提过类似的观点他认为世间万物都需要额外的能量和秩序来维持自身所有的事物都在缓慢地分崩离析。没有外部力量的注入事物就会逐渐崩溃这是世间万物的规律而非我们哪里做得不对。 五 软件架构治理复杂度 为软件系统注入的外力就是我们的软件架构以及我们未来的每一行代码。软件架构有很多种从最早的单体架构到后面的分布式架构、SOA、微服务、FaaS、ServiceMesh等等。所有的软件架构万变不离其宗都在致力解决软件的复杂性。 1 架构的本质 编程范式指的是程序的编写模式软件架构发展到今天只出现过3种编程范式( paradigm ),分别是结构化编程面向对象编程与函数式编程。 结构化编程取消 goto 移除跳转语句对程序控制权的直接转移进行了限制和规范面向对象编程限制 指针 的使用对程序控制权的间接转移进行了限制和规范函数式编程以 λ演算法 为核心思想对程序中的赋值进行了限制和规范 面向对象的五大设计原则 S.O.L.I.D。依赖倒置限制了模块的依赖顺序、单一职责限制模块的职责范围、接口隔离限制接口的提供形式。 软件的本质是约束。商品的代码不能写在订单域数据层的方法不能写在业务层。70年的软件发展并没有告诉我们应该怎么做而是教会了我们不该做什么。 2 递增的复杂性 软件的复杂性不会凭空消失并且会逐级递增。针对递增的复杂性有3个观点 模糊性创造了复杂依赖性传播了复杂复杂性往往不是由单个灾难引起的我们可以容易地说服自己当前变更带来的一点点复杂性没什么大不了 曾经小李跟我抱怨说这段代码实在是太恶心了花了很长时间才看懂并且代码非常僵硬而正好这个需求需要改动到这里代码真的就像一坨乱麻。我问他最后是怎么处理的他说我给它又加了一坨。 3 编程思维论 战术编程 其实小李的这种做法并非是一个个体行为或许我们在遇到复杂代码时都曾这样苟且过John教授这种编程方法称之为“战术编程”。战术编程最主要的特点是快同时具备如下几个特点。 当前一定是最快的不会花费太多时间来寻找最佳设计每个编程任务都会引入一些复杂度重构会减慢当前任务速度所以保持最快速度 HSFProvider(serviceInterface AgnDistributeRuleConfigQueryService.class) public class AgnDistributeRuleConfigQueryServiceImpl implements AgnDistributeRuleConfigQueryService {Overridepublic ResultModelAgnDistributeRuleConfigDto queryAgnDistributeRuleConfigById(String id) {logger.info(queryAgnDistributeRuleConfigById id id);ResultModelAgnDistributeRuleConfigDto result new ResultModelAgnDistributeRuleConfigDto();if(StringUtils.isBlank(id)){result.setSuccess(false);result.setErrorMsg(id cannot be blank);return result}try {AgnDistributeRuleConfigDto agnDistributeRuleConfigDto new AgnDistributeRuleConfigDto();AgnDistributeRuleConfig agnDistributeRuleConfig agnDistributeRuleConfigMapper.selectById(id);if(agnDistributeRuleConfig null){logger.error(agnDistributeRuleConfig is null);result.setSuccess(false);result.setErrorMsg(agnDistributeRuleConfig is null);return result}this.filterDynamicRule(agnDistributeRuleConfig);BeanUtils.copyProperties(agnDistributeRuleConfig, agnDistributeRuleConfigDto);result.setSuccess(true);result.setTotal(1);result.setValues(agnDistributeRuleConfigDto);} catch (Exception e) {logger.error(queryAgnDistributeRuleConfigById error,, e);result.setSuccess(false);result.setErrorMsg(e.getMessage());}return result;} }我们看上面这段代码是一段查询分发规则的业务逻辑。虽然功能能够work但不规范的地方其实非常多 Facade层定义全部逻辑 - 未做结构分层业务与技术未做分离 - 耦合接口信息与业务数据Try catch 满天飞 - 缺少统一异常处理机制没有规范化的日志格式 - 日志格式混乱 但不可否认他一定是当前最快的。这就是战术设计的特点之一永远按当前最快速交付的方案进行推进甚至很多组织鼓励这种工作方式为了使功能更快运作只注重短期收益而忽略长期价值。 战术龙卷风 Almost every software development organization has at least one developer who takes tactical programming to the extreme: a tactical tornado. -- John Ousterhout 《A Philosophy of Software Design》 译几乎每个软件开发组织都有至少一个将战术编程发挥到极致的开发人员战术龙卷风。将战术编程发挥到极致的人叫战术龙卷风。战术龙卷风以腐化系统为代价换取当前最高效的解决方案或许他自己并未觉得。战术龙卷风也有如下几个特点 是一位多产的程序员没人比龙卷风更快完成任务总能留下龙卷风后毁灭的痕迹留给后人去清理是真的很卷 一些组织甚至会将战术龙卷风视为英雄为什么能干得又多又快因为他将成本放到了未来。软件工程最大的成本在于维护我们每一次代码的改动都应该是对历史代码的一次整理而非单一的功能堆积。龙卷风能赢得现在但终将失去未来而这个失败的未来或许需要全团队与他一起买单。 战略编程 John教授提出与战术编程相对的是战略编程战略编程更注重长期价值不满足于功能work致力于制作出色的设计以满足对未来扩展的诉求注意不要过度。战略设计有如下4个特点 工作代码远远不够引入不必要的复杂度不可接受不断对系统设计进行小幅改进投资心态每位工程师都需要对良好的设计进行连续的少量投资 10~20% John Ousterhout教授在 A Philosophy of Software Design 书中提到了战略设计与战术设计的总成本投入。随着时间的流逝战略设计可以有效控制软件成本但战术设计会随着时间的推移线性递增。这与Martin Fowler在 Patterns of Enterprise Application Architecture 这本书中所提的关于数据驱动与领域驱动关于复杂度的治理是同样的含义要致力于长期的价值投资。 4 系统的困境与演进 没有系统是天然复杂的为了快速完成任务不断引入新的复杂度至系统逐渐腐化无限增长与无限传递的复杂度让软件需求越来越难“快速完成”。当有一天我们意识到系统的复杂性时再试图通过战略设计进行软件的迭代你会发现举步维艰一处很小的修改需要投入大量的基建修复最终我们不得不向成本低头不断再通过战术设计无限的苟且。 A condition that is often incorrectly labeled software maintenance. To be more precise, it is maintenance when we correct errors; it is evolution when we respond to changing requirements; it is preservation when we continue to use extraordinary means to keep an ancient and decaying piece of software in operation. Unfortunately, reality suggests that an inordinate percent- age of software development resources are spent on software preservation. -- Grady Booch 《Object-Oriented Analysis and Design with Applications》 译我们总是说我们需要“维护”这些老系统。而准确的说在软件发展过程里只有我们修正错误时才是维护在我们应对改变的需求时这是演进当我们使用一些极端的手段来保持古老而陈腐的软件继续工作时这是保护苟且。事实证明我们更多的时间是在应对最后一种状况。如同Grady Booch在 Object-Oriented Analysis and Design with Applications 中所提到的观点当我们使用一些极端的手段来保持古老而陈腐的软件继续工作时这确实是一种苟且。我们小心翼翼、集成测试、灰度发布、及时回滚等等我们没有在“维护”他们而是以一种丑陋的方式让这些丑陋的代码继续能够成功苟且下去。当代码变成意大利面条时将几乎是不可能修复成本将成指数倍增长并且似乎我们的系统已经存在这样的代码并且可能还在持续增加中。 六 架构伪论 在架构设计中总有一些软件工程师所坚信的诗和远方但到不了的乌托邦不一定就是遥不可及的美好圣地实则也可能是对系统无益甚至有害的架构设计。这里列举其中2条可能存在的架构伪论。 1 好的代码自解释 Comments do not make up for bad code -- Martin Fowler 《Clean Code》 译注释不是对劣质代码的补救Martin Fowler在 Clean Code 书中提到注释不是对劣质代码的补救以前我也一直坚信如果代码足够好是不需要注释的。但实则这是一个伪命题John教授这么评价它 ‘good code is self-documenting’ is a delicious myth。 /*** 批量查询客户信息*/ public ListCustomerVO queryCustomerList(){ // 查询参数准备UserInfo userInfo context.getLoginContext().getUserInfo(); if(userInfo null || StringUtils.isBlank(userInfo.getUserId())){ return Collections.emptyList();}LoginDTO loginDTO userInfoConvertor.convert(userInfo); // 查询客户信息ListCustomerSearchVO customerSearchVOList customerRemoteQueryService.queryCustomerList(loginDTO);IteratorCustomerSearchVO it customerSearchVOList.iterator(); // 排除不合规客户 while(it.hasNext()){CustomerSearchVO customerSearchVO it.next(); if(isInBlackList(customerSearchVO) || isLowQuality(customerSearchVO)){it.remove();}} // 补充客户其他属性信息batchFillCustomerPositionInfo(customerSearchVOList);batchFillCustomerAddressInfo(customerSearchVOList); return customerSearchVOList; } 这段代码我们可以很轻松的在5秒内看明白这个函数是做什么的并且知道它内部的一些业务规则。无限的私有方法封装会让代码链路过深无限类的拆解会造成更多网状依赖至少有3点内容让我们绝不能抛弃注释。 无法精准命名命名的含义是抽象实体隐藏细节我们不能在一个名字上赋予它全部的信息而必要的注释可以完美的进行辅佐。设计思想的阐述代码只能实现设计不能阐述设计这也是为什么一些复杂的架构设计我们需要文档的支撑而非代码的‘自解释’在文档与代码之间的空隙由注释来填补。母语的力量这点尤其适合我们中国人有时并不是因为注释少代码多所以我们下意识会首先看代码。而是我们几十年感受的文化让我们对中文与ABC具有完全不一样的感观。 2 永远追求最优雅 雷布斯曾自夸自己写的代码像诗一样优雅追求优雅的代码应该是每个软件工程师的心中的圣地。但有时存在一些不优雅存在一些‘看似不合理’并不代表就不对反而有时在追求更优雅的路上我们持续跑偏。 The goal of software architecture is to minimize the human resources required to build and maintain the required system. -- Robert C.Martin 《Clean Architecture》 译软件架构的终极目标是用最小的人力成本来满足构建和维护该系统的需求Robert C.Martin在 Clean Architecture 一书中提到了架构终极目标用最小的人力成本来满足构建和维护该系统的需求。架构始终是我们解决复杂度的一个工具如果当前系统并不复杂我们不需要为了所谓的优雅去过分改造与优化它持续将成本置在一个较低水位就是软件最好的解决办法。 业务简单的系统不应用DDD架构弱交互场景也无需进行前后端分离哪怕是邓总设计师在规划新中国的发展上也是制定了一套‘中国特色社会主义’制度。不要盲从一些教条的观念选择适合自己的控制在可控制范围内既不过度也不缺失。毕竟没有绝对的优雅甚至没有绝对的正确。 七 写在最后 很多人认为做业务开发显得没那么有挑战性但其实正好相反。最难解决的bug是无法重现的bug最难处理的问题域是不确定性的问题域。业务往往是最复杂的面向不确定性设计才是最复杂的设计。软件工程学科最难的事情是抽象因为它没有标准、没有方法、甚至没有对错。如何在软件固有的复杂性上找到一条既不过度也不缺失的路是软件工程师的终身课题或许永远也无法达到或许我们已经在路上了。 原文链接 本文为阿里云原创内容未经允许不得转载。
http://www.sadfv.cn/news/56578/

相关文章:

  • 中国城乡建设部网站房贴文件免费ppt模版网站
  • 如何将自己做的网站传到网上怎么给网站做spm
  • 哪里可以做网站php网站模板源码
  • 北京网站建设找华网天下wdcp wordpress伪静态
  • 帮人做钓鱼网站以及维护想开一家公司需要多少钱
  • 视频一页网站怎么做公司中英文网站建设
  • 网站返回首页按钮h5商城网站建设是什么
  • 站长号定制网络接口报警灯生产厂商
  • 做网站吗公司主页设计案例
  • 郑州网站技术顾问怎么联系做网站公司
  • dw怎么做网站教程网站设计详细设计
  • 做网站模板的海报尺寸多少钱学做ps的软件的网站有哪些内容
  • 网站建设伍金手指下拉2邯郸微信推广平台
  • 做网站的公司叫什么名字呼市做网站公司
  • 网站建设电话销售技巧和话术嘉兴网站建设一薇
  • 珠海做网站需要多少钱赶集招聘网
  • wordpress获取分类文章标题列表南昌做网站优化的公司
  • 天津高端网站建设公司房地产销售段子
  • 昆山设计网站的公司2016年网站推广方法
  • 网站开发 环境制作公司网页要注意什么问题
  • 网站后台怎么网站相似度检测 站长
  • 好看网电影网站模板免费下载东莞 企业网站建设
  • 牙科网站模板抖音小程序怎么删除
  • 爱用建站dede后台网站主页
  • 磁力棒柳州网站seo优化公司
  • 石柱县建设局网站电子网站开发技术包括
  • 潘家园网站建设公司关于网站建设工作的通报
  • 成都网站建设 Vr学做饺子馅上那个网站
  • 网站建设补贴是经信局的政策吗建设网站软件下载
  • 看室内设计案例的网站公司长沙建站