您如何决定何时以及如何违反single responsability principle?
例如,假设我有一个带有以下界面的网络摄像头(为简单起见,界面保持愚蠢和“错误”):
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();
}
这看起来很自然,但看起来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);
这里的东西在责任性方面整齐地分开,但现在它看起来非常像具有哑结构和功能的C ......这就引出了为什么我们首先需要OOP的问题。
如何在便利性和SRP之间取得平衡?
[编辑]
@stjin想法被@John Zwinck作为答案显示
答案 0 :(得分:4)
我会这样写你的例子:
class Session
{
public:
Session(string url, string user, string password);
};
class Camera
{
public:
Camera(Session);
image take_snapshot();
bool reboot();
};
这里的主要思想是将认证和会话/端点定义(以及可能的连接)与摄像机控件分开。相机类现在更接近真实相机的模型:它有类似电源按钮和快门按钮的东西。相机的虚拟化本身就在其他地方。如果有人想为不同的相机制作USB会话,这也会更明显地做什么。
这里的第二个想法是从一开始就使用有效状态创建对象。例如,在没有密码的情况下,没有办法配置摄像头,因此无法使用不使用凭证调用take_snapshot()。当然,凭证可能无效,但可以通过某个可能在其中一个构造函数中调用的方法来检查。
顺便说一句,免费功能没有任何问题。 OOP被高估了,我们都知道,如果免费功能在您的用例中起作用,您不应该道歉。哑结构可能比无意义的getter和setter更好 - 特别是如果你没有构建一个具有ABI兼容性要求的可重用库。