单个函数类(命名为动词)

时间:2017-03-04 15:23:40

标签: c# .net naming-conventions command-query-separation

我正在尝试一种新的代码结构,我将所有巨型存储库和工厂分成大量的小类,每个类都有一个责任。最重要的是,我使用动词作为类名,因为我认为这是描述每个类的确切含义的最佳方式。

每个类只有一个公共方法(称为“执行”),但通常有私有方法,有时还有带参数的构造函数。

实施例

在:

class DocumentRepository {
  public List<Document> GetDocuments()
  public void SaveDocument(Document document)
  public Document CopyDocument(int id)
}

后:

class GetDocuments {
  public List<Document> Execute()
}
class SaveDocument {
  public void Execute(Document document)
}
class CopyDocument {
  public Document Execute(int id)
}

这种结构的一个好处是我更愿意将公共方法的功能分成多个私有方法(更容易阅读和管理)。在此之前会增加存储库中的混乱,但现在私有方法包含在它们各自的类中。

我一直认为类应该有名词作为名称,但是当一个类只有一个用途时,最好用它的名字命名。

问题

这是一个坏主意(分离和命名)?如果是这样,创建这种分离和避免大型课程的更好方法是什么?

修改: 应该注意的是,我从Command-Query的角度来看这些(奇怪的)想法。因此,将它与存储库进行比较可能是最有意义的。

3 个答案:

答案 0 :(得分:1)

IMO,你的设计很奇怪。

当然,我理解你的目标 - 通过将私有方法移动到其他地方来减少类中的噪声,但是将每个方法移动到一个单独的类中似乎太过分了。

之前,您只需要一个对象来获取,保存和复制文档。现在你需要3个并行!我想你可以创建一个包装这三个类的包装器,

public class DocumentRepository {
    public readonly GetDocument Get = new GetDocument();
    public readonly SaveDocument Save = new SaveDocument();
    public readonly CopyDocument Copy = new CopyDocument();
}

但仍然太复杂了。

如果您想减少噪音,请尝试以更好的方式组织课程,并在IDE支持时使用#region#endregion。如果我是你,我会这样做:

public SomeClass {
    // private fields
    ...
    // properties
    ...
    // public methods
    ...
    // private methods
    ...
}

另一种方法是:

public SomeClass {
    // private fields
    ...
    // properties
    ...
    // public method 1
    ...
    #region
    // private methods related/called by public method 1
    ...
    #endregion
    // public method 2
    ...
    #region
    // private methods related/called by public method 2
    ...
    #endregion
    // public method 3
    ...
    #region
    // private methods related/called by public method 3
    ...
    #endregion

    #region
    // other private methods that are not related to a particular public method.
    #endregion
}

答案 1 :(得分:1)

虽然将每个方法提取到单独的类中似乎过于激进,但它中有一个有意义的元素。对于高负载系统,正在应用命令 - 查询责任隔离(CQRS)原则。它的主要思想是严格地分离查询(幂等方法,不修改系统状态,但只返回数据)来自Commands(修改系统状态的方法;&#34; pure&#34; CQRS,它们甚至不均匀)返回数据 - 虽然我仍然很难接受这个。)

这样做可以使您的系统更加稳定且易于扩展,因为您可以拥有许多除了读取之外什么都不做的分布式节点,专注于修改数据的单个节点的性能。然而,并非所有系统都需要这个。

即使你真的需要单独的类用于单个方法,将它命名为动词也不是一个好主意,因为它会混淆其他开发人员(留在一个类中,很难确定你在代码中看到的内容 - 另一个类名或此类&#39;内部方法)。你不需要在这里发明你自己的符号,只需使用以下(相对标准):

class GetDocumentsQuery { }

class SaveDocumentCommand { }

class CopyDocumentCommand { }

有关CQRS的更多信息:

  1. https://en.wikipedia.org/wiki/Command%E2%80%93query_separation

  2. http://rob.conery.io/2014/03/04/repositories-and-unitofwork-are-not-a-good-idea/

答案 2 :(得分:0)

  

这是一个坏主意(分离和命名)?

我想说命名​​主要是品味问题。然而,你的新设计简直太糟糕了。

您应该以逻辑方式将功能相关的方法组合在一起,通常基于它执行操作的实体。我会说你的GetSave等方法属于存储库模式类,或者属于实体类本身。 从不我会把方法变成类,这根本就没有意义。

我可以理解你想要保持每个班级的行数减少。也许最好使用基类将公共代码放入或在一个单独的类中拆分一些重复的操作。