2010-11-01 52 views
2

我有一種情況,我有2 Activity個對象(比如空的和計劃的活動,不受我控制)共享一些行爲,例如預訂活動的人員,活動發生的房間,活動類型,主題等正確使用實現而不是抽象或更改實現?

我創建了有一個超類ActivityWrapper實現一些常見的兩種孩子的方法和對孩子的包裝一些抽象的方法/屬性作出相應的反應兩個包裝器對象(EmptyWrapperScheduledWrapper)。他們在行爲上非常相似,但有一個至關重要的區別,你只能安排活動,如果它是空的插槽!該結構是這樣的(非常簡單的代碼):

public class EmptyWrapper : AppWrapper 
{ 
    EmptySlot _emptySlot;   

    public EmptySlotWrapper(EmptySlot emptySlot) : base() 
    { 
     this._emptySlot = emptySlot; 
    } 

    public override string Id 
    { 
     get { return _emptySlot.AgendaId; } 
    } 

    public override string Room; 
    { 
     get{ return _emptySlot.Room;} 
    } 

    public override string Person 
    { 
     get{ return _emptySlot.Person;} 
    } 

    public override string AppType; 
    { 
     get{ return "Empty";} 
    } 

    public override bool IsAppSlot() 
    { 
     return false; 
    } 

    public override bool IsEmptySlot() 
    { 
     return true; 
    } 

    public override bool CanPerformOperations() 
    { 
     return true; 
    } 

    public void ReserveApp(ObjWithActivityInfo actObj) 
    { 
     (...)    
    } 
} 

ActivityWrapper相似,但纏的對象是不同的,在布爾變量爲IsAppSlot返回true,false爲IsEmptySlot和虛假的CanPerformOperations並沒有ReserveApp()方法。

其次是基類:

public abstract class AppWrapper 
{ 
    public abstract string Collaborator { get; } 
    public abstract string Room { get; } 
    public abstract string AppType { get;} 

    public AppWrapper() 
    { } 

    public abstract bool IsAppSlot(); 
    public abstract bool IsEmptySlot(); 

    public abstract bool CanPerformOperations(); 

    public virtual string GetTextToShow() 
    { 
     return Person + " - " + Room; 
    } 

    (...) 
} 

在我的代碼,我想引用僅ActivityWrapper,因爲對於一般的操作(顯示信息和外觀)我不需要的實現。當我需要爲空插槽預訂活動時,問題會增加。在這一點上,在我的代碼中,我將AppointmentWrapper轉換爲EmptyWrapper,併爲該活動預留了插槽(它仍然是一個EmptySlot,但它保留給選定的活動),否則,如果演員陣容不對,我什麼都不做因爲它不是正確的Activity類型。

這是正確的,還是應該在兩個包裝中實施ReserveActivity()方法,並讓ActivityWrapper什麼都不做?

或者我應該以另一種方式做到這一點?也許會改變類的結構?

對不起,長文字。

+0

哪裏是'AppointmentWrapper'? – 2010-11-01 13:04:44

+0

對不起:感謝錯誤提示。 – Jay 2010-11-01 14:44:01

回答

1

將函數添加到不需要它的類是毫無意義的。它會打敗你的繼承點。

我會做一個安全的投...

var i = obj as theClass 

,然後測試空。我將使用一些linq來選擇所有具有您定義屬性的對象,以指示它們設置爲true的類型。

可能做到這一點,並節省自己的演員和測試,但這意味着設計是不太明顯的外人。

我認爲它是一個品味的問題,但更喜歡你做它的方式。我不確定我喜歡bool屬性來確定類型。如果你再次繼承基類呢?除此之外,您還可以進行投射以確定類型 - 具有更深對象結構的類型可能更有用。

我同意你希望與抽象類的集合工作。

+0

我做了演員,這似乎是當時最好的方式,但它可能是一個更好的方法。當談到布爾屬性,我只是尋找一種快速的方式來確定包裝對象是否可以安排活動或不安排,沒有cast.That方式,我會忽略的情況下,用戶點擊一個已安排的活動。但它有點覺得時髦是啊...所以你認爲我最好是鑄造包裝? – Jay 2010-11-01 14:38:48

+0

是的definatley。我傾向於爲國際奧委會的原因編寫接口代碼 - 他們也傾向於解決當時我還沒有發現的問題。這裏的抽象類在功能上是一樣的(你實現了tostring,但除此之外它基本上是一個接口)。所以我認爲,嘗試投射的解決方案是可靠的 - 其技術對我而言效果很好。我不建議添加冗餘方法 - 這是可以肯定的,因爲它可能會讓任何試圖弄清楚發生了什麼的人感到困惑。我確實認爲這是一種風格的東西 - 我知道我和他一起工作的人會在這裏。 – 2010-11-01 23:34:39

+0

我會試試看這個包裝器。關於抽象類,就是這樣。我使用它,因爲我有一些方法可以用於活動對象的公共部分,否則它肯定會成爲一個接口。如果我可以抽象出這種行爲,我只是不喜歡在類中重複代碼的想法。 – Jay 2010-11-02 10:21:05

1

在我需要處理類似問題的幾種情況下,我傾向於認爲創建用於識別多個對象的常用函數的接口真的更加優雅,然後創建繼承類將實現的抽象方法你提到。

例如

public interface IAppSlotContainer 
{ 
    void relevant_Method_When_ObjectIsAppSlot(); 
} 

public interface IEmptySlotContainer 
{ 
    void relevant_Method_When_ObjectIsEmptySlot(); 
} 

public class EmptyWrapper : AppWrapper, IAppSlotContainer, IEmptySlotContainer 
{ 

public EmptyWrapper(EmptySlot emptySlot) : base() 
{ 
    this._emptySlot = emptySlot; 
} 

public override string Id 
{ 
    get { return _emptySlot.AgendaId; } 
} 

public void relevant_Method_When_ObjectIsEmptySlot() 
{ 
} 

public void relevant_Method_When_ObjectIsAppSlot() 
{ 
} 

}

然後,而不是覆蓋抽象方法「爲IsEmpty」和實現它爲「返回true」,只是檢查對象是否是IEmptySlotContainer的一個實例,它映射到該接口,並執行接口相關的命令。 這是更爲通用的,優雅的對我的口味......

希望這有助於...

+0

哼哼...我很喜歡它!我絕對會放棄! – Jay 2011-06-21 07:41:37