代码之外的功夫
-
善用设计原型,探索项目创意
-
从理解项目背后的需求入手
细节问题都可以暂时搁置,现在应该几种精力探讨这个想法究竟是否可行 -
利用线框图表达功能需求
你可以通过线框图向大家解释待开发应用的基本结构,同时让大家都了解需要完成什么工作,以免过度关注技术细节而迷失了大方向 -
编程之初立即搭建测试系统
速成原型法的意义是拉近项目中每个参与者之间的距离。要达到这些目标,搭建一个人人都能使用的交互系统很有必要。这样不仅可以鼓励大家亲自操作和试验,还能让大家更方便地了解你的进度。 -
全面探讨不足,改善追求实效
每当发现自己的软件有瑕疵时,你可能想要停下手中的工作,立即去修复。但是在项目的探索阶段,你得去平衡软件缺陷带来的损失和修复这一缺陷的时间成本 -
早问多问,验证设想
多向项目参与者提一些能够发掘其目标的问题。这样一来,你既可以验证自己的想法,又可以更好地了解他人对问题的看法 -
力求缩小自己的工作范围
第一天所做的大部分工作是搭建一个基本框架,因此接下来的开发工作就会变得相对容易。你可以在这个已有的框架中发掘真正的问题,并试着去解决。如果一开始就直接考虑整个问题怎么解决,你就会很难找到一个切入点,这样停滞的时间就会更长。 -
谨记原型并非生产系统
在项目早期,集中精力解决有风险或未知的问题。建立原型是为了探索问题空间,而不是为了做出完整的产品。 -
巧妙设计特性,轻松收集反馈
想要做到张弛有度,知道什么时候该快、什么时候该细,是需要经验的。原型可以帮助你更快地做出有用的产品,但也可能让你失败地更快。但出现这样的情况并不意味着开发过程有问题,你恰恰应该做好准备面对反馈环加速所产生的这一副作用。如果不用花太多时间就能辨认出死胡同,那你就有更多的时间和精力去寻找正确的路。
-
-
观察增量变更,发觉隐藏依赖
-
不存在所谓的独立特性
不要因为某个变更没有明显改变现有特性,就认为它会向后兼容或绝对安全。相反,应该对隐藏的依赖关系随时保持警惕,即使进行的是最简单的更新操作。注意除代码库之外的大量共享资源,这些工具形成了一张隐藏依赖网,会给看起来毫无关联的应用特性带来副作用或引起故障。 -
两特性同屏必相互依赖
对数据库模式所做的任何修改都应该考虑到数据的一致性。不管新特性在代码层面上多么独立,在数据层面上仍有可能存在隐藏的依赖的关系。这意味着,为了支持某一特性而在代码库的某一部分进行的模式升级,可能会使一些看起来毫无关系的其他特性崩溃。 -
避免不必要的实时数据同步
因为太过耗时,很容易引发一系列问题。可以通过定时更新的方式来简化问题,毕竟数据更新不及时要比无响应崩溃等错误要可接受的多 -
复用旧代码,寻找新问题
利用限制和验证的方式,在最大程度上防止局部故障对整个系统造成影响。但还要确保系统拥有良好的监控机制,以保证快速知晓和处理突如其来的系统故障。
在复用现有的工具和资源时,要尤其注意使用环境的变化。任何对使用范围、性能标准或隐私安全级别的改变,如果不经过仔细考虑,都可能引起非常危险的问题。
-
-
准确识别痛点,高效集成服务
-
面对小众需求,切记未雨绸缪
我的理解是极端情况,可以用冒烟测试来避免。 -
谨记外部服务并不可靠
当你的应用依赖于你不甚了解的外部服务时,一定要加倍小心。如果找不到和你的用法相似的成功例子,就要提高警惕:往好的方面说,可能没有人用过该服务解决与你的需求类似的问题;往坏的方面说,该服务可能根本就不适合你。
谨记库和服务之间最关键的不同点:只有在代码库或基础设施发生改变时,库才会引起显著变更;而外部服务随时都可能让系统行为发生改变,甚至导致系统崩溃。 -
服务一旦有变,查找过期的模拟对象
如果遇到服务依赖变更,除了要进行代码复查,查找过期的模拟对象,一定还要定期运行小规模的自动化测试来审查服务本身。 -
遭遇烂代码,维护必头疼
处理紧急事件时,交流顺畅能够决定成败。
认真对待每次代码复查,把它当做对所依赖服务的一次小规模审查,比如评估测试策略、考虑如何处理故障或者思考如何防止错用资源。 -
不存在纯粹的内部问题
-
-
设计严密方案,逐步解决问题
-
收集实时,清晰描述
排除噪声信息,找到问题的核心,是在遇到任何复杂问题时都应该首先做的工作 -
写代码之前手动解决部分问题
难题由很多活动部分组成。先观察各个部分如何联系在一起,而不要管具体的实现细节。在写代码之前,先用纸笔解决部分问题。 -
核实输入数据,随后进行处理
在无效数据集上运用有效规则可能会得到难以调试的混乱结果。不要假设输入数据集的格式正确。 -
善用演绎推理,检验工作质量
-
欲解复杂问题,先知简单情况
递归、博弈等思维:每个问题的背后都有一堆简单的子问题,你早已知道如何解决它们。要将问题不断拆分,直到你能辨认出构成它的子问题为止。
-
-
谨记自底向上,优化软件设计
-
找出关键词,认清问题
-
从实现最小化功能入手
-
避免对象间不必要的时间耦合
在为项目增加新功能时,注意对象之间的联系。重视那些在量和时间上灵活的设计,这样对象就不会向其协作对象施加人为约束。 -
逐步提取可复用的组件与协议
推迟决策确实是自底向上设计的重要部分。过早提取对象,然后尝试去想象未来的使用情况,可能导致接口变的乱七八糟;一旦考虑实际需求,就能更轻松地进行接口设计。
在提取可复用的对象和函数时,寻找不太随时间变化的基本结构单元,而不是去找那些表面上看起来可以复用的模板式代码。
要充分利用那些在复用基本结构单元的过程中以外出现的特性,以便解决新问题。但同时要注意,在拼接对象时,不要使代码过于复杂。如果集成点过于混乱,就说明不适合使用自底向上的设计方法。 -
进行大量实验,发掘隐藏抽象
实验虽然很有趣,但只是为了帮助探索一些抽象概念。至于这些抽象概念是否能被正式支持,还要看它们是否能被证明有用。 -
了解自底向上方法的局限
在实际应用中,自底向上和自顶向下是相辅相成的。自底向上的设计方法有利于发掘新的设计理念,同时让设计保持间接。当你遭遇死胡同或碰到难点时,自顶向下的设计方法可以帮助你从整体上思考问题,将事务之间的联系统一起来。两种设计方法并非水火不容,只是用途不同。
-
-
认清现实瑕疵,改善数据建模
-
分清概念建模和物理建模
在数据源混乱的系统中,一般最好是保留一定的灵活性,不要在模型的物理层强加太多结构 -
明确设计模型,追踪数据变化
时间溯源模式将独立事件建模为不变的数据。这些数据代表不变的事实。通过遍历时间序列计算结果,可以看到系统当前的状态由于数据在以事件为基础的模型中单向流动,因此这一状态将永远与生成它的时间序列保持一致 -
理解康威定律,实践数据管理
组织在设计系统时会被自身的沟通结构所限制,设计出的系统会有相同的结构。
数据管理工作流的设计要尊重和支持软件使用者的组织文化。若在设计时不考虑康威定律,系统很可能被成千上万种使用方法压得不堪重负,最终崩溃。 -
谨记工作流设计与数据建模密不可分
-
-
逐渐改善流程,合理安排时间
-
敏捷、安全地应对意外故障
在处理系统级故障时,要根据需要停用或降级一些特性,使软件尽快回到可用状态。一旦压力得以缓解,便可以开始认真修复发生故障的部分。 -
识别并分析操作瓶颈
-
注意权衡工作的经济效益
寻找过度耗费时间的部分,用合理的安排加以限制,这样就可以省下时间进行其他工作。做决策不能只靠直觉,要使用毛估计算法,将经济因素也考虑进去 -
限制积压工作,力求减少浪费
谨记未上线的代码不是资产,而是存货。存货容易腐坏,并且具有持有成本。要帮助项目中的每个工作人员理解这一点。做法是让他们集中精力在给定的时间段内交付有价值的工作,而不是让团队中的每个人都为了忙碌而忙碌。 -
力求整体大于部分之和
与分工不同的人合作时,试着用对方能理解的方式进行交流。从旁观者的角度看待问题,并思考:这件事与正在和我交谈的人有关吗?这件事对整个项目有何影响?
-
-
认清行业未来,再议软件开发
-
程序员是用技术解决人类社会常见问题的人
-
站在足够高的层次与计算机交流,只需要关注如何解决问题,而不是纠结于代码编写的细枝末节
-
为了使计算机行业发挥所有潜能,我们需要一种开发工具链,其设计应完全以人为本、为人类服务
-
等等,我想解决什么问题来着?
-