在 Minecraft 中实现块功能时如何执行单一职责原则?
How to do Single Responsibility Principle when implementing Chunk functionality like in Minecraft?
我正在尝试为区块创建功能(就像我们在 Minecraft 中看到的由 16x16x256 块组成的区块)。
在实现单一职责原则的同时我应该如何去做?
功能包括加载、保存、创建网格和跟踪所有块。
我应该
创建一个包含许多 class 的块 class,每个块都具有其中一种功能,例如加载或保存。然后在 Chunk class 中启动 classes。
当这些 classes 需要 Chunk class 的功能时我该怎么办,这不会破坏 SRP 吗?
在块中创建所有功能class
所以,如果我们在这里谈论一般指针,那么可以从一些简单的事情开始。
- 您的
Chunk
class 应该只处理其主要职责 - 管理 Chunk
. 中包含的任何内容
- 听起来您需要一个
ChunkGroup
,可能会在 Chunk 上使用 Adapter 模式,它聚合了 Chunk
的 'network'。
- 应该存在一些持久化
Chunk
对象的方法。这不是 Chunk
本身的责任,但可能涉及一个内部 class 允许将 Chunk
转换成可以(反)序列化的东西。
所以,我期待看到类似
的内容
interface Chunk {
String doTheThing();
}
interface ChunkNetwork extends Chunk {
add(Chunk chunk);
};
final class ChunkList implements ChunkNetwork {
private List<Chunk> theChunks;
add(Chunk chunk) {
theChunks.add(chunk);
}
String doTheThing() {
StringBuilder builder = new StringBuilder();
for (Chunk chunk : theChunks) {
builder.append(chunk.doTheThing());
}
return builder.toString();
}
}
final class JsonChunk implements Chunk {
@JsonProperty
private final int someField;
@Override
public String doTheThing() {
String.format("%d", someField);
}
@JsonCreator
public JsonChunk(int fieldValue) {
someField = fieldValue;
}
}
这里关于SRP的注意事项:
- Chunk 接口仅包含与 Chunk 应该执行的核心功能相关的方法。
- 适配器将创建
Chunk
个对象的 'network' 的功能提取到单独的 class 中。管理此类网络有不同的方法,您可能希望稍后更改它。您可以在不改变 Chunk
本身的工作方式的情况下这样做。
ChunkNetwork
根据您的使用情况可能有不同的方法,这可能会告诉您如何选择实现接口,但关键是网络管理不在 Chunk
本身.
Chunk
对象如何在 XML 或 JSON(或任何磁盘上,文件中)中表示是与 API 的内容不同的问题Chunk
是。然而,对于像 Jackson 这样的库,我们通常可以不用为 marshalling/unmarshalling 定义单独的 class。但是,如果您的 Chunk
实现变得复杂,您可能需要这样做。
最终,SRP 表示任何个人 class 都应该有一个改变的理由。因此,您需要查看您的功能并查看它可能会发生变化的原因。典型的原因是:
- 核心功能的变化。您的域可能需要额外/更改的功能。这相当于
Chunk
界面的变化。
- 更改核心对象的排列方式以提供系统内的高级表示(也许您决定使用树结构表示
Chunk
的网络)。等同于 ChunkList
class. 的更改(或重新实现)
- 持久性发生方式的变化。这可能是持久性库(例如 Jackson、JPA、JAXB 等)使用的注释的更改,或者它可能是代表 'Data Transfer Object'.
的全新 class 结构
根据经验,如果您发现自己在描述 class 时使用了多个句子或使用了连词('and'、'but',还有逗号等标点符号)那么您可能会看到违反单一职责原则的情况。另一个经验法则是将这些句子/连词中的每一个都取出来,并尝试将它们隔离成一个 class。然后查看 class 是否违反了 SRP。冲洗并重复,直到没有任何东西违反 SRP。
听起来很简单,但就像国际象棋一样,学会需要几分钟,但要掌握则需要一生。
我正在尝试为区块创建功能(就像我们在 Minecraft 中看到的由 16x16x256 块组成的区块)。
在实现单一职责原则的同时我应该如何去做?
功能包括加载、保存、创建网格和跟踪所有块。
我应该
创建一个包含许多 class 的块 class,每个块都具有其中一种功能,例如加载或保存。然后在 Chunk class 中启动 classes。 当这些 classes 需要 Chunk class 的功能时我该怎么办,这不会破坏 SRP 吗?
在块中创建所有功能class
所以,如果我们在这里谈论一般指针,那么可以从一些简单的事情开始。
- 您的
Chunk
class 应该只处理其主要职责 - 管理Chunk
. 中包含的任何内容
- 听起来您需要一个
ChunkGroup
,可能会在 Chunk 上使用 Adapter 模式,它聚合了Chunk
的 'network'。 - 应该存在一些持久化
Chunk
对象的方法。这不是Chunk
本身的责任,但可能涉及一个内部 class 允许将Chunk
转换成可以(反)序列化的东西。
所以,我期待看到类似
的内容interface Chunk {
String doTheThing();
}
interface ChunkNetwork extends Chunk {
add(Chunk chunk);
};
final class ChunkList implements ChunkNetwork {
private List<Chunk> theChunks;
add(Chunk chunk) {
theChunks.add(chunk);
}
String doTheThing() {
StringBuilder builder = new StringBuilder();
for (Chunk chunk : theChunks) {
builder.append(chunk.doTheThing());
}
return builder.toString();
}
}
final class JsonChunk implements Chunk {
@JsonProperty
private final int someField;
@Override
public String doTheThing() {
String.format("%d", someField);
}
@JsonCreator
public JsonChunk(int fieldValue) {
someField = fieldValue;
}
}
这里关于SRP的注意事项:
- Chunk 接口仅包含与 Chunk 应该执行的核心功能相关的方法。
- 适配器将创建
Chunk
个对象的 'network' 的功能提取到单独的 class 中。管理此类网络有不同的方法,您可能希望稍后更改它。您可以在不改变Chunk
本身的工作方式的情况下这样做。 ChunkNetwork
根据您的使用情况可能有不同的方法,这可能会告诉您如何选择实现接口,但关键是网络管理不在Chunk
本身.Chunk
对象如何在 XML 或 JSON(或任何磁盘上,文件中)中表示是与 API 的内容不同的问题Chunk
是。然而,对于像 Jackson 这样的库,我们通常可以不用为 marshalling/unmarshalling 定义单独的 class。但是,如果您的Chunk
实现变得复杂,您可能需要这样做。
最终,SRP 表示任何个人 class 都应该有一个改变的理由。因此,您需要查看您的功能并查看它可能会发生变化的原因。典型的原因是:
- 核心功能的变化。您的域可能需要额外/更改的功能。这相当于
Chunk
界面的变化。 - 更改核心对象的排列方式以提供系统内的高级表示(也许您决定使用树结构表示
Chunk
的网络)。等同于ChunkList
class. 的更改(或重新实现)
- 持久性发生方式的变化。这可能是持久性库(例如 Jackson、JPA、JAXB 等)使用的注释的更改,或者它可能是代表 'Data Transfer Object'. 的全新 class 结构
根据经验,如果您发现自己在描述 class 时使用了多个句子或使用了连词('and'、'but',还有逗号等标点符号)那么您可能会看到违反单一职责原则的情况。另一个经验法则是将这些句子/连词中的每一个都取出来,并尝试将它们隔离成一个 class。然后查看 class 是否违反了 SRP。冲洗并重复,直到没有任何东西违反 SRP。
听起来很简单,但就像国际象棋一样,学会需要几分钟,但要掌握则需要一生。