2009-11-19 77 views
1

我需要爲現有接口添加一些新功能。項目中已經有很多類實現它,但其中一些不需要這些新功能。我的第一種方法是將新功能添加到現有接口並在各處實施,並在適用的地方添加無作用的功能等。但是現在我想知道是否有更好的方法來做到這一點。通過添加新接口而不是擴展現有接口來添加功能

舉個例子:

// 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; } 
} 

另一種選擇是創建一個新的界面,將只能通過定位波形流,如實施。 FileWaveform:

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

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

,並使用它像這樣:

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

注意,在這個方法我沒有強迫IPositionableWaveform也成爲IWaveformResource。

我想知道是否有比這更優雅的解決方案,在此先感謝。

回答

8

不幸的是,改變現有的界面是一個突破性的改變。

順便提一下,這是支持抽象類到接口的更強大的參數之一 - 使用抽象基類,您可以在不破壞API的情況下添加成員(使用默認實現)。

介紹第二個接口(從第一個接口繼承)可能是您最好的選擇。主要的變化我會做,從你描述的東西,是做:

public interface IWaveformResource : IAudioResource { ... } 

這種方式,很明顯,一個波形資源也是一個音頻資源。

3

如果不是所有實現接口的類都需要新的功能,那麼很可能它從來不屬於那個接口。