我知道 OOP 的“数据隐藏”概念,但在实际开发中,当规范发生变化时,它总是会受到挑战。
例如:
class role
{
std::string name;
int level;
public:
const std::string& get_name() { return name; }
void set_name(const std::string& value) { name = value; }
void set_level(int value) { level = value; }
int get_level() const { return level; }
}
当然,这段代码没有任何问题。但是,我想name
,level
根本没有封装。
我的意见如下:
- 用户可以通过 setter 函数修改数据。
- setter/getter暴露这些数据成员的数据类型。如果这些数据成员必须改变它们的类型,setter/getter 函数成员也必须改变它们的接口。
- 如果我需要对
level
成员进行其他操作,则添加更多操作成员(eqadd_level(int value)
等sub_level(int value)
)功能是唯一的方法。 - 只有一件事是好的。如果
get/set
一定要给它们加上一些判断,这些接口都可以正常工作。
那么,我应该封装什么样的数据成员呢?我无法预测这些数据成员的规模和使用情况。如果我直接暴露它们,对它们的操作将完全简单、清晰、有意义。如果我封装它们,我会为它们做很多操作成员,如果有一天它们的类型被规范改变(int -> class,class -> int),我的操作成员必须改变它们的接口或直接将它们全部杀死(因为我将它们发送到公共区域,一劳永逸!)。