Premature commitment 
wiki上的解释为:
Are there strong constraints on the order with which tasks must be accomplished?
Are there decisions that must be made before all the necessary information is available?
Can those decisions be reversed or corrected later?
微软将其改为如下说法:
To what extend does a developer have to make decisions before all the needed information is available?
开发者在使用API完成任务之前,有时不得不提前思考一些问题,比如使用API的哪些接口完成任务,它们之间有何联系,调用顺序是怎样的等等。那么开发者的思考代价有多大呢?
是在写代码之前就能轻松得出结论,还是写了一些验证性的代码之后才可以,还是整个代码都写得差不多了才发现当初思考的方式并不正确,需要重头再来?
如果开发者在使用API过程中经常遇到最后一种情况,那么就认为该API含有过多的不合理的约束(我对premature commitment的理解)。
比如API约束了调用顺序,约束了接口之间的某种调用关系,并且这些约束是一般开发者不能提前思考清楚的。
比如地图API里可以给标注添加一个标题,当鼠标移到这个标注上时,就会显示这个标题,实际上,这是给标注的DOM容器元素增加了title属性。开发者在使用过程中可能会使用下面的写法:var er = new BMap.Marker(map.getCenter());  // 创建一个标注对象,并给定一个坐标点
er.setTitle("百度大厦");            // 标注创建完了,给它加个标题
map.addOverlay(er);             // 好了,添加到地图上当我们把鼠标移到标注上,“百度大厦”四个字并没有显示,哪出问题了?API文档那个上明明写了这个接口的作用呀?实际上,只有下面的写法才能实现:var er = new BMap.Marker(map.getCenter());  // 创建一个标注对象,并给定一个坐标点
map.addOverlay(er);             // 先添加到地图上
er.setTitle("百度大厦");            // 再给它加个标题其中原因很简单,由于标题是添加在DOM元素上的,那么在调用addOverlay方法之前,DOM元素并没有创建出来,setTitle发现DOM元素不存在就直接return了,也没有把这个title存起来,那么后来再添加到地图上也就看不到标题了。
这里,API就存在一个调用顺序上的约定,使用者可能在经历了失败时候才会知道这个约定,好在调整起来并不费力,至少代码没有白写。
一个好的API应该尽量减少这种不合理的约定。另外,如果想减少开发者的思考代价,一份结构清晰的文档是必不可少的。
Penetrability 
How does the API facilitate exploration, analysis, and understanding of its components, and how does a targeted developer go about retrieving what is needed.
这个维度是指开发者需要理解API的底层实现细节到一个什么程度以及对这些细节的理解程度,也就是说API的透明程度(penetrability)如何。
比如,一个封装了很多底层接口的API需要使用者理解这些底层实现细节,否则API就不能正常工作。
API Elaboration 
To what extend must th eAPI be adapted to meet th eneeds of a targeted developer?
开发者使用API来完成任务,其中一些任务仅仅通过调用几个API的现有接口就能完成,另一些任务可能需要继承API的一个类,并重载一些方法来完成,还有一些任务可能需要开发者自己编写接口的具体实现来完成。
这个维度描述了API暴露出来的扩展性,即API有哪些接口直接使用的,有哪些需要开发者自己继承扩展的,有哪些是开发者自行创建的。
当用户使用地图API时,有些功能可能是API中没有提供的,这时候就需要开发者自己写一些模块来处理(就像线上的百度地图)。
对于一些简单的任务,API要尽可能提供现成的接口供开发者使用。另有一部分开发者对接口的灵活性要求更高,希望通过扩展现有的API来实现自己的功能。API最好能同时满足这些不同的需求
API Viscosity 
What are the barriers to change inherent in the API, and how much effort does a targeted developer need to expend to make a change.
这个维度描述了改变已写代码的容易程度,可简称为易改性。当用户发现自己代码运行错误或者发现选用的方法不对,修改起来是否足够容易呢?
这里的修改通常是指那些比较小的修改,但是一个小的修改可能会产生“多米诺”效应:一个地方的代码变动会导致另一个地方的代码需要调整,接着又会导致另一处……这就要求API在设计过程中模块划分要合理,同时处理好它们之间的耦合程度。
修改代码是不可避免的,这和我们思考行为有关系,我们会在大脑中勾画一个方案,并不断的进行调整。那些高手可直接在大脑中就想出一些中等复杂问题的解,一般人也能在大脑中直接处理一些简单的问题,而那些大型而又复杂的问题,估计没有人能够直接通过大脑就能想出解决办法。
当问题越大越复杂,API的易改性的作用就越明显。
Consistency 
Once part of an API is learned, how much of the rest of it can be inferred?
一致性也是API可用性需要考虑的,我们经常会注意产品界面是否具有一致性,比如同一个网站的每个网页的菜单样式是否一样,图标风格是否一样,字体类型、颜色、大小是否一样等等。
Green在他的文章中也将这个因素描述为API的可猜测性,也就是说使用者了解了部分API的使用方法后,是否能很顺利的猜出API其他部分的使用方法。
在地图API中,本地搜索接口的使用方式为:var myLoc = new BMap.LocalSearch(map);
myLoc.search("百度大厦");当用户了解它的使用方法后,可以很轻松的使用公交导航、驾车导航等接口。// 公交导航
var myTransit = new BMap.TransitRoute(map);
myTransit.search("百度大厦", "中关村");// 驾车导航
var myDrv = new BMap.DrivingRoute(map);
myDrv.search("百度大厦", "中关村");// 步行导航
var myWalk = new BMap.WalkingRoute(map);
myWalk.search("百度大厦", "西二旗");从上面可以看出,这些接口使用方法都非常类似,因此具有很高的一致性。
地图API中也存在一些一致性较差的问题,许多接口都要求提供offset属性,比如控件的位置偏移、标注、信息窗口的位置偏移。
当给控件添加偏移值时,采用的是下面的方法:var ctrl = new BMap.ScaleControl({offsetX: 10, offsetY: 10});我们通过offsetX和offsetY两个属性来描述这个偏移值,然而当我们获取控件偏移位置时,接口为:var offset = ctrl.getOffset();
alert(offset.x + ", " + offset.y);得到的偏移值使用了一个对象描述。那标注呢?var mkr = new BMap.Marker(map.getCenter(), {offset: [3, 4]});天哪,标注又是使用数组进行传递的。
在地图API中,我们使用了三种不同的方式来描述偏移值,这无疑增加了开发者的使用难度,也更容易出错。这个问题我们在API的后续升级中进行解决。
Role Expressiveness 
How apparent is the relationship between each component and the program as a whole?
这个维度包含两方面的意思,那就是:说你所想,想你所说(原文是:say what you mean and mean what you say)。
一段容易阅读的代码(mean what you say)不一定很容易写出来(say what you mean)。所以在考虑这个维度时,不仅仅要考虑代码是否容易阅读,也应该考虑编写过程是否也同样容易。
在地图API初期,创建一个简单的导航控件的代码是这样的:var navCtrl = new BMap.NavigationControl({type: 1});
map.addControl(navCtrl);这段代码并不能完全表达出它的含义(cannot express its role),如果不借助文档,你几乎不可能知道type等于1意味着什么,最多你可能知道这里在指定控件的类型,但是1具体表示什么类型就不得而知了。
所以,升级之后的API做了如下调整:var navCtrl = new BMap.NavigationControl({type: BMAP_NAVIGATION_CONTROL_SMALL});
map.addControl(navCtrl);现在我们使用常量BMAP_NAVIGATION_CONTROL_SMALL来描述控件的类型,即使不看文档,也能知道这是个小型的导航控件。
Domain Correspondence 
How clearly do the API components map to the domain? Are there any special tricks?
这个维度描述了API所提供的类、方法与那些概念上的对象是否吻合,也就是接口和问题领域的相关程度如何。
如果代码与问题领域相关程度高,那么开发者编写的过程就会轻松许多,反之,开发者就需要多花费一些时间和精力才能完成他们的工作。
举一个最简单的例子,我们打算遍历数组的每一个元素,并alert出来,那么我们可以用循环来实现:var a = [1, 2, 3];
for (var i = 0; i < a.length; i ++){
  alert(a[i]);
}而另一种可能的方法是:var a = [1, 2, 3];
a.each(function(x){alert(x)});或者干脆写成:var a = [1, 2, 3];
a.each(alert);程序员的目的是遍历数组,然而第一种方法出现的for循环结构以及相关的循环变量定义、数组长度判断等内容实际上是编程语言实现“遍历”功能所附加的一些概念。
显然这样的代码与问题领域的相关程度也比较低,而最后一种写法对于母语是英语的人来说简直就像说话一样简单。
参考资料 
Cognitive dimensions of notations, (http://en.wikipedia.org/wiki/Cognitive_dimensions_of_notations)
Steven Clarke & Curtis Becker, Using the Cognitive Dimensions Framework to evaluate the usability of a class library, 2003. 
Green, T. R. G. & Petre, M. (1996) Usability analysis of visual programming environments: a ‘cognitive dimensions’ framework. J. Visual Languages and Computing, 7, 131-174. 
Steven Clarke & Visual Studio Usability Group, Microsoft Corporation, Describing and evaluating API usability at Microsoft. 

解决方案 »

  1.   

    一致性也是API可用性需要考虑的,我们经常会注意产品界面是否具有一致性,比如同一个网站的每个网页的菜单样式是否一样,图标风格是否一样,字体类型、颜色、大小是否一样等等。
    界面设计
      

  2.   

    How apparent is the relationship between each component and the program as a whole
      

  3.   

    Premature commitment 
    wiki上的解释为:
    Are there strong co