【问题标题】:How to do Single Responsibility Principle when implementing Chunk functionality like in Minecraft?在 Minecraft 中实现 Chunk 功能时如何执行单一职责原则?
【发布时间】:2017-01-03 22:32:11
【问题描述】:

我正在尝试为块创建功能(就像我们在 Minecraft 中看到的由 16x16x256 块组成的块)。

在实现单一职责原则的同时,我应该如何做到这一点?

功能包括加载、保存、创建网格和跟踪所有块。

我应该

  1. 创建一个由许多类组成的 Chunk 类,每个类都具有这些功能之一,例如加载或保存。然后在 Chunk 类中启动类。 当这些类需要来自 Chunk 类的功能时,我该怎么办,这不会破坏 SRP 吗?

  2. 在 Chunk 类中创建所有功能

【问题讨论】:

  • 无法给出有用的答案,问题太抽象了。您的描述听起来像您现有的类违反了 SRP,因此需要将其分解为个人职责。公开字段听起来像是 BadThing(tm) 所以不要这样做。如何避免这种情况取决于上下文。你有一些代码吗?
  • 没有要显示的代码。我只是想了解 SRP。我想我的问题归结为:我如何正确分解一个类?如何管理它?我有点需要一般建议。但正如你所说,它取决于上下文。所以我不知道。

标签: oop single-responsibility-principle


【解决方案1】:

所以,如果我们在这里谈论一般指针,那么有一些简单的事情可以开始。

  • 您的 Chunk 类应该只处理其主要职责 - 管理 Chunk 中包含的任何内容。
  • 听起来您需要一个ChunkGroup,可能在块上使用适配器模式,它聚合了Chunks 的“网络”。
  • 应该存在一些持久化Chunk 对象的方法。这不是Chunk 本身的责任,但可能涉及允许将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 对象的“网络”的功能提取到单独的类中。管理此类网络有不同的方法,您可能希望稍后更改。您可以在不改变 Chunk 本身的工作方式的情况下这样做。
  • ChunkNetwork 可能有不同的方法,具体取决于您的使用情况,这可能会告知您选择如何实现接口,但关键是网络管理在Chunk 本身之外。
  • Chunk 对象如何在 XML 或 JSON(或任何磁盘上的文件中)表示是与Chunk 的 API 不同的问题。然而,对于像 Jackson 这样的库,我们通常可以在不为编组/解组定义单独的类的情况下摆脱困境。但是,如果您的 Chunk 实现变得复杂,您可能需要这样做。

最终,SRP 说任何单独的班级都应该有一个改变的理由。所以你需要看看你的功能,看看它为什么会改变。典型的原因是:

  • 核心功能的变化。您的域可能需要额外/更改的功能。这相当于更改了Chunk 接口。
  • 改变核心对象的排列方式以在系统内提供高级表示(也许您决定使用树结构表示Chunks 的网络)。相当于更改(或重新实现)ChunkList 类。
  • 持久性发生方式的变化。这可能是持久性库(例如 Jackson、JPA、JAXB 等)使用的注释的更改,也可能是表示“数据传输对象”的全新类结构。

根据经验,如果您发现自己使用多个句子或连词(“and”、“but”,以及逗号等标点符号)来描述一个类,那么您可能会看到违反了单一职责原则。另一个经验法则是,将这些句子/连词中的每一个都提取出来,并尝试将它们隔离到一个类中。然后查看该类是否违反了 SRP。冲洗并重复,直到没有违反 SRP。

听起来很简单,但就像国际象棋一样,学习需要几分钟,但要掌握一辈子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    相关资源
    最近更新 更多