2009-11-28 15 views
3

假設我正在使用'Job'類記錄一些數據。 (具有各種屬性的業務對象列表,以及它的價值)。調用類上的方法或將其作爲參數傳遞給另一個類? C#

我希望能夠打印這些數據,所以我想知道是否有一個更喜歡這樣做的設計。我目前所面對的兩個想法 - 調用print()方法的工作本身,還是傳遞一個作業實例某種打印控制器類,例如:

job.Print(); 

PrintWidget pw = new PrintWidget(job); 
pw.Print(); 

在此刻,我無法想象打印此作業類中的任何數據。但是,誰知道未來會如何。考慮到這一點,在我想要打印的任何類上打印單獨的Print()方法還是可以處理不同類型的打印類型的Print控制器類會更好?

你會如何去設計這個?預先感謝任何答案。

回答

7

您的問題,正視適合的單一職責原則(SRP )SOLID原理之一。

原理實質上指出,一個設計良好的組件應該永遠只能負責單一的任務。看待它的另一種方式是組件應該只有一個改變的理由。這可以確保當你需要改變的東西,你知道所有的功能將在一個地方並不會與其他功能混合。

在你的情況下,Job大概有某種比打印,也許有些責任,表示您的域模型中的「工作」等功能。如果是這樣,那麼你不想在這裏添加打印功能。相反,創建您的打印小部件,並把所有的邏輯打印在那裏。

如果打印必須改變,你不會有觸摸你Job對象,因爲它的責任並沒有改變。同樣,如果「作業」的概念發生變化,則只修改類別Job,並且打印保持不變(除非您現在有額外要打印的內容)。

但是......

如果Job類的唯一目的是爲了代表打印一些信息,那麼它最肯定應該包含PrintTo(Printer)方法,其中Printer將負責交談一臺物理打印機。在這種情況下,責任轉移到只涉及打印的Job,它應該控制它的打印方式。

SRP可以是一個困難的圖案在你的設計中看到的,但有一個簡單的辦法,以確保:

如果你能總結一下 類的功能,而無需使用這個詞 「和「,這個班級有一個責任感。

因此,Job要麼負責「代表一份工作」或「打印工作信息」,但不是兩者。

+0

很好的答案,謝謝。然後是單獨的打印類。 – Andy 2009-11-28 11:47:45

0

就我個人而言,我將Print方法放在Job類中。如果您創建一個單獨的PrintWidget類,它將必須知道關於Job類的所有信息。無論如何,如果事實證明您將來需要或想要PrintWidget,您可以隨時創建它,並重構Job類的Print方法。

3

打印Job課程的關鍵部分的知識?如果不是,它可能不應該在該類別中(分離關注等)。如果在不同的環境下打印可能會有所不同,這將適用雙重打印。我可能會做更多的東西一樣:

PrintWidget pw = new JobPrintWidget(); // perhaps via abstract-factory 
pw.Print(job); 

至於什麼PrintWidget是...如果你需要支持其他類型的未來,我猜你可能要麼有一個具體的實現的抽象基類的(如上所示,其中Print是一種抽象方法),或者可替代的一個接口。

對於我來說,工作感覺更像是輸入,但如果小部件只需要打印1份工作,那就這樣吧。

另一種可能性(在C#3)是一個擴展方法:

static class PrintUtil { 
    public static void Print(this Job job) {...} 
} 

它允許您使用job.Print(),但沒有將代碼置於Job

+0

工作的主要功能主要是將其保存包含到文件,並且將其顯示在數據。我預計實際印刷它將是罕見的。 – Andy 2009-11-28 10:37:14

+0

這聽起來* *像它會是更好地保持了「我是一個職業」和「我*打印*工作」邏輯分離,然後。 – 2009-11-28 10:58:02

2

一種選擇是使用在C#3.0中引入的Extension Methods。擴展方法允許您擴展一個類而不從其派生,這允許更大的靈活性。使用擴展方法,您可以在不改變原始類的情況下,將Job方法添加到Job類和任何其他類。例如:

static class PrintExtensions 
{ 
    public static void Print (this Job job) 
    { 
     // TODO: print Job 
    } 

    public static void Print (this SomeOtherClass c) 
    { 
     // TODO: print SomeOtherClass 
    } 
} 

一旦你定義一個擴展方法,你使用它,就好像它是類本身定義的,例如:

Job job = GetJob(); 
job.Print(); // call PrintExtensions.Print(this Job job) 
相關問題