Sil*_*lex 1 c++ coding-style single-responsibility-principle design-principles
您如何决定何时以及如何违反单一责任原则?
例如,假设我有一个具有以下接口的网络摄像机(为了简单起见,接口保持愚蠢和“错误”):
class Camera
{
string user();
void set_user(string user);
string password();
void set_password(string password);
string url();
void set_url(string url);
image take_snapshot();
bool reboot();
}
Run Code Online (Sandbox Code Playgroud)
这看起来很自然,但看起来 Camera 类有 3 个职责:存储元数据、拍摄快照、重新启动。按照SRP,你可以这样写:
class Camera
{
string user();
void set_user(string user);
string password();
void set_password(string password);
string url();
void set_url(string url);
}
image take_snapshot(camera c);
bool reboot_camera(camera c);
Run Code Online (Sandbox Code Playgroud)
这里的东西在职责方面被整齐地分开,但现在它看起来非常像具有愚蠢结构和函数的 C...这引出了一个问题:为什么我们首先需要 OOP。
您如何在便利性和建议零售价之间取得平衡?
[编辑]
@stjin 的想法被@John Zwinck 显示为答案
我会这样写你的例子:
class Session
{
public:
Session(string url, string user, string password);
};
class Camera
{
public:
Camera(Session);
image take_snapshot();
bool reboot();
};
Run Code Online (Sandbox Code Playgroud)
这里的主要思想是将身份验证和会话/端点定义(可能还有连接)与相机控件分开。Camera 类现在更接近于真实相机的模型:它有一个电源按钮和一个快门按钮之类的东西。相机的虚拟化在其他地方,单独进行。如果有人想为不同的相机建立 USB 会话等,这也使得该做什么变得更加明显。
这里的第二个想法是对象从一开始就以有效状态创建。例如,没有密码就无法配置相机,因此在没有凭据的情况下调用 take_snapshot() 根本不可能。当然,凭据可能无效,但可以通过在构造函数之一中调用的某种方法来检查。
顺便说一句,自由函数没有什么问题。OOP 被高估了,我们都知道这一点,如果免费函数在您的用例中工作,您不应该感到有必要道歉。哑结构可能比无意义的 getter 和 setter 更好——特别是如果您不构建具有 ABI 兼容性要求的可重用库。