SRP 是否与单个 class 的可能操作或它们在其中的实施有关?

Is SRP related to possible actions of a single class or to their implementation in it?

我在很多地方读到 SRP 是一个很好的应用原则,我想在我的项目中应用它。

实际上,这是一个游戏,我的对象基本上有两个功能updatedraw,所以它们有两个职责(定义为"reason to change")。它可能看起来像这样:

class Object {
    public:
        void update() {
            // implementation...
        }

        void draw() {
            // implementation...
        }
};

假设我选择使用组件设计模式将 updatedraw 拆分为 UpdateComponentDisplayComponent,使用这些组件的对象将仍然有 update/draw 这对,但不再是它们的实现了。所以它现在看起来像这样:

class Object {
    public:
        void update() {
            m_updateComponent.update(*this);
        }

        void draw() {
            m_displayComponent.draw(*this);
        }

    private:
        UpdateComponent m_updateComponent;

        DisplayComponent m_displayComponent;
};

在此实现中,updatedraw 被视为对象的组件 的责任,还是仅被对象同意的组件使用 SRP?

您已考虑 "reason to change" 并移动了它。现在如果绘图或更新需要更改,则不需要更改 Object class。这完全符合 SRP。

但是,你有一些不必要的耦合。由于 DisplayComponentObject 之间的双向依赖关系,您可以分辨出来。为什么 Object 需要知道(取决于)它的 DisplayComponent 甚至是 UpdateComponent

你有:

DisplayComponent <--> Object

(这些行代表一种依赖关系,也就是说,如果没有它指向的另一个,你就无法编译一个)

你只需要:

DisplayComponent ---> Object

但是,如果您不能从对象调用 DisplayComponent,您将如何到达 DisplayComponent 来调用 draw

ObjectContainer          --\ 
   --> UpdateComponent   ---> Object
   --> DisplayComponent  --/

所以我引入了一个新的 ObjectContainer class,它知道(取决于)UpdateComponentDisplayComponentObject

您的外部游戏循环只能访问 ObjectContainers 并且只能通过 m_updateComponent 更改游戏状态并通过 m_displayComponent 绘制。 Object现在唯一的职责是保持对象的状态:

class Object {
    public:
      //getters/setters maybe

    private:
        int x;
        int y;
        float speed;
        float health;
        //etc
};

class ObjectContainer {
    public:
        void update() {
            m_updateComponent.update(object);
        }

        void draw() {
            m_displayComponent.draw(object);
        }

    private:
        Object object;

        UpdateComponent m_updateComponent;

        DisplayComponent m_displayComponent;
};

上面的ObjectContainer和你的Object非常相似,但是没有双向依赖。