通过添加新接口而不是扩展现有接口来添加功能

Tra*_*rap 1 .net c# interface

我需要为现有界面添加一些新功能.项目中已经有很多类实现它,但其中一些不需要新的功能集.我的第一种方法是将新功能添加到现有接口并在任何地方实现,在适用的地方添加无操作功能等.但现在我想知道是否有更好的方法来做到这一点.

举个例子:

// Everything able to produce a waveform must implement this interface.
interface IWaveformResource
{
    int Collect( Stream _target, int _sampleCount );
}

// A waveform stored in a file
class FileWaveform : IWaveformResource
{
    public int Collect( Stream _target, int _sampleCount )
    {
        // ...
    }
}

// A sine waveform.
class SineWaveform : IWaveformResource
{
    public int Collect( Stream _target, int _sampleCount )
    {
        // ...
    }
}

// Added feature, we want to be able to specify the read position
interface IWaveformResource
{
    int Collect( Stream _target, int _sampleCount );
    int ReadOffset { get; set; }
}

class FileWaveform : IWaveformResource
{
    public int Collect( Stream _target, int _sampleCount )
    {
        // ...
    }

    // Moves the associated file pointer accordingly.
    int ReadOffset { get; set; }
}

class SineWaveform : IWaveformResource
{
    public int Collect( Stream _target, int _sampleCount )
    {
        // ...
    }

    // There's no point in setting or retrieving a sine wave's read position.
    int ReadOffset { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是创建一个新的接口,该接口只能由可定位的波形流实现,例如.FileWaveform:

interface IPositionableWaveform
{
    int ReadOffset { get; set; }
}

// A waveform stored in a file
class FileWaveform : IWaveformResource, IPositionableWaveform
{
    public int Collect( Stream _target, int _sampleCount )
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

private List<IWaveformResource> mResources;
public int ReadOffset
{
    set
    {
        foreach( IWaveformResource resource in mResources )
        {
            if( resource is IPositionableWaveform )
            {
                ((IPositionableWaveform)resource).ReadOffset = value;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在这种方法中,我并没有强制IPositionableWaveform也是IWaveformResource.

我想知道是否有比这更优雅的解决方案,提前感谢.

Ree*_*sey 8

不幸的是,改变现有界面是一个重大改变.

顺便说一句,这是支持抽象类接口的更强有力的参数之一 - 使用抽象基类,您可以添加成员(使用默认实现)而不会破坏API.

引入第二个接口(继承自第一个接口)可能是您的最佳选择.根据您的描述,我要做的主要改变是:

public interface IWaveformResource : IAudioResource { ... }
Run Code Online (Sandbox Code Playgroud)

这样,很明显波形资源也是一种音频资源.