背景
做过很多需求.每次需求过来,稍微分析一下就开始建表写代码.两年下来,总感觉对开发流程,代码规范的认知缺少深度,这里想通过阅读代码大全这本经典,对自己做一次总结.
什么是软件构建
定义问题
需求分析
规划构建
高层设计
详细设计
编码与调试
单元测试
集成测试
集成
系统测试
保障维护
隐喻
写作,代价是丢掉一张草稿
培育,软件开发相当于系统生长,骨架-肌肉-皮肤,增量式开发.
建造, 定义问题-设计(线路)-审查(质检)
前期准备
有些人断言,前期准备毫无用处.
前期准备不周全的原因:
- 不具备相关规划技能.学习
- 尽快编码的欲望.总结之前的项目痛点
问题定义
问题定义只定义了问题是什么,而不涉及任何可能的解决方案
需求变更
为什么会有变更?
随着客户参与项目的时间增长,他们对项目的理解也就越深.
平均情况,25%的需求会有变化.特殊情况,75%-85%的需求变更
架构的组成部分
程序组织 Programma Organization
主要的类 Major Classes
80/20法则:对哪些构成系统80%的行为的20%的类进行详细说明
数据设计
数据通常只应该由一个子系统或者一个类直接访问
业务规则
用户界面设计
资源管理
安全性
性能
可伸缩性
互用性
国际化/本地化
输入输出
错误处理
%90的代码用来处理异常情况,10%的代码处理常规情况
一般被认为是代码约定层次的事情
以下是关于错误处理需要考虑的事情:
- 进行纠正还是检测?
- 检测是主动还是被动?
- 如果传播错误?
- 错误消息的处理有什么约定?
- 如何处理异常?记录或者描述
- 每个类在验证输入数据的有效性方面,需要负何种责任?每个类都验证,还是有一个类负责验证整个系统的数据有效性?
- 使用运行环境的错误处理机制,还是自己建立一套?
容错性
容错策略:
- 检测到错误退回去,退回到之前一切正常的时刻,从该点继续运行
- 切换到另外一套辅助程序
- 表决算法
- 使用默认值代替错误值
- 遇到错误时,进入”部分运转”的状态
架构的可行性
过度工程
买还是造
关于复用的决策
变更策略
表驱动技术
架构的总体质量
你,作为一个实现该系统的程序员,是否对这个架构感觉良好?
构建中的设计
设计是一个险恶(wicked)的问题,wicked指的是你必须把这个问题”解决”一遍,才能明确地定义它,然后再次解决该问题,从而形成一个可行的方案.
关键的设计概念
设计的难题主要包括偶然的难题和本质的难题
管理复杂度
复杂度原因
- 用复杂的方法解决简单的问题
- 用简单但错误的方法解决复杂的问题
- 用正确但复杂的问题解决复杂的问题
应对复杂度
- 最小复杂度 避免做出”聪明的设计”,应该做出简单且易于理解的设计
- 易于维护 为其他程序员着想
- 松散耦合 设计出关联尽可能少的类
- 可扩展性
- 可重用性
- 高扇入(被利用) 让大量的类使用某个子类
- 低扇出 少量或适中地使用其他的类(7个以下)
- 精简性 一本书的完成,不在他不能再加入任何内容的时候,而在不能再删去任何内容的时候
- 层次性
- 标准技术
设计的层次
- 子系统或者包 子系统之间的调用,应该是无环图
- 分解为类
- 分解为子程序
- 子程序内部的设计
找出容易改变的区域
对变化的预期能力
- 找出看起来容易变化的项目
- 把容易变化的项目分离出来
- 把看起来容易变化的项目隔离开来
容易变化的区域
- 业务规则
- 对硬件的依赖性
- 输入和输出
- 非标准的语言特性
- 困难的设计区域和构建区域
- 状态变量
- 常量
耦合标准
尽可能缩减相互连接
耦合的种类
简单数据参数耦合
简单对象耦合
对象参数耦合
语义上的耦合,使用潜在的耦合假设,危险
类和子程序适用于降低复杂度的首选和最重要的智力工具,如果他们没帮助你简化工作,那么他们就是失职的
常见的设计模式
设计模式是一种非常强大的管理复杂度的工具
但同时也存在一个潜在的陷阱:”为了模式而模式”,有时候对代码进行一些微小的改动,以符合某个广为人知的模式,会使这段代码更容易理解.
但是如果一段代码做出巨大改动,迫使它去符合某个标准模式,有时反而会把问题复杂化
数学领域的解题思路
- 理解问题,未知量,现有数据,条件分别是什么.现有数据是否足够,或者不够
- 再次之前你遇到过这个问题吗,或者类似的问题.
- 盯住未知量,试着想出一个有着相同或者类似未知量的问题来
- 现在能重述这个问题吗,用之前不同的方式重述
- 如果还是解决不了,试着先去解决一些相关的问题,一个更一般,或者更特殊,或者问题的一部分
- 设计一个计划,找出现有数据和未知量的联系
- 执行这一计划,能否检查每一步,并证明他是正确的
- 回顾整个解