2011-10-03 33 views
3

我構建了一個異步任務服務執行程序,它通過外部請求執行任務。強制程序員調用其基地中的方法

每個任務都包含函數void run(),,因此任何想要向系統添加任務的程序員都需要繼承自BaseTask

interface ITask{ 
     void run(); 
    } 
    abstract BaseTask : ITask{ 
     //force "run()" to set Result 
     public ResultContainer Result {set; get;} 
     void run(); 
    } 

    class SomeTask : BaseTask { 
     void run(){ 
      ////run the operation here, in the end, set the result. 
      //force the programmer to set the Result; 
      this.Result = new ResultContainer("task ok"); 
     } 
    } 

由於內部原因,run()必須是無效的。

有什麼辦法可以強制一個程序員想要添加一個任務來調用ResultBaseTask並設置其值? 你認爲這是一個不好的做法?

感謝

+0

您可以與執行添加另一種方法來ITask和BaseTask對onResult()來設置的結果,但不管依託別人做你想讓他們做的事情可能是不可靠:) –

+0

這似乎有關:http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface –

回答

12

是的,這是要避免的。像這樣的規則應該到位,以便它們在可能和實際的情況下由編譯器執行(而不是慣例)。

在你的情況,你應該做這樣的事情:

public abstract class BaseTask 
{ 
    public void Run() 
    { 
     Result = RunInternal(); 
    } 

    public ResultContainer Result { get; set; } 

    protected abstract ResultContainer RunInternal(); 
} 

這將完成你想要的語義內容(即調用Run功能外也總是會使Result屬性設置),以及它的力量從BaseTask繼承的開發人員提供正在使用的值。唯一的區別是它們將覆蓋(或者說,實現)RunInternal函數而不是Run

+0

只是完美!簡單又幹淨,我沒什麼可說的 – fatnjazzy

+0

'BaseTask.Run'需要'密封'嗎? –

+0

@HemalPandya:在C#中,除非用'virtual'標記,否則所有方法都是密封的。 –

1

我不確定這是否符合一些預想象的設計模式,但是您能否添加另一種方法來確保返回值,並讓開發人員執行該操作?例如(如果代碼是遺憾不是100%正確的,在VS不這樣做):

interface ITask{ 
    void run(); 
} 

abstract BaseTask : ITask{ 
    //force "run()" to set Result 
    public ResultContainer Result{set;get;} 

    void run() { 
     Result = runInternal(); 
    } 

    protected abstract ResultContainer runInternal(); 

} 

class SomeTask : BaseTask { 
    protected override ResultContainer runInternal(){ 
     return new ResultContainer("task ok"); 
    } 
} 
+0

+1謝謝!我將採用這種方法。 – fatnjazzy

+0

它的舊C++習慣用法 - 曾經被稱爲「公共非虛函數調用私人純虛函數」......或類似的東西。 '函數方法'現在需要'保護'。請參閱http://stackoverflow.com/questions/3970279/what-is-the-point-of-a-private-pure-virtual-function –

相關問題