最近看了一篇博文,文中作者对于访问控制的一个点感觉讲的很对。问题场景如下:
对于某些创建过程较为复杂的类,我们通常借助于工厂方法创建、获取对象,以封装复杂的创建过程。所以在技术实现上需要将待创建类型的构造函数定义为私有,并将工厂类定义为该待创建类型的友元。
class Secret
{
// 将工厂类生命为友元
friend class SecretFactory;
private:
// 私有构造函数
Secret()
{
}
//类内定义的其他私有接口
void secretMethod()
{
}
};
class SecretFactory
{
public:
static Secret* GetSecret(const std::string& type)
{
auto* ptr_secret = new Secret();
// 这是作甚
ptr_secret->secretMethod();
return ptr_secret ;
}
};
这样的实现其实从使用来将没有问题。但如果将访问控制再细化一下,其实是有问题的。对SecretFactory类创建对象而言,Secret类只需要开放给它构造函数的访问权限即可,可一旦生命为友元,所有的Secret的私有接口工厂类均可访问,开放的权限过大了。所以文中作者提出了密钥授权的方式,密钥的创建做了限制,而可访问的接口需要传入密钥对象,从而限定了可访问接口的范围,思路上很是巧妙:
// 引入了中间密钥类型
struct SecretKey
{
// 对密钥的获取做授权控制
friend class SecretFactory;
private:
SecretKey();
};
class Secret
{
public:
// 对象的创建需要带密钥参数
Secret(const SecretKey& key);
void secretMethod()
{
}
};
class SecretFactory
{
public:
static Secret* GetSecret(const std::string& type);
};
当然上述实现也是有代价的,一是引入了新的中间类,二是对Secret类而言多了一个功能实现无关参数。