我们说我们正在为其他程序员开发API。我们的API有一个Date对象供他们使用,我们希望将月,日和年的值限制为有效值,例如当月的1-12,当天的1-31和1900 2014年度。为此,我们创建单独的Month,Day和Year对象,所有这些对象都传递给Date的构造函数,我们称之为:
Date date(Month::Jan(), Day(1), Year(1980));
为了确保Month只能是1-12,我们可以为每个月创建单独的函数,每个函数返回一个与该月对应的月份对象,并确保没有人可以创建错误的月份值,我们将Month的构造函数设为私有:
class Month {
public:
static Month Jan () { return Month(1);}
static Month Feb () { return Month(2);}
static Month Mar () { return Month(3);}
static Month Apr () { return Month(4);}
static Month May () { return Month(5);}
static Month Jun () { return Month(6);}
static Month Jul () { return Month(7);}
static Month Aug () { return Month(8);}
static Month Sep () { return Month(9);}
static Month Oct () { return Month(10);}
static Month Nov () { return Month(11);}
static Month Dec () { return Month(12);}
private:
Month (int n) : monthNum (n) {}
int monthNum;
};
但是,对于日和年,我们不能只包含Year::1997()
等数字的函数名称,我们希望这种格式对客户端开发人员来说很直观,因此Year::year1997()
等语法是出。另外,我们不想为每一年都手动编写功能。让我们说几年回到足够远的地方,这将是一个问题,例如回到1900年。因此,我们会坚持使用Day(1)
或Year(1997)
格式。
鉴于此,确保构建的日和年只能返回我们想要的值范围的好方法是什么?一种方法是在输入无效值时抛出异常:
class Day {
public:
Day (int d) : dayNum(d) {
if(d <= 0 || d >= 31) {
throw "Invalid day";
}
}
private:
int dayNum;
};
但是这会在运行时产生错误,而不是在编译期间产生错误,并且我们正在为开发人员构建这个错误,所以我们希望他们在他们做错事情时尽快知道,例如作为无效的一天或一年(例如第32天或第3000年)。什么是确保客户只能创建具有有效值的Day或Year对象的有效方法,而无需等到程序执行才能通知他们?