如何做正确的SRP?

时间:2017-01-03 22:32:11

标签: oop single-responsibility-principle

我有一个案例,我正在创建一个Chunk类

这个类必须加载,保存,创建网格,跟踪块中的对象,等等。

实现单一责任原则的正确方法是什么?

你应该为每个"工作"创建一个班级,并且所有课程都要在" god"中实现。名为Chunk的类。 如果是这样,如果其他类需要来自Chunk类的函数调用,我该怎么办。我应该在所有其他类中引用Chunk类吗?如果我需要使用Chunk类中的私有变量怎么办?我该怎么做呢?让变量公开吗?

或许我应该有一个"上帝"班级,并有"工作"内心阶级?

还是其他?

1 个答案:

答案 0 :(得分:0)

所以,如果我们在这里谈论一般性指针,那么首先要做一些简单的事情。

  • 您的Chunk课程应该只处理其主要责任 - 管理Chunk中包含的内容。
  • 听起来你需要ChunkGroup,可能会在Chunk上使用适配器模式,它会聚合Chunk的“网络”。
  • 应该存在一些持久化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本身之内。 / LI>
  • Chunk对象如何用XML或JSON(或任何,在磁盘上,文件中)表示,与Chunk的API有什么区别。然而,对于像杰克逊这样的图书馆,我们经常可以逃脱,而无需为编组/解组定义单独的类。但是,如果您的Chunk实施变得复杂,则可能需要这样做。

最终,SRP说任何一个班级都应该有一个改变的理由。因此,您需要查看您的功能并查看其可能发生的变化。典型的原因是:

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

根据经验,如果您发现自己使用多个句子或使用连词('和','但',还有逗号等标点符号)来描述一个类,那么您可能会看到违反单一责任原则。进一步的经验法则是采用这些句子/连词中的每一个,并尝试将它们分离为单个类。然后查看该类是否违反了SRP。冲洗&amp;重复,直到没有违反SRP。

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