Make interfaces easy to use correctly and hard to use incorrectly
接口,顾名思义,供别人使用的一些方法。function 接口,class接口,template 接口。。。。每一种接口都是客户与你的代码互动的手段。但是你所设计的接口的好坏,直接导致了被调用产生错误的几率。所以:“容易被正确使用,不容易被误用”的接口的重要性。 下面以书中表现日期的class 设计。
class myDate
{
public :
myDate(int month,int day, int year);
//...
};
当调用这个日期类的时候,我们不知道三个参数各个代表了什么,比如
myDate md(14,3,2011);
这样的初始化,是完全错误的,因为没有14个月份。
所以我们要想办法杜绝这种现象的出现。
第一种方法就是导入简单的 wrapper types来区别天数,月份,和年。如
struct myDay
{
explicit myDay(int d)
:val(d){}
int val;
};
struct myMonth
{
explicit myMonth(int d)
:val(d){}
int val;
};
struct myYear
{
explicit myYear(int d)
:val(d){}
int val;
};
此时,我们的Date类就为
class myDate
{
public :
myDate(const myMonth & m,const myDay &d,const myYear & y);
//...
};
这个时候,当我们初始化时,
myDate md(14,3,2011); 会报错
myDate myD(myMonth(3),myDay(3),myYear(2011)); 正确
但是,因为一年只有十二个有效月份,所以,我们就预先定义好所有的月份。
struct myMonth
{
public:
static myMonth jan(){return myMonth(1);}
static myMonth Feb(){return myMonth(2);}
static myMonth mar(){return myMonth(3);}
//.....
static myMonth Oct(){return myMonth(10);}
....
};
当我们初始化时:
myDate myD(myMonth::Feb(),myDay(3),myYear(2011));
其他天数,和年份都可以这样。
预防客户出错调用就是利用限制类型表示什么可以做,什么不可以做。常见的就是const修饰。
避免无端与内置类型不兼容,真正的理由是为了提供行为一致的届接口。不一致性很容易导致接口的错误调用。
stl 容器届口十分的一致。每个容器都有名为size的成员函数,返回容器内有多少对象。但是java 就有length和size
很多方法。我之前做过一年的 java 深有体会。
在条款13中,我们学习到了factory函数,缠身一个对象的指针,方便我们对对象的管理,如
Investment* createInvestment();
在资源管理的那个章节,我们知道管理资源的重要性,我们要对指针删除,会出现
忘记删除,删除多次。
所以,我们使用了智能指针。让指针管理。std::tr1::shared_ptr<Investment.createInvestment();
shared_ptr的一个构造函数提供了技术功能,有如下代码:
std::tr1::shared_ptr<Investment> creatInvestment()
{
std::tr1::shared_ptr<Investment> retVal(static_cast<Investment*>(0),getRidOfInvestment);
retVal=...;
retrun retVal;
}
static_cast<Investment* >(0),强制转换为指针类型。
请记住:
■ 好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质.
■ "促进正确使用"的办法包括接口的一致性,以及与内置类型的行为兼容.
■ "阻止误用"的办法包括建立新类型、限制类型上的操作、束缚对象值以及消除客户的资源管理责任.
■ tr1::shared_ptr支持定制型删除器.这可防范DLL问题,可被用来自动解除互斥锁等等.
■ 好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质.
■ "促进正确使用"的办法包括接口的一致性,以及与内置类型的行为兼容.
■ "阻止误用"的办法包括建立新类型、限制类型上的操作、束缚对象值以及消除客户的资源管理责任.
■ tr1::shared_ptr支持定制型删除器.这可防范DLL问题,可被用来自动解除互斥锁等等.