您如何决定何时以及如何违反单一责任原则?
例如,假设我有一个具有以下接口的网络摄像机(为了简单起见,接口保持愚蠢和“错误”):
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 显示为答案
c++ coding-style single-responsibility-principle design-principles
我了解许多设计原则在某些情况下会相互冲突。因此,我们必须权衡它们,看看哪个更有利。直到现在,我才意识到SRP原理,并仅以此为基础进行了很多设计,但在内部,遵循该原理有时会感到不对。现在我开始了解TDA,对此我的感觉得到了更多支持:)
SRP:-对象应该担心自己的关注而不是其他人
TDA:-行为(仅取决于其对象状态)应保留在对象本身内部
示例:- 我有不同的形状,如矩形,正方形,圆形等。现在我必须计算面积。
到目前为止,我的设计是:-我遵循SRP,这里有AreaCalculatorService类,该类将询问形状状态并计算面积。该设计背后的理由是形状不应该担心面积计算,因为它不是形状责任。但是理想情况下,我曾经以为区域计算代码应该驻留在每个形状下,如果出现新形状,就好像在线下一样,我必须修改AreaCalculatorService类(这违反了Open的扩展名和闭合的修改原则(OECM))。但始终优先考虑SRP。好像错了
神话被打破了(至少是我的):-使用TDA,我的感觉是正确的,在这里我不应该询问物体的状态,而要告诉形状以计算其面积。尽管它将违反SRP原则,但将支持OECM原则。正如我所说的那样,设计原则有时会相互冲突,但是我相信行为完全取决于其对象状态,行为和状态应该在一起。
另一个示例:-说我必须计算组织中所有雇员的所有部门的薪水,那么我们应该遵循SRP,SalaryCalculatorService将取决于部门和雇员。
它将询问每个员工的薪水,然后对所有薪水进行汇总。因此,我在这里要求员工的状态,但仍不违反TDA calcSalary不仅取决于每个员工的薪水。
让我知道我对这两个原则的解释是否正确,在第一种情况下应遵循TDA,在第二种情况下应遵循SRP?
oop single-responsibility-principle tell-dont-ask design-principles
我创建了一个在 Azure Function Apps 的帮助下实现的演示微服务应用程序。为了分离关注点,我创建了 API 层、业务层和数据层。
API层,即功能应用程序,调用业务层实现业务逻辑,而数据层实现存储和检索数据的逻辑。
经过深思熟虑,我决定在我的演示中使用基于查询的 API 版本控制。
我的问题是,
组织代码以促进这一点的最佳方法是什么?除了使用不同的命名空间/存储库之外,还有其他方法来组织我的代码以适应不同的版本吗?
到目前为止,我已经为每个版本创建了单独的命名空间,但这会造成大量代码重复。另外,在我的一些朋友对其进行审查后,他们提出了这样的担忧:如果使用单独的命名空间,我将迫使遗留系统更改对新命名空间的引用(如果它们需要更新),这是不建议的。
任何帮助,将不胜感激。
使用引用子类类型的 switch case 的方法创建一个基类。
下面的一段代码是否违反了面向对象原则,如果是,是哪一个?
public abstract class BaseClass
{
public BaseClass Method()
{
switch (this)
{
case DerivedClass1 s:
return new DerivedClass1();
case DerivedClass2 c:
return new DerivedClass2();
case DerivedClass3 r:
return new DerivedClass3();
default:
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)