2017-03-04 32 views
0

我正在尝试一种新的代码结构,我将所有巨型资源库和工厂分解为每个负责一个小类的负载。最重要的是,我使用动词来表示类名,因为我认为这是最准确地描述每个类的意思。单功能类(命名为动词)

每个类只有一个公共方法(称为“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) 
} 

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

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

问题

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

编辑: 应该指出,我已经从命令查询的角度来看这些(奇怪的)想法。所以也许最有意义的是比较它而不是存储库。

+0

这可能会更好放置在http://codereview.stackexchange.com。也就是说,我会说班级是名词,方法是动词,但这都是意见。 –

回答

1

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

这样会使你的系统更加稳定,易于扩展,你可以有许多分布式节点是做什么,但读,重点讨论修改数据的单个节点的性能。然而,并非所有系统都需要这样做。

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

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/

+0

我实际上是通过阅读和探索命令查询思想来了解这些想法的。我想我正试图在这些原则附近的某个地方找到我舒适的地方。但是我看到你对其他开发人员被动词名称混淆的观点,即使唯一的区别是在类名后添加“Query”或“Command”。 – svejk

0

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

我会说命名主要是品味的问题。然而,你的新设计简直太可怕了。

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

我可以理解你想保持每个类的行数减少。也许最好使用基类来放置通用代码,或者在一个单独的类中分割一些重复的动作。

+0

感谢您的意见,如果您从命令查询角度查看Aleksei的参考资料,您是否认为我的工作更有意义? – svejk

+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 
} 
+0

问题是,除了处理相同类型的对象之外,这些方法(或我的例子中的类)实际上与彼此无关。我不需要将它们包装在一起,除非将它们放在同一个文件夹中,因为它们在域的相同部分中操作。 他们每个人都从一个单独的控制器操作调用。 – svejk

+0

这听起来像你应该创建一个实用课程。如果'DocumentRepository'不包含任何状态(没有属性或字段),则应该创建一个静态实用程序类,其中包含这些方法,按我在答案中描述的方式组织。 @svejk – Sweeper

+0

由于静态使用继承(SaveDocument-class是SaveEntity-class的子类),静态不太适合。我发现使用可实例化的类来管理单元测试要容易得多(必要时可以创建它们的模拟对象)。但你说得对,他们根本没有任何国家,他们只是应用程序中特定任务的执行者。 – svejk