如何编写优质的需求文档

fmms 13年前
     <p>        英文原文:<a title="How to write good requirements" href="/misc/goto?guid=4958333718234582465" rel="nofollow" target="_blank">Job Vranish</a></p>    <p>        编写需求文档,在嵌入式开发领域是非常普遍的。需求文档被用来定义开发任务,协调大规模的研发计划。对于最终的产品,需求文档扮演着开发者行为 和消费者行为之间沟通纽带的角色。当需求文档书写正确的时候,便可以发挥巨大的作用。然而,如果你在嵌入式开发领域工作的时间足够长,你就会很快发现,这 个领域里不合格的需求文档实在是太多了。当你尝试对这些不合格的文档进行修复时,你又会很快发现,书写正确的需求文档绝非易事。在这里,我们提出一些建 议,希望能将书写正确需求文档这件事情变得清晰一些。</p>    <p>        从较高的层次来看,书写需求文档的目的就是要提供对所需行为的有效描述。该所需行为可用一个黑盒系统描述,并需要注意以下细节:</p>    <ul>     <li>工程师可以根据系统所说进行实现</li>     <li>测试人员,在不与开发人员沟通的前提下,可以利用满足硬件要求的设备验证需求。</li>     <li>最终产生的成果满足终端用户的要求。</li>    </ul>    <dl>     <dt>      <a title="黑盒测试" rel="lightbox[15561]"><img style="display:block;margin-left:auto;margin-right:auto;" title="黑盒测试" alt="如何编写优质的需求文档" src="https://simg.open-open.com/show/afc7dadc8968ad093e3d3bc0ac3284d1.jpg" width="300" height="82" /></a>     </dt>    </dl>    <ul>     <li>黑盒测试</li>    </ul>    <p>        <strong>书写优质的需求文档:</strong></p>    <p style="text-align:center;"><a title="如何编写优质的需求文档" rel="lightbox[15561]"><img title="如何编写优质的需求文档" alt="如何编写优质的需求文档" src="https://simg.open-open.com/show/f8e88cdafc9b09ad59ef8c15858b59cb.jpg" width="300" height="190" /></a></p>    <p>        <strong>最基本的原则是:需求文档应当尽量简洁,用最易懂的描述来约束系统的预期行为。</strong>如果你遵循这个原则,剩下的那些重要因素(可测试性、避免过度设计等等)都将变得顺理成章。</p>    <p>        列举一下更详细的规则,通常会更有帮助。下面是书写优质需求文档需要遵循的步骤:</p>    <p>        1. 定义系统的边界。这也是黑盒系统所必要的。</p>    <p>        2. 定义输入和输出。这也应当是你看待内部系统的唯一方式。</p>    <p>        3. 用最易懂的方式描述系统的预期行为</p>    <p>        4. 除了输入和输出之外,你的需求是不是还涉及了系统的其他部分?如果是,那么你的需求就设计过度了。<a title="重构" href="http://www.amazon.cn/gp/product/B003BY6PLK/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B003BY6PLK" rel="nofollow" target="_blank">重构</a>需求,让它变得精简。</p>    <p>        5. 你的需求是不是过于模棱两可?加入更多的限定规范。注意:有些模棱两可的描述并不是坏事,假设描述所包含的所有情况均可被接受,且测试的时候不需要附加的信息加以说明,那么就没关系。你不需要(也不应该)把系统的行为限制得过头。</p>    <p>        6. 你的需求是否可测试?(这里指的是黑盒测试)如果不是,你最好返回到第 4 步。如果这种返工发生很多次,那就说明你的黑盒无法正确描述系统,或者你的测试工具不够优秀。无论是哪种情况,不可测试的需求文档几乎就是一文不值的。</p>    <p>        7. 你的需求文档通俗易懂么?如果你的需求文档非常难以读懂,那就说明你写得不好,只能给那些照着你的需求负责实施的人带来无尽的痛苦。如果是这样,回到第 3 步。</p>    <p>        8. 你是不是真的做到了第 4 步?你确认么?再检查一下。</p>    <p>        <strong>例子:</strong>下面的例子,让我们描述一个自制的嵌入式设备的需求,这个设备能从弯曲传感器上读取弯曲的频率,并根据不同的频率值让一个 LED 闪烁。</p>    <p>        显然,我们已经完成了步骤 2 和步骤 3 了!</p>    <p>        · 输入:从弯曲传感器读取数据。</p>    <p>        · 输出:LED。</p>    <p>        但是我们跳过了步骤1:</p>    <p>        · 在这个例子里,我们将把黑盒画到设备的微处理器上。</p>    <p>        让我们继续往下进行,</p>    <p>        <strong>第四步:</strong>除了输入和输出以外,我们是否还涉及了其他的系统边界?</p>    <p>        · 微处理器并不关心从弯曲传感器读取什么样的数据,从处理器的角度来看,仅需要做的是测量 ADC 脚的电压而已。</p>    <p>        · LED 仅由数字输出脚控制。</p>    <p>        下面,让我们来修正这个问题:</p>    <p>        第 0 版本的需求:</p>    <p>        1. 该设备应当根据 ADC 脚的不同频率的电压,来切换数字输出端的状态。</p>    <p>        <strong>第五步:</strong> 需求写模棱两可么?</p>    <p>        恩,我们的描述太模棱两可了.输出端切换的速度要多快? 跟电压的关系如何? 输入电压的范围是多少? 让我们加一些更细节的描述吧:</p>    <p>        版本0.1</p>    <p>        1. 输出端应当由一个自由活动的定时器进行控制</p>    <p>        2. 自由运行定时器的频率最高不得高于每秒 10 次,不得低于每秒 1 次.</p>    <p>        3. 自由运行定时器的触发频率应当在最高和最低值之间呈线性变化,并与 ADC 端的输入电压成正比.</p>    <p>        4. ADC 端的输入电压应当每 100 毫秒读取一次</p>    <p>        5. 当 ADC 端的输入电压端被读入时,控制自由运行定时器周期时间的注册值也应当被更新.</p>    <p>        6. ADC 输入端的电压有效范围应当被控制在 0 到 1 伏之间.</p>    <p>        <strong>第六步:</strong> 你的需求是可测试的么?</p>    <p>        · 首先,自由运行的定时器在这里不需要提及. 因为对它基本上无法进行黑盒测试,它既不是输入也不是输出,而且跟这两者也没有什么联系。</p>    <p>        让我们用“数字输出端变化的频率应控制在每秒 10 次和每秒 1 次之间”来代替自由运行定时器的测试标准。</p>    <p>        · 对于上述的第四条需求,可能需要一些小修改才能作为测试标准。让我们用“ADC 端的输入电压应当保证在每 100 毫秒内至少被读取一次”来加以描述,这样的描述能让我们预期的测试行为显得更加通俗易懂。</p>    <p>        · 需求的第五条也需要一些小修改。我们如何才能检测电压的输出范围是在 0 到 1 伏之间呢? 总不能给个 2 伏的电压,然后看看元器件有没有被烧毁吧?</p>    <p>        那么,说“检验系统在 ADC 端输入电压为 1 到 2 伏之间的时候,工作是否正常”,这样就检验就容易多了。需求描述应当是“正面”的,应当描述设备“应该”的行为,而不是设备“不应该”的行为。否则的话,测试将会无法进行。</p>    <p>        版本0.2</p>    <p>        1. 数字输出端的切换频率应当控制在每秒 10 次到每秒 1 次之间</p>    <p>        2. 数字输出端的切换频率应当在最大值和最小值之间呈线性变化,并与 ADC 端的输入电压成正比</p>    <p>        3. ADC 端的输入电压应当保证在每 100 毫秒内至少被读取一次</p>    <p>        4. 检验当 ADC 端的输入电压范围在 0 到 1 伏之间的时候,系统工作是否正常</p>    <p>        <strong>第七步:</strong>你的需求是否通俗易懂?</p>    <p>        相比于我们原来的描述:“根据弯曲传感器的输出不同频率来控制 LED 闪烁”,我们上面的那些需求描述显得难以阅读和理解。</p>    <p>        我发现,让需求文档变得通俗易懂,最简单办法莫过于,把过于细节的东西抽取出来,然后以条目的形式单独定义。</p>    <p>        版本1</p>    <p>        1. 弯曲传感器应当保证至少在 100 毫秒内读取一次数据(放到注释单独列出)</p>    <p>        2. 切换 LED 的状态,使其与弯曲传感器的读数保持一致</p>    <p>        3. 当弯曲传感器的读数为 1 伏特时,LED 状态切换的次数应当保持在平均一秒十次;当传感器的读数为 0 伏特时,LED 的切换次数应保持在一秒 1 次。</p>    <p>        定义:</p>    <p>        · 弯曲传感器:输入电压位于 ADC 的X端。安全电压范围为 0 到 1 伏特(放到注释单独列出)</p>    <p>        · LED 状态:数字状态由Y端输出</p>    <p>        这样就好多了(尽管还不完美)。这些需求通俗易懂,不涉及到系统内部实现,且易于测试。对于系统行为的限定也仅仅限于需要做什么,点到为止。(例如,对弯曲传感器的采样频率,在实现上也可以更高,只要不产生非预期行为,一切都可以)。</p>    <p>        编写需求就仿佛是在大脑中构建软件的过程。因此要重于实作。</p>    <p>        编译:<a href="/misc/goto?guid=4958185140659301754" target="_blank">伯乐</a>在线 – <a title="如何编写优质的需求文档" href="/misc/goto?guid=4958333720502633478">黄小非</a></p>