.NET的情形驱动设计(Scenario Driven Design)

.NET的情形驱动设计(Scenario Driven Design)

在新概念泛滥的计算机业,甭管有事没事,每天不吆喝几句敏捷(Agile)啦、模型驱动(Model-Driven)啦、Ajax啦就显得特别没面子。但天天听这些日子久了胃会感到不适。所以呢,今天特别表彰一下默默无闻埋头苦干的情形驱动(Scenario Driven)同学,也就是.NET Framework采用的设计方法。

情形驱动和模型驱动都是设计方法,不同的是情形驱动更侧重API的易用性和功能的协调。我们将开发人员分成三类,张飞、关羽、诸葛亮。咋没刘备呢?因为人家刘备是Manager。张飞是很生猛的那种,从来不看文档,兵书有什么好看的,先杀再说。张飞主要开发垂直应用,所用的API范围较小,但务必简单实用,不喜欢读书,喜欢在实践中学习。关羽比较实际,耍大刀之余也要看看兵法,可是文武双全的双学位呢。关羽比较注重功能和开发效率的平衡,又想高效的开发程序,又想能使用各种高级功能。诸葛亮则是先熟读兵书,而后一把羽扇论天下。要设计API给他用,那可必须将每处的实现原理详实道来,要是人家不满意,还得能允许人家用自己的实现替换。以前三位英雄各操各的家伙,而现在,要设计一个类库同时给这三位英雄用,这可不容易啊。

在模型驱动方法下,我们打开一个UML工具,用面对对象的方法设计好对象模型,然后去领工资。在情形驱动的方法下,这是错误的,我们必须反过来,首先要写一些用户将要如何使用这些API的样例,也就是情形(Scenario),然后根据这些用法来设计API。就好比设计汽车时首要考虑的是坐在车里开车的人的感受,而不是马力如何、改装的灵活度如何。这种方法设计的API有可能并不符合面对对象(OOP)原则,但其实,它正是强调不要拘泥于面对对象的方法来设计API。因为面对对象的方法是被发明用来设计易于修改、有弹性的内部实现的,而不是用于外部API设计的。

如何即能让张飞容易上手,又能给诸葛亮足够的功能和灵活度呢。很显然,用同一个API是无法做到的。这里所要用的原则就是“让常用功能简单,高级功能可用(Make the routine tasks easy, and the advanced tasks possible)”。在类方法上,为常用的方法调用提供参数很少的简单重载,同时为高级功能提供有足够参数的重载,如Graphics.DrawString();在类上,将常用类放在主名字空间内,高级功能类放在子名字空间内,如System.Drawing下是常用图形类,而高级矢量功能在System.Drawing.Drawing2D里,高级图像处理在System.Drawing.Imaging里。

张飞不看文档的脾气可不好对付,为了让他能够上手,API必须是自说明的(self-documenting)、可实验的(support experimentation)。自说明意味着新API必须和张飞所熟悉的东西类似,能够望文生义。比如组件的“创建、设置属性、调用方法”使用模式,如果你的API遵从这个模式,张飞肯定知道怎么用。可实验意味着要让老张能在用错的情况下,通过几次猜测和尝试找出正确用法,那么就必须在名字上具备引导性,同时要有指出该如何改正的异常信息。比如有个类PrintQueue提供打印队列的接口,但张飞根本不关心有没有打印队列,他只是要打印文档,只想到要用Printer。

诸葛亮倒是捧起文档,从头看到尾,然后想出一堆我们从没想过的用法,然后写5分钟的代码。要是我们的API哪里绊到人家了,那是咱的错。这时,功能、效率、灵活性、扩展性等经典思想跃然纸上。即使如此,仍不要忘了编程的最古老的原则:小就是美。越少的代码,bug越少。

张飞诸葛亮都搞定了,还怕关羽不成。

抛开严格定义不说,情形驱动和模型驱动里的用例研究(Use Case Study)有相似之处,都是要从使用方法的角度优化,只不过用例只考虑最终的软件用户。

你可能感兴趣的:(.net,api,manager,文档,UML,图像处理)