什么时候违反单一责任原则?

时间:2014-03-04 10:17:12

标签: c++ coding-style single-responsibility-principle design-principles

您如何决定何时以及如何违反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作为答案显示

1 个答案:

答案 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兼容性要求的可重用库。