JoelOnSoftware

Joel on Software

Painless Functional Specifications - Part 2: What's a Spec?

无痛软件规范-第二部分:什么是规范

by Joel Spolsky Tuesday, October 03, 2000

(Have you already read part one? If not, that's here .)

(你读过第一部分么?如果没有,请戳这里)。

This series of articles is about functional specifications, not technicalspecifications. People get these mixed up. I don't know if there's any standard terminology, but here's what I mean when I use these terms.

这系列的文章是关于功能规范的,不是技术规范。人们会把这些混淆起来。我不知道是不是有什么标准的哦术语,但我用这些称谓的时候意思是。

  1. A functional specification describes how a product will work entirely from the user's perspective. It doesn't care how the thing is implemented. It talks about features. It specifies screens, menus, dialogs, and so on.

  2. A technical specification describes the internal implementation of the program. It talks about data structures, relational database models, choice of programming languages and tools, algorithms, etc.

  1. 功能规范完全从用户角度描述了产品如何工作。它并不关心具体实现是什么样子的。它讨论的是功能,它会制定屏幕,对话框,之类的。

  2. 技术规范描述的是程序的内部实现。讨论了数据结构,关系数据库模型,编程语言的选择以及工具,算法之类的。

When you design a product, inside and out, the most important thing is to nail down the user experience. What are the screens, how do they work, what do they do. Later, you worry about how to get from here to there. There's no use arguing about what programming language to use before you've decided what your product is going to do. In this series, I'm only talking about functional specifications.

当你有内而外的设计一个产品的时候,最重要的事情是敲定用户体验。屏幕是什么样子的,他们怎么工作,他们做什么。然后你就开始操心怎么从这儿过去那儿。在决定你的产品做什么之前无需讨论使用什么编程语言。在这个系列里,我只讨论功能规范。

I've written a short sample spec which should give you an idea for what a good functional specification looks like. Before we go further, pleaseread the sample spec.

我写了个简单的示例规范,以便给你们一个直观的感受好的规范是长什么样的。在我们继续之前,请看一下样例规范。

Did you read it?

你读了么?

No you didn't. Go read it now and then come back, so we can talk more about what a good spec should and shouldn't have in it. I'll wait here for you. Thanks.

不,你肯定没读 。 现在马上去读一下然后再回来,然后我们就可以更多的讨论关于一个好规范应该有什么,不应该有什么。我会在这儿等你的。谢谢。

(waiting patiently...)

(耐心地等待中。。。)。

Ah, good. You're back.

很好,你回来了。

Here are some of the things I put in every spec.

下面是些我会在每个规范里都放的东西。

A disclaimer. Pure self defense. If you put a paragraph saying something like "This spec is not complete", people won't come into your office to bite your head off. As time goes on, when the spec starts to be complete, you can change it to say "this spec is complete, to the best of my knowledge, but if I forgot something, please tell me." Which reminds me, every spec needs:

免责声明。 纯粹是出于自我保护。如果你写上一段类似“这个规范还没有完成”之类的话,人们就不会来你的办公室把你的头咬下来,随着时间流逝,当规范要完成的时候,你可以改成“据我所知,该规范已经完成但是如果我忘记了什么东西,请告诉我。”这总是提醒我,每个规范需要:

An author. One author. Some companies think that the spec should be written by a team. If you've ever tried group writing, you know that there is no worse torture. Leave the group writing to the management consulting firms with armies of newly minted Harvard-educated graduates who need to do a ton of busywork so that they can justify their huge fees. Your specs should be owned and written by one person. If you have a big product, split it up into areas and give each area to a different person to spec separately. Other companies think that it's egotistic or not "good teamwork" for a person to "take credit" for a spec by putting their name on it. Nonsense. People should takeresponsibility and ownership of the things that they specify. If something's wrong with the spec, there should be a designated spec owner, with their name printed right there on the spec, who is responsible for fixing it.

作者。一个作者。有些公司认为规范应该由团队编写。如果你尝试过集体协作,你就知道没有比这更糟糕的折磨了。还是把集体协作留给那种管理顾问公司的新晋哈佛毕业生吧,他们需要巨量的繁忙工作以平衡他们的收费。你的规范应该由一个人编写归一个人所有。如果你有大产品,把它分成不同的方面,然后把每个方面交给不同的人分别来编写规范。有些公司认为让个人在规范上署名而“获益”有点唯我独尊的意思而且不是好的团队合作。一派胡言。人们会因为他们规范事物的所有权而承担责任。如果规范出了差错,就应该有一个制定的责任人,他们的名字就印在规范上,他将负责修正该错误。

Scenarios. When you're designing a product, you need to have some real live scenarios in mind for how people are going to use it. Otherwise you end up designing a product that doesn't correspond to any real-world usage (like the Cue?Cat). Pick your product's audiences and imagine a fictitious, totally imaginary but totally stereotypical user from each audience who uses the product in a totally typical way.Chapter 9 of my UI design book (available online for free) talks about creating fictional users and scenarios. This is where you put them. The more vivid and realistic the scenario, the better a job you will do designing a product for your real or imagined users, which is why I tend to put in lots of made-up details.

场景。当你在设计产品的时候,你脑海里应该有一些现实生活中的场景描述人们如何使用它。否则你最终做出来的就是无法对应到现实世界使用场景的的产品(如CueCat)。挑选你产品的目标受众群体,从受众群体中想象一个虚构的,完全想象中的但是又栩栩如生的用户,该用户以一种完全特定的方法是用该产品。我的UI设计书的第9章(在线免费版)讨论了创建虚构的用户和场景。这儿就是你用上他们的地方。场景越是生动现实,你的对真实或虚拟用户的产品就设计的越好,这也是我为什么倾向于放入大量编造的细节。

Nongoals. When you're building a product with a team, everybody tends to have their favorite, real or imagined pet features that they just can't live without. If you do them all, it will take infinite time and cost too much money. You have to start culling features right away, and the best way to do this is with a "nongoals" section of the spec. Things we are just not going to do. A nongoal might be a feature you won't have ("no telepathic user interface!") or it might be something more general ("We don't care about performance in this release. The product can be slow, as long as it works. If we have time in version 2, we'll optimize the slow bits.") These nongoals are likely to cause some debate, but it's important to get it out in the open as soon as possible. "Not gonna do it!" as George Sr. puts it.

非目标。 当你在和团队创建产品的时候,每个人都会倾向于有自己最喜欢的,真的或假想的宠物功能,离开这些功能他们简直无法生活。如果你全部实现这些功能,要花无穷多的时间和套多的金钱。你得马上开始裁剪功能,最好的办法就是在规范中设立“非目标”部分。也就是我们不打算去做的东西。一个非目标可能是你没有的功能(“没有心灵感应的用户界面!”)或者是一些更通用的(“我们在这版发布里不关心性能,产品能很慢,但是只要它能工作。如果我们在第二版的时候有时间,我们会优化慢的部分。”)这些非目标很有可能会引起一些争论,但是尽快打开这些争论很重要。“不做”就像George爵士说的那样。

An Overview. This is like the table of contents for your spec. It might be a simple flowchart, or it might be an extensive architectural discussion. Everybody will read this to get the big picture, then the details will make more sense.

概述。这就像是你规范的目录。可能是个简单的流程图,或是一个详述的架构讨论。所有人都会阅读这段来获得高层次的理解,然后细节就显得更加合理。

Details, details, details. Finally you go into the details. Most people will skim this until they need to know a particular detail. When you're designing a web-type service, a good way to do this is to give every possible screen a canonical name, and provide a chapter describing each one in utter and mind-numbing detail.

Details are the most important thing in a functional spec. You'll notice in the sample spec how I go into outrageous detail talking about all the error cases for the login page. What if the email address isn't valid? What if the password is wrong? All of these cases correspond to real code that's going to be written, but, more importantly, these cases correspond to decisions that somebody is going to have to make. Somebody has to decide what the policy is going to be for a forgotten password. If you don't decide, you can't write the code. The spec needs to document the decision.

细节,细节,细节。 最后终于到了细节。大多数人会跳过这段直到他们需要某个特定的细节。当你在设计网页类型服务的时候,一个好的方法是给每个屏幕一个典型的名字,然后用一章来巨细无遗地描述每个细节。

细节是功能规范里最重要的东西。你注意到了我在示例规范里如何事无巨细的讨论登录页面的所有错误情况。如果电子邮件地址错误怎么办?如果密码错误怎么办?所有这些情况都会对应最终要编写的代码,但是,更重要的是这些情况对应了某人要做的决定。必须有人决定密码忘了的策略是怎样的。如果你不决定,你无法写代码。规范必须几轮这些决定。

Open Issues. It's OK for the first version of the spec to leave open issues. When I write a first draft, I always have lots of open issues, but I flag them (using a special style so I can search for them) and, if appropriate, discuss the alternatives. By the time the programmers start work, all of these need to be stomped out. (You might think it's OK to just let the programmers start on all the easy stuff, and you'll solve the open issues later. Bad idea. You will have enough problems resolving the new issues that come up when the programmers try to implement the code, without having old open issues around that you knew about in advance and could have solved then. Besides, the way you resolve anything non-trivial may have a major impact on how the code should be written.)

开放问题。规范的第一版本遗留一些开放问题是可以的。当我第一次起草规范的时候,我总是有一堆开放问题,但是我会标记他们(用一种特殊的样式,以便我能搜索到它们) 而且,如果合适的话,讨论替代策略。 到程序员开始工作的时候,所有的这些问题都必须被清理干净。(你也许认为可以让程序员先开始一些简单的东西,稍后你会解决这些开放问题。坏主意。如果没有事先知道这些旧的开放问题并解决他们,在程序员开始编码的时候,你解决新问题就已经有足够多的问题了。另外,你解决的任何问题都有可能对如何编写代码有着巨大影响。

Side notes. While you're writing a spec, remember your various audiences: programmers, testers, marketing, tech writers, etc. As you write the spec you may think of useful factoids that will be helpful to just one of those groups. For example, I flag messages to the programmer, which usually describe some technical implementation detail, as "Technical Notes". Marketing people ignore those. Programmers devour them. My specs are often chock full of "Testing Notes," "Marketing Notes," and "Documentation Notes."

笔记。当你在编写规范的时候,记住你的各种受众:程序员,测试,销售,技术作家,等等。在你编写规范的时候你可能会想到一些对其中一个群体有用的改编。例如,我会标出对程序员有用的信息,这些信息通常会描述一些技术实现细节,标记为“技术笔记”。 销售人员会忽略那些。程序员会消化他们。 我的规范通常标满了“测试笔记”,“销售笔记”,以及“文档笔记”。

Specs Need To Stay Alive. Some programming teams adopt a "waterfall" mentality: we will design the program all at once, write a spec, print it, and throw it over the wall at the programmers and go home. All I have to say is: "Ha ha ha ha ha ha ha ha!"

This approach is why specs have such a bad reputation. A lot of people have said to me, "specs are useless, because nobody follows them, they're always out of date, and they never reflect the product."

保持更新的规范。一些编程团队会采用一种“瀑布”心理开发模型:我们只设计程序一次,编写一个规范,打印出来,然后扔给墙那边的程序员然后回家,对此我只想说“哈哈哈哈哈哈哈哈哈哈!”。

这种方式也是为什么规范有坏名声的重要原因。很多人都对我说,“规范毫无用处,因为没人会遵守它们,它们总是过时的,它们从来不反应产品”。

Excuse me. Maybe your specs are out of date and don't reflect the product. My specs are updated frequently. The updating continues as the product is developed and new decisions are made. The spec always reflects our best collective understanding of how the product is going to work. The spec is only frozen when the product is code complete (that is, when all functionality is complete, but there's still testing and debugging work.)

对不起。也许你的规范过时而且不反应产品。我的规范可是经常更新,随着产品的开发和新决定的产生规范不断被更新。规范总是最佳地反映了我们群体对产品如何工作的理解。规范只有在产品编码完成的时候才会被冻结(也就是,所有的功能都完成了,但是还是有测试和调试需要做)。

To make people's life easier, I don't rerelease the spec daily. I usually keep an up to date version on a server somewhere where the team can use it as a reference. On occasional milestones, I print a copy of the spec with revision marks so that people don't have to reread the whole thing -- they can scan the revision marks to see what changes have been made.

为了让大家生活更轻松点儿,我不会每天都发布规范。我通常会在服务器的某个地方维护规范的最新版本以便团队能引用它。在偶尔的里程碑上,我会打印出标记了修改的规范版本以便与大家不要重新阅读整个规范 -- 童年、他们扫搜寻改标记来寻找发生了什么样的改变。

Who should write the specs? Read all about it in Part 3.

谁应该编写规范? 在第三部分里了解。