2009-05-02 135 views
1

我有一個具有「notify」方法的進程,它接收消息類型的基類作爲參數。我想根據派生類型的消息做不同的處理。這是否意味着我需要添加一個名爲「process」或類似於消息類型的方法,並使用多態性調用它?爲每個特定的消息類型添加「通知」會更好嗎?如何根據消息類型處理不同的處理?

更多細節:語言是C++。我認爲通知在這裏是一個好主意,所以我只需要一種方法來通知各種消息類型。控制器從指定純虛通知(MsgBaseClass)方法的偵聽器類繼承。我仍然喜歡這個想法,因爲我不必爲每個新消息類型添加通知。但是在控制器代碼本身中,除了動態類型轉換之外,我沒有看到任何區分消息類型或向消息添加消息類型的方法。

編輯:我想我要去與訪客模式。它允許我只保留一個通知的方法,並且可以避免在代碼中使用switch語句。 「訪問者」接口將指定偵聽器處理各種派生消息類型所需的各種方法。這將只需要一個消息被添加到消息的基類,純虛「接受(MyMessageTypeVisitor v)的派生消息類別將利用v.visit實現它(這);

認爲這個現在應該工作

回答

1

經典的OO答案要求基類消息類提供一個抽象方法,其中具體的消息子類覆蓋以提供特定的處理。

Dylan和CLisp等一些(不是很普遍)的語言提供了「通用函數」(在參數類型上動態調度),可以非常徹底地解決問題。

在流行語言中可行的一種靈活方法是Bob叔叔的「Acyclic Visitor」設計模式,http://www.objectmentor.com/resources/articles/acv.pdf;欲瞭解更多訪客變體,請訪問www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usage/papers/plop96/variations-visitor-nordberg.ps。

1

編輯:我認爲dirkgently有一個很好的觀點,並且這些消息不應該知道如何處理自己,因此我描述的消息可以用作工廠的方法並不是一個好主意。認爲抽象工藝工廠可能是一個很好的解決方案。

使用抽象工廠來創作一個可以處理處理的對象,並使用多態性調用它。這個工廠可能直接包含在消息類中,或者你可以創建一個單獨的工廠類來接受消息類型作爲參數並返回一個合適的對象。

class Message { 
public: 
    virtual Processor *getProcessor() = 0; 
    // other methods 
}; 

class Processor { 
public: 
    virtual void doWork() = 0; 
}; 

class MyListener : Listener { 
public: 
    void notify(Message *message); 
}; 

void MyListener::notify(Message *message) { 
    Processor *proc = message->getProcessor(); 
    proc->doWork(); 
}; 

(很抱歉,如果這是不正確。我的C++是有點弱,但我相信它說明原理。)

這將允許你只覆蓋getProcessor()每個消息類型,在那裏創建適當的處理器。

IMVHO,多態是要走的路。我猜想你所要做的處理邏輯不屬於消息類,應該移到不同的類中。我更喜歡這種方法的另一個原因是,如果我添加其他消息,它不需要我更改要通知的類的結構。如果只有一種或兩種消息類型,這可能不是問題。

0

你是否堅持觀察者設計模式?

Overloaded notify看起來像一個候選人。觀察者模式非常簡單。它基於the Hollywood Principle,即「不要打電話給我們,我們會打電話給你!」。這個想法是有一組對象(觀察者)並通知他們而不是讓他們查詢你。您向觀察者傳遞一種通用的Event類型的數據。應由觀察員決定如何處理。如果觀察者對不同的事件作出反應(是的,你還需要一個事件層次結構),那麼會有一些dynamic_casts

+0

嗨德克, 我給主要問題增加了一些細節。 – 2009-05-02 16:50:25

+0

我喜歡動態演員主意的簡單性。但是將處理與消息本身打包在一起更「OO」,不是嗎? – 2009-05-02 17:06:59

0

你可以做這樣的事情:

DerivedType *dt = dynamic_cast<DerivedType>(&BaseType); 
if(dt != NULL) 
{ 
    // Handle processing of DerivedType 
} 

剛剛嘗試做一個dynamic_cast的每個處理DerivedType。如果你得到一個非空指針,那麼你知道你已經收到了你想要轉換的類型。