条款18:让接口更容易被使用,不容易被误用
2019-12-10 本文已影响0人
MR_Model
条款18:让接口更容易被使用,不容易被误用
1、使用外覆类型,预防客户参数写入错误
Date18(int month, int day, int year);
如上函数声明,我们可以通过名称的命名,来告知每个用户的变量含义。但,如以下:
Date18 date(12, 8, 2019);
Date18 date(8, 12, 2019);
我们无法从函数的使用上进行任何的区分:
Date18 date(13, 8, 2019);
这种状况的出现,可能是由于:
1、客户端打算写入 8月13日,但是变量顺序反了
2、客户端本打算写入 12月8日,但输入错误
这种状况我们无法知晓,必须通过函数的定义,去获取含义。
fix:
Date_fix(MyMonth month, MyDay day, MyYear year);
使用另外的类型 MyMonth、MyDay、MyYear来告知用户每个位置的变量含义,同时可以在每个外覆类中限制值的范围,防止用户出现输入错误的情况。如下:
class MyMonth
{
public:
MyMonth Jan()
{
return MyMonth(1);
}
...
private:
MyMonth(int month):
m_month(month)
{
}
int m_month;
}
2、使用const、explicit、shared_ptr来限制接口
const:
a*b = c
以上代码是任何人都不想遇见的,如果在 operator*前添加限制符 const 可以防止以上这种情况的出现。
explicit:
防止类构造函数的隐式自动转换
shared_ptr:
class Investment
{
public:
Investment()
{
std::cout << __FUNCTION__ << std::endl;
}
~Investment()
{
std::cout << __FUNCTION__ << std::endl;
}
};
class Factory
{
public:
std::shared_ptr<Investment> CreateSharedPointer();
Investment* CreatePointer();
};
std::shared_ptr<Investment> Factory::CreateSharedPointer()
{
std::shared_ptr<Investment> res(new Investment);
return res;
}
Investment * Factory::CreatePointer()
{
return new Investment;
}
在用户不知道delete申请内存时,预测一下,上面两个函数调用后回出现什么情况呢。
3、保持接口的一致性,且与内置类型的行为兼容
MyList
{
bool isNotEmpty();
}
std::list
{
bool empty();
}
虽然命名清晰,含义容易理解,不过应该没有人想要使用MyList的接口,特别是两种类同时使用时,后续维护的开发人员,怕是要掉光了头发