2017-03-04 67 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