2017-07-26 81 views
0

我知道靜態方法對於接口不正確(請參閱:Why Doesn't C# Allow Static Methods to Implement an Interface?),但是遇到了一種情況,即我有一個對象實現接口的所有方法,其中所有方法都可以是靜態的,所以我想我一定是設計不當。替代接口的靜態方法

麻煩的是,我看不到任何替代

我的界面IDataSerializer是由幾個類實現的。一種是對XML進行反序列化,一種是JSON等。所有這些類都實現了相同的功能,而且沒有任何「狀態數據」(成員等),但最終都會導致輸出相同類型的對象。

例如,XML類:

public class MyXmlSerializer : IDataSerializer 
{ 
    public string SerializeFoo(object foo) 
    { 
     // uses .Net XML serialzer to serialize foo 
    } 

    public object DeserializeFoo(string foo) 
    { 
     // uses .NET XML serializer to deserialize foo 
    } 

    // Object type returned by above methods is only ever 
    // used by following method which returns a type available 
    // to all IDataSerializer implementations as this is 
    // the data actually used by the rest of the program 

    public IList<Bar> CreateBarList(object deserializedFoo) 
    { 
     // does some magic to extract a list of Bar from the 
     // deserialized data, this is the main work for any 
     // IDataSerializer implementation 
    } 
} 

顯然,上述所有所示的方法可以是靜態的(他們都採取在他們需要的技術參數的所有信息都將返回他們工作的結果,沒有成員或字段)...但是因爲它們應該在可以爲任何類型的串行數據(XML,JSON,YAML等)工作的串行器中實現,那麼它們將形成一個接口......這是什麼?我在想這個錯嗎?有沒有一種替代的,具體的模式來實現我想要做的事情?

有感:也許我應該簡單地改變我的德/序列化是工作的東西可以做到每個執行情況的思維是一個 serlializer,從而表明用抽象類取代接口想法?

事後回顧:重寫的方法也不能是靜態的,所以改爲抽象類沒有任何幫助。

+1

參見:[方法可以製造的S tatic,但應該嗎?](https://stackoverflow.com/questions/169378/method-can-be-made-static-but-should-it) – Corak

+2

確實,您的界面的所有方法都可以是靜態的,但它們不需要是靜態的。如果您將它們設置爲類「XmlSerializer」或「JsonSerializer」的靜態方法,您將失去依賴合約的好處並依賴於靜態類。添加新的Serializer類可能需要您在很多地方更改代碼。 –

+1

在你的例子的上下文中,使用單例將避免在接口中不允許靜態的問題,同時保留靜態引入的「一個實例」方法的精神。靜態和單身之間有區別,但它們似乎與您目前的情況無關。我知道你的問題更關注_why_靜態在任何情況下都不允許在接口中使用,但這是一個沒有結果的討論,這裏沒有人能夠改變它。 – Flater

回答

1

從邏輯的角度來看,這些方法應該是靜態的,因爲它們在邏輯上不適用於特定實例,並且不使用共享資源。該類也沒有狀態。但是......從實用主義角度來說,即時類帶來了很多好處,如:

  • 類(接口)如果完全可測試的,
  • 遵循OOP和SOLID原則,
  • 可以註冊爲單,所以你只能創建一個此對象的實例,
  • 很容易就任何相關性添加到這些類
  • 易於維護
  • 一些有用的設計模式可以應用(如裝飾,CO goaf作者:王金柱)
  • 可以延遲加載和設置在任何時候

在你的情況,在我看來,你應該隱藏在接口背後的實現,並將其註冊爲singleton,例如(使用autofac

builder.RegisterType<MyXmlSerializer>().As<IDataSerializer>().SingleInstance(); 

另外,如果需要,您可以爲此接口創建一個擴展方法,並將靜態方法添加到此合同中。

更多信息可以在這裏找到: