继承和责任

Tek*_*Tek 10 oop inheritance single-responsibility-principle

当我读到关于继承时,我总是对某个例子感到困惑.

通常有一个类似于下面例子的例子.

class Shape
{
public:
    Shape() {}
    virtual ~Shape  () {}
    virtual void Draw() = 0;
};

class Cube : public Shape
{
public:
   Cube(){}
   ~Cube(){}
   virtual void Draw();
};

Shape* newCube = new Cube();
newCube->Draw(); 
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么Shape要自拔自拔?难道渲染器类不应该知道如何绘制形状而是为渲染器提供形状吗?如果我们想记录维度的变化怎么办?等等?我们是否有针对这些不同任务的方法Shape

看到这样的众多例子有时让我想知道我将责任分配给班级的能力.有什么我不理解只有一个责任的课程吗?

ali*_*ind 3

AShape应该不知道它是如何绘制的。设计的项目越大,这个决定就越关键。

对我来说,这一切都归结为循环依赖,除了最尖锐的情况之外,它只会引起头痛。

模型视图控制器的基本原则是,您所做的事情(动词或“视图”)与正在操作或分析的事情(名词或“控制器”)明显分开:表示和逻辑的分离。“模特”就是中间人。

这也是单一职责原则:“......每个类都应该有单一职责,并且该职责应该完全由类封装”

其背后的原因是:循环依赖意味着对任何事物的任何更改都会影响所有事物

另一条(为简洁起见而编辑的)引用了单一责任原则:“一个类或模块应该有一个且只有一个改变的理由。单一责任原则说问题的实质和表面方面实际上是两个独立责任,因此应该位于单独的类或模块中。将在不同时间因不同原因而变化的两个事物结合在一起将是一个糟糕的设计。” (强调我的)

最后,关注点分离的概念:“设计系统的目标是使功能可以独立于其他功能进行优化,这样一个功能的失败不会导致其他功能失败,并且总体上使其更容易理解、设计和管理复杂的相互依赖的系统。” (强调我的)


这不仅仅是一个编程设计问题。

考虑一个网站的开发,“内容”团队必须非常温和地围绕一些脚本(由“开发”团队创建)放置文字、格式、颜色和图片,就这样,否则一切都会崩溃。内容团队希望根本没有脚本——他们不想学习如何编程,只是为了改变一些文字或调整图像。开发团队不想担心由不知道如何编码的人所做的每一个微小的视觉变化都有可能破坏他们的东西。

我每天在处理自己的项目时都会思考这个概念。当两个源文件相互导入时,其中任何一个的更改都需要同时重新编译。对于较大的项目,这可能意味着一个微不足道的更改需要重新编译数百或数千个类。在我目前参与的三个主要项目中,大约有一千个不同的源代码文件,恰好存在这种循环依赖。

无论是业务团队、源代码文件还是设计编程对象,我建议避免循环依赖,除非绝对必要。


所以,至少,我不会将绘制函数放在Shape. 尽管非常依赖于正在设计的项目的类型和大小,但渲染可以由一个RenderingUtils类来完成,该类只包含完成大部分工作的公共静态函数。

如果该项目是一个中等规模的项目,我会更进一步,创建一个Renderable界面作为模型层。AShape实现Renderable,因此不会知道或关心它是如何绘制的。无论绘图需要什么,都不需要了解Shape.

这使您可以灵活地完全更改渲染的完成方式,而不会影响(或必须重新编译!)Shapes,并且它还允许您渲染与 a 截然不同的东西Shape,而无需更改绘图代码。