条款18:让接口容易被正确使用,不易被误用
Make interfaces easy to use correctly and hard to use incorrectly
欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑客户可能做出什么样的错误。
class Date{
public:
Date(int month, int day, int year);
}
乍见之下这个接口很合理,但它使客户很容易犯下至少两个错误。
// 以错误次序传递参数
Date d(30, 3, 1995);
// 传递一个无效的月份或天数
Date d(2, 30, 1995);
许多客户端错误可以因为导入新类型而获得预防(类型系统)。让我们导入简单的外覆类型(wrapper types)来区别天数、月份和年份,然后在Date构造函数中使用这些类型:
struct Day{
explicit Day(int d) : val(d) {}
int val;
}
struct Month{
explicit Month(int m) : val(m) {}
int val;
}
struct Year{
explicit Year(int y) : val(y) {}
int val;
}
class Date{
public:
Date(const Month& m, const Day& d, const Year& y);
}
Date d(30, 3, 1995); //错误!不正确的类型(必须显式调用)
Date d(Day(30), Month(3), Year(1995)); //错误!不正确的类型
Date d(Month(3), Day(30), Year(1995)); //正确
令Day, Month和Year成为成熟且充分锻炼的classes并封装器数据,比简单使用structs好。但即使当前也足够示范:明智而审慎地导入新类型对预防“接口被误用”有神奇疗效。
---