条款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的接口,特别是两种类同时使用时,后续维护的开发人员,怕是要掉光了头发

上一篇下一篇

猜你喜欢

热点阅读