2017-07-26 85 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(); 

另外,如果需要,您可以为此接口创建一个扩展方法,并将静态方法添加到此合同中。

更多信息可以在这里找到: