1.前言
C++合理的程序代码中,有很多接口:function接口,class接口,template接口....,每一个接口都是与代码互动的手段。要开发一个“容易被正确使用,不容易被误用”的接口,首先需要考虑客户可能做出什么样的错误。这里举个例子:假设为一个表现日期的类class设计构造函数:
Class Date{
public:
Data(int month,int day,int year);
...
};
表面一看,这个接口合情合理可,但使用它的人员容易犯下以下错误:
1.会以错误的次序传递参数
Data d(30,3,1995);//把日期以错误的顺序进行传递
2.传递一个无效的月份或天数
Data d(2,30,1995);
2.设计正确接口的举例
针对上述例子中的问题,我们可以导入简单的外覆类型来区别天数,月份和年份,然后与Data构造函数中使用这些类型:
struct Day{
explict Day(int d):val(d){
}
int val;
};
struct Month{
explict Month(int m):val(m)
{ }
int val;
};
struct Year{
explict Year(int y):val(y)
{ }
int val;
};
class Data{
public(const Month& m,const Day& d,const Year& y);
....
};
Data d(30,3,1995);//错误类型
Data d(Day(30),Month(3),Year(1995));//错误类型
Data d(Month(3),Day(30),Year(1995));//正确类型
该方法表现了明智而审慎地导入新类型对预防“接口被误用”有神奇疗效。
第二种方法是限制其数值的范围:
class Month{
public:
static Month Jan(return Month(1);)//函数,返回有效月份
static Month Feb(return Month(2);)
....
static Month Dec(return Month(12);)
....其他成员函数
private:
explict Month(int m);//阻止生成新的月份
};
Date d(Month::Mar(),day(30),Year(1995));
代码中“以函数替换对象,表现某个特定的月份”相关内容在条款4可以了解,这里不再陈述。
总而言之,言而总之,一个良好的接口需要不断迭代,不断积累工程经验,才能写出经过考验的程序代码。