条款18:让接口容易被正确使用,不易被误用

欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑客户可能做出什么样的错误。

现在假设我们为一个用来表现日期的class设计构造函数:

class Date {
	public:
		Date(int month, int day, int year);
		// 其中 month = 1, 2, ..., 12
		// day = 1, 2, ..., 28, 29, 30, 31
		// year > 0
		...
};
  • 当出现Date d(2022, 2, 12),即时间为2022.2.12时是否正确?
  • 即使每个参数传入的位置正确,那么出现Date d(13, 12, 2022)时,是否又正确呢?

那么此时这个构造函数出现的问题如下:

1.传递参数的次序出现错误
2.可能传入一个无效的月份或天数

很多客户端错误可以因为导入新类型而获得预防。那怎么才能==区分年、月、日呢,而不是都是统一的int类型?我们可以通过导入简单的外覆类型(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(20, 2, 2002); //error,不正确的类型
Date d(Day(30), Month(3), Year(2002)); //error,不正确的类型
Date d(Month(3), Day(30), Year(2002)); //OK

令Day,Month,Year成为成熟且经充分锻炼的classes并封装其内数据,比简单使用上述的structs好(见条款22)。

当正确的类型定位好后,限制它的值便简单多了。例如一年有12个月,那么我们所设置的类型Month就会反应出这个限制。办法之一,我们可以使用enum表示月份,但是enums不具备我们希望拥有的类型安全性,例如enums可被拿来当一个ints使用(见条款2),比较安全的解法是预先定义所有有效的Months:

class Month {
	public:
		static Month Jan() {return Month(1)};
		static Month Feb() {return Month(2)};
		...
		static Month Dec() {return Month(12)};
		...
	private:
		explicit Month(int m); //阻止生成新的月份,这是月份专属数据	
};
Date d(Month::Mar(), Day(3), Year(2002));

如果我们对以函数替换对象,表现某个特定月份感到奇怪,或是因为忘记non-local static对象的初始化次序有可能出问题,那我们可以阅读条款4

预防客户错误的另一个办法是,限制类型内什么事可做,什么事不能做。常见的是加上const限制符,可阅读条款3

——————————————————————————————————————

接下来另一个准则就是“让types容易被正确使用,不容易被误用”的表现形式:除非有好的理由,否则应该尽量令我们的types的行为与内置types一致。因为内置类型大家都很熟悉,我们建立的类型行为应该与其保持一致,也方便大家的使用。

STL容器的接口十分一致,这使得它们非常容易被使用。
任何接口如果要求客户必须记得做某些事情,就是有着“不正确使用的倾向,因为客户很可能忘记做这件事情,如条款13中展示的。

总结

好的接口很容易被正确使用,不容易被误用;
“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容;
“阻止误用”的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任;
tr1::sharel_ptr支持定制型删除器(custom deleter)。这可预防DLL问题,可被用来自动解除互斥锁(mutexes,见条款14)等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑字。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值