2014-05-21 203 views
1

我有一個層次結構。接口繼承接口

public interface IIncomingMessage : IMessage 
{ 
    String Source { get; set; } 
    void ProcessMessage(); 
} 


public interface IOutgoingMessages : IMessage 
{ 
    void SendMessage(); 
} 

我有一個使用靜態的CreateMessage方法生成郵件客戶端。

IMessage message = MessageFactory.CreateMessage("incomingA"); 
messageA.ProcessMessage(); 

但是,我可以做到這一點的唯一方法是如果我將ProcessMessage()添加到IMessage。但是,如果我這樣做,那麼我必須在IOutgoingMessage中實現這一點。

現在,當我寫這個我看到,我可以擺脫IMessage ..應該我?或者有更好的方法來做到這一點?

+2

也許最簡單的解決這個問題的方法是兩種方法:'CreateInboundMessage'和'CreateOutboundMessage' –

+5

只需簡單提醒一下:接口**相互擴展**。 –

+1

我看到很多界面,但是我沒有看到它們背後的意圖。你想達到什麼目的? – zzzzBov

回答

4

根據您如何使用CreateMessage工廠,您預計ProcessMessage是所有IMessage類型的常用方法。根據您希望代碼的工作方式,我會說IMessage應該有一個ProcessMessage方法接口定義。

但是,在查看一小段代碼時,我認爲您的意圖不是總是處理消息,而只是在執行IIncomingMessage時才這樣做。所以你的工廠方法是不行的。 T. Kiley建議使用兩種工廠方法CreateInboundMessageCreateOutboundMessage可能會更有意義,因爲您對這兩種消息都有不同的行爲。然後這些方法將返回IIncomingMessage和'IOutgoingMessage`實例,然後您可以處理它們或相應地處理它們。

IMessage目前被用作標記接口。如果您看到這種需求 - 無論是對泛型的限制(例如MyCollection<T> where T : IMessage),然後保留它。但是,如果它沒有描述行爲或一組共同的屬性/方法,或者如果它不被用作有用的標記,那麼我不確定它提供了什麼好處。

此外,這是基於只看到一點點的代碼。我假設幕後有更多的行爲和功能。祝你好運!!

1

我會盡力給予此方案的另一個例子簡化:

public class Animal 
{ 
    void Run(); 
} 

public class Giraffe : Animal 
{ 
    void ExtendNeck(); 
} 

public class Monkey : Animal 
{ 
    void EatBanana(); 
} 

現在是好的,如果我現在添加EatBanana()Animal?如您注意到自己,並非所有IMessage執行者ProcessMessage()和在此示例中並非所有動物EatBanana()。什麼是另一種完成你想要做的事情的方式?只有使用IMessage時,如果您有共同的功能可以在您的課程中共享。如果你沒有,就不需要接口。記住YAGNI。如果有共同的功能,您可以稍後添加它。如果你想創建一個IncomingMessage並且調用IncomingMessage特定的方法,那麼只需創建一個強類型的IncomingMessage並使用它。您甚至可能不需要靜態工廠方法。

0

您可以使用不同的類,它們不會繼承任何東西並且完全分離過程。如果你這樣做,你會在這種情況下喪失使用子類化的幾個優點。它們之間可能有類似的屬性,如果它們都擴展了一個普通的類,那麼它們可以更容易地引用一個和另一個。至於這些子類的方法問題,您可以簡單地讓父類聲明一個通用方法(我們稱之爲ProcessMessage()),並簡單地讓每個子類覆蓋此類方法的行爲。這樣你就不需要不同的方法,只需要兩個不同的定義。簡單的多態概念。

0

(假定 'MessageFactory.CreateMessage( 「incomingA」)' 返回類型IIncomingMessage的對象)

要麼使用VAR

var message = MessageFactory.CreateMessage("incomingA"); 
message.ProcessMessage(); 

或鑄造的結果

IMessage message = MessageFactory.CreateMessage("incomingA"); 

    if (!(message is IIncommingMessage)) 
     throw new InvalidOperationException(); 

    (message as IIncommingMessage).ProcessMessage(); 
+0

雖然這種方法可行。我覺得這很醜陋。通過更好的設計,OP不必將這些類型的支票放在整個地方。 –

+0

我同意,但我只是想回答這個問題 - 不批評設計。 – tooslow