您的位置:首页 > 其它

最重要的设计指导原则

2007-10-14 16:36 169 查看
作者:Scott Meyers

“设计”这项工作包括很多东西,不过当然最重要的方面之一是接口规范。接口决定了一个组件的哪些方面对哪些人是可以查阅的;它们因此决定了封装。 接口指名什么功能(数据,属性,方法等)对客户来说是可用的。接口反映了一个系统是怎样被分解成它所定制的组件的。

接口遍地都是。它们是GUI和API中的"I",但是它们比那个更加无孔不入。类和结构都有接口;函数和方法有接口;模版和名称空间有接口;子系统和模块有接口;库和应用程序有接口。不论你在软件系统开发中扮演什么角色,都会或多或少设计一些接口的设计,所以,了解一些启发式,它们暗示什么时候你做的不错,什么时候你做的糟糕,这样对你是有帮助的。随着时间的推移,我总结了一些最重要的通用接口设计指导原则如下:

使接口容易被正确地使用并且难于被错误地使用。

这条准则导致一个结论就是有些开发人员觉得不安。

接口设计者必须负责

让我们做一个合理的假设,你的客户-使用你的接口的人-正试图完成一个好的项目。他们聪明,很热情,并且有责任心。他们愿意阅读一些有助于理解正在使用的系统的文档。他们想让一切都正确的工作。

既然如此,如果他们使用你的接口时犯了一个错误,那这就是你的错误。我们假设他们尽全力而为-他们想要获得成功。如果他们失败了,原因在于你。因此,如果某个人错误地使用你的接口,不管他们是很努力地去做(很少这样)还是你的接口允许他们去做一些简单但不正确(经常是这样)的事情。这就像把鞋穿在并不合适的脚上:这意味着接口使用错误的责任在于接口设计者,而不是接口使用者。

在一个完美的世界中,坚持这条原则将保证程序正确地执行。在这样的世界中,做一些不正确的事情的程序将不会被编译,而通过编译的程序几乎做的都是正确的事情。在人机接口层,错误的命令将被拒绝,而被接受的命令则几乎当然执行做正确的事情,但是在大多数软件系统中使用的接口只要稍作努力就能得倒显著的改善。

改善你的接口

考虑一个表示日期的(C++)类,它的构造函数可能像这样声明:

class Date {
public:
explicit Date(int month, int day, int year);
};

这是一个接口容易被错误使用的经典例子。因为3个参数都是一个类型的,调用者很容易将顺序搞混。按照作者的意思我们应该这样做(不过这似乎有点麻烦,没办法,老美就是牛,听他的吧):

#include <iostream>

struct Day {                            // thin wrapper for Day
explicit Day(int day): d(day) {}
int d;
};

struct Year {                           // thin wrapper for Year
explicit Year(int year): y(year) {}
int y;
};

class Month {
public:
static const Month Jan;               // a fixed set of immutable
static const Month Feb;               // Month objects
//...
static const Month Dec;

int number() const { return m; }

private:
explicit Month(int month): m(month) {}
int m;
};

const Month Month::Jan(1);
const Month Month::Feb(2);
//...
const Month Month::Dec(12);

class Date {
public:
explicit Date(Month m, Day d, Year y);       // revised (safer,
explicit Date(Year y, Month m, Day d);       // more flexible)
explicit Date(Day d, Month m, Year y)        // interface
: dNum(d.d), mNum(m.number()), yNum(y.y)
{
std::cout << "D.M.Y = "
<< dNum << '.' << mNum << '.' << yNum << '/n';
}

private:
int dNum, mNum, yNum;
};

int main()
{
Date today(Day(10), Month::Jan, Year(2005));
}
接下来干什么?不翻译了,发现这翻译文章还真是挺麻烦的,以后就自己看看就行了,也没那么多的时间啊。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: