SRP 是否与单个 class 的可能操作或它们在其中的实施有关?
Is SRP related to possible actions of a single class or to their implementation in it?
我在很多地方读到 SRP 是一个很好的应用原则,我想在我的项目中应用它。
实际上,这是一个游戏,我的对象基本上有两个功能update
和draw
,所以它们有两个职责(定义为"reason to change")。它可能看起来像这样:
class Object {
public:
void update() {
// implementation...
}
void draw() {
// implementation...
}
};
假设我选择使用组件设计模式将 update
和 draw
拆分为 UpdateComponent
和 DisplayComponent
,使用这些组件的对象将仍然有 update
/draw
这对,但不再是它们的实现了。所以它现在看起来像这样:
class Object {
public:
void update() {
m_updateComponent.update(*this);
}
void draw() {
m_displayComponent.draw(*this);
}
private:
UpdateComponent m_updateComponent;
DisplayComponent m_displayComponent;
};
在此实现中,update
和 draw
被视为对象的组件 和 的责任,还是仅被对象同意的组件使用 SRP?
您已考虑 "reason to change" 并移动了它。现在如果绘图或更新需要更改,则不需要更改 Object
class。这完全符合 SRP。
但是,你有一些不必要的耦合。由于 DisplayComponent
和 Object
之间的双向依赖关系,您可以分辨出来。为什么 Object
需要知道(取决于)它的 DisplayComponent
甚至是 UpdateComponent
?
你有:
DisplayComponent <--> Object
(这些行代表一种依赖关系,也就是说,如果没有它指向的另一个,你就无法编译一个)
你只需要:
DisplayComponent ---> Object
但是,如果您不能从对象调用 DisplayComponent
,您将如何到达 DisplayComponent
来调用 draw
?
ObjectContainer --\
--> UpdateComponent ---> Object
--> DisplayComponent --/
所以我引入了一个新的 ObjectContainer
class,它知道(取决于)UpdateComponent
、DisplayComponent
和 Object
。
您的外部游戏循环只能访问 ObjectContainer
s 并且只能通过 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
非常相似,但是没有双向依赖。
我在很多地方读到 SRP 是一个很好的应用原则,我想在我的项目中应用它。
实际上,这是一个游戏,我的对象基本上有两个功能update
和draw
,所以它们有两个职责(定义为"reason to change")。它可能看起来像这样:
class Object {
public:
void update() {
// implementation...
}
void draw() {
// implementation...
}
};
假设我选择使用组件设计模式将 update
和 draw
拆分为 UpdateComponent
和 DisplayComponent
,使用这些组件的对象将仍然有 update
/draw
这对,但不再是它们的实现了。所以它现在看起来像这样:
class Object {
public:
void update() {
m_updateComponent.update(*this);
}
void draw() {
m_displayComponent.draw(*this);
}
private:
UpdateComponent m_updateComponent;
DisplayComponent m_displayComponent;
};
在此实现中,update
和 draw
被视为对象的组件 和 的责任,还是仅被对象同意的组件使用 SRP?
您已考虑 "reason to change" 并移动了它。现在如果绘图或更新需要更改,则不需要更改 Object
class。这完全符合 SRP。
但是,你有一些不必要的耦合。由于 DisplayComponent
和 Object
之间的双向依赖关系,您可以分辨出来。为什么 Object
需要知道(取决于)它的 DisplayComponent
甚至是 UpdateComponent
?
你有:
DisplayComponent <--> Object
(这些行代表一种依赖关系,也就是说,如果没有它指向的另一个,你就无法编译一个)
你只需要:
DisplayComponent ---> Object
但是,如果您不能从对象调用 DisplayComponent
,您将如何到达 DisplayComponent
来调用 draw
?
ObjectContainer --\
--> UpdateComponent ---> Object
--> DisplayComponent --/
所以我引入了一个新的 ObjectContainer
class,它知道(取决于)UpdateComponent
、DisplayComponent
和 Object
。
您的外部游戏循环只能访问 ObjectContainer
s 并且只能通过 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
非常相似,但是没有双向依赖。