单一功能类(命名为动词)
Single function classes (named as verbs)
我正在尝试一种新的代码结构,在这种结构中,我将所有庞大的存储库和工厂拆分为较小的 classes 负载,每个负载都有一个职责。除此之外,我对 class 名称使用动词,因为我认为这是准确描述每个 class 的含义的最佳方式。
每个 class 只有一个 public 方法(称为 "Execute"),但通常有私有方法,有时还有带参数的构造函数。
例子:
之前:
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)
}
这种结构的一个好处是我更愿意将 public 方法的功能拆分为多个私有方法(更易于阅读和管理)。在此之前会增加存储库中的混乱,但现在私有方法包含在它们单独的 classes.
中
我一直读到 classes 应该有名词作为名字,但是当 class 只有一个用途时,最好用它的作用来命名它。
问题:
这是个坏主意吗(分离和命名)?如果是这样,创建这种分离并避免大 classes 的更好方法是什么?
编辑:
应该指出的是,我是从命令-查询的角度得出这些(奇怪的)想法的。因此,将它与存储库进行比较可能最有意义。
Is this a bad idea (both the separation and the naming)?
我想说命名主要是个人喜好问题。然而,您的新设计简直太糟糕了。
您应该以逻辑方式将功能相关的方法组合在一起,通常基于它执行操作的实体。我会说您的 Get
、Save
等方法属于存储库模式 class 或实体 class 本身。 从不 我会把方法变成 classes,那根本没有意义。
我知道您想减少每个 class 的行数。也许最好使用一个基础 class 来放入公共代码,或者将一些重复的动作拆分成一个单独的 class.
IMO,你的设计很奇怪。
当然,我理解您的目的 - 通过将私有方法移动到其他地方来减少 class 中的噪音,但是将每个方法移动到单独的 class 中似乎太过分了。
以前,您只需要一个对象即可获取、保存和复制文档。现在你需要 3 个并行!我想你可以创建一个包装器来包装这三个 classes,
public class DocumentRepository {
public readonly GetDocument Get = new GetDocument();
public readonly SaveDocument Save = new SaveDocument();
public readonly CopyDocument Copy = new CopyDocument();
}
但还是太复杂了。
如果您想要更少的噪音,请尝试以更好的方式组织您的 class 并使用 #region
和 #endregion
(如果您的 IDE 支持它们)。如果我是你,我会这样做:
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
}
虽然将每个方法都提取到单独的 class 中似乎过于激进,但其中还是有道理的。对于高负载系统,正在应用命令查询责任分离 (CQRS) 原则。它的主要思想是将查询(幂等方法,不修改系统状态,但仅 returning 数据)与命令(修改系统状态的方法;在 "pure" CQRS 中它们甚至不return数据——虽然我还是很难接受这个)。
这样做会使您的系统更加稳定且易于扩展,因为您可以拥有许多除了读取之外什么都不做的分布式节点,专注于修改数据的单个节点的性能。然而,并非所有系统都真正需要它。
即使您真的需要一个单独的 class 用于单个方法,将其命名为 verb 也不是一个好主意,因为它会使其他开发人员感到困惑(留在一个 class 中很难以确定您在代码中看到的内容 - 其他 class 名称或此 class' 内部方法)。你不需要在这里发明自己的符号,只需使用以下(相对标准):
class GetDocumentsQuery { }
class SaveDocumentCommand { }
class CopyDocumentCommand { }
有关 CQRS 的更多信息:
我正在尝试一种新的代码结构,在这种结构中,我将所有庞大的存储库和工厂拆分为较小的 classes 负载,每个负载都有一个职责。除此之外,我对 class 名称使用动词,因为我认为这是准确描述每个 class 的含义的最佳方式。
每个 class 只有一个 public 方法(称为 "Execute"),但通常有私有方法,有时还有带参数的构造函数。
例子:
之前:
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)
}
这种结构的一个好处是我更愿意将 public 方法的功能拆分为多个私有方法(更易于阅读和管理)。在此之前会增加存储库中的混乱,但现在私有方法包含在它们单独的 classes.
中我一直读到 classes 应该有名词作为名字,但是当 class 只有一个用途时,最好用它的作用来命名它。
问题:
这是个坏主意吗(分离和命名)?如果是这样,创建这种分离并避免大 classes 的更好方法是什么?
编辑: 应该指出的是,我是从命令-查询的角度得出这些(奇怪的)想法的。因此,将它与存储库进行比较可能最有意义。
Is this a bad idea (both the separation and the naming)?
我想说命名主要是个人喜好问题。然而,您的新设计简直太糟糕了。
您应该以逻辑方式将功能相关的方法组合在一起,通常基于它执行操作的实体。我会说您的 Get
、Save
等方法属于存储库模式 class 或实体 class 本身。 从不 我会把方法变成 classes,那根本没有意义。
我知道您想减少每个 class 的行数。也许最好使用一个基础 class 来放入公共代码,或者将一些重复的动作拆分成一个单独的 class.
IMO,你的设计很奇怪。
当然,我理解您的目的 - 通过将私有方法移动到其他地方来减少 class 中的噪音,但是将每个方法移动到单独的 class 中似乎太过分了。
以前,您只需要一个对象即可获取、保存和复制文档。现在你需要 3 个并行!我想你可以创建一个包装器来包装这三个 classes,
public class DocumentRepository {
public readonly GetDocument Get = new GetDocument();
public readonly SaveDocument Save = new SaveDocument();
public readonly CopyDocument Copy = new CopyDocument();
}
但还是太复杂了。
如果您想要更少的噪音,请尝试以更好的方式组织您的 class 并使用 #region
和 #endregion
(如果您的 IDE 支持它们)。如果我是你,我会这样做:
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
}
虽然将每个方法都提取到单独的 class 中似乎过于激进,但其中还是有道理的。对于高负载系统,正在应用命令查询责任分离 (CQRS) 原则。它的主要思想是将查询(幂等方法,不修改系统状态,但仅 returning 数据)与命令(修改系统状态的方法;在 "pure" CQRS 中它们甚至不return数据——虽然我还是很难接受这个)。
这样做会使您的系统更加稳定且易于扩展,因为您可以拥有许多除了读取之外什么都不做的分布式节点,专注于修改数据的单个节点的性能。然而,并非所有系统都真正需要它。
即使您真的需要一个单独的 class 用于单个方法,将其命名为 verb 也不是一个好主意,因为它会使其他开发人员感到困惑(留在一个 class 中很难以确定您在代码中看到的内容 - 其他 class 名称或此 class' 内部方法)。你不需要在这里发明自己的符号,只需使用以下(相对标准):
class GetDocumentsQuery { }
class SaveDocumentCommand { }
class CopyDocumentCommand { }
有关 CQRS 的更多信息: