您的位置:首页 > 其它

改善程序与设计的55个具体做法 day7

2016-10-02 16:08 267 查看
条款18:让接口容易被正确使用,不易被误用

这里说的接口是广义上的接口,即包括但不限于函数接口、类接口、template接口等,每一种接口都是客户与你的代码进行交互的手段。

我们对客户的所谓“资质或水平”做出假设或要求,因此面对不同的客户,需要接口在形式上有足够的易用性以及足够的不被误用性。

e.g.

CDate(int year, int month, int day)

该类CDate的构造函数为三个int参数,分别代表年月日。客户在使用的时候很容易用错,比如写错顺序、写的日期不合法等,比较好的做法是对接口的形式有足够的限制,比如

CDate(const CYear& year, const CMonth& month, const CDay& day),

其中对CMonth的使用可以预定义:

class CMonth

{

public:

CMonth(int m);

static CMonth Jan(){ return CMonth(1); }

// ...

static CMonth Nov(){ return CMonth(12); }

}

另,接口中使用的类型要与内置类型一致,即【除非有好理由,否则应该尽量令你的types的行为与内置types一致】。

任何接口如果要求客户必须记得做某些事情,就是有着【不正确使用】的倾向,因为客户可能会忘记做那件事。

e.g.

函数声明



CBase* CreateObj();

std::tr1::shared_ptr<CBase> ptr(CreateObj());



std::tr1::shared_ptr<CBase> CreateObj();

std::tr1::shared_ptr 有一个特别好的性质是:它会自动使用它的【每个指针专属的删除器】,因为消除另一个潜在的客户错误:所谓的【Cross DLL problem】。这个问题发生于【对象在DLL中被new创建,却在另一个DLL内被delete销毁】。

而std::tr1::shared_ptr没有这个问题,它的缺省的删除器是来自【std::tr1::shared_ptr诞生所在的那个DLL】的deleter。

e.g.

std::tr1::shared_ptr<CBase> CreateObj()

{

return std::tr1::shared_ptr<CBase>(new CDerived);

}

返回的指针可以被传递给任何其他DLLs,而无需在意【Cross DLL problem】。

条款19:设计class犹如设计type

即设计类犹如设计类型。

设计一个C++类,就是设计一个新的C++类型。

而一个新的类型的设计,需要回答面对几个规范的设计:

a 新的type的对象应该如何被创建和销毁

b 对象的初始化和对象的赋值有什么样的差别

c 新的type的对象如果被值传递,意味着什么

d 什么是新的type的【合法值】?

e 新的type需要配合某个继承图系吗?

f 新的type需要什么样的转化?

g 什么样的操作符和函数对此新type而言是合理的?

h 什么样的标准函数应该驳回? 即那些被声明为private的

i 谁该取用新type的成员? 即哪些是public protected pricate的

j 什么是新type的【未声明接口】?

k 新type有多么一般化? 即定义了一个type还是一个types族? 如果当真如此就应该使用class template代替这些types

l 你真的需要一个新type吗? 如果只是定义新的派生类,说不定添加几个 non-member 函数 或 template就可以达到目标。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: