views:

125

answers:

3

Lets say i have the following set of interfaces....

 public interface IStart
        {
            void M1();
            bool IsWorking { get; }
        }

    public interface IStartStop : IStart
        {
            void M2();
                   event EventHandler DoM1;
            event EventHandler DoM2;
        }
    public interface IPreferencesReader : IStartStop, IDisposable
        {
            string CustomColumnDefinition       {get;}
                bool UsePricelevelDetection  {get;}
            void InitializePreferences();
        }

Now, if i want to implement IPreferencesReader my class would look like below. This is an example of a fat interface, where i will have to provide implementation of methods that i may not need in all scenarious.

public class PreferencesReaderBase : IPreferencesReader
    {
        public void M1()
        {
            throw new NotImplementedException();
        }

        public bool IsWorking
        {
            get { throw new NotImplementedException(); }
        }

        public void M2()
        {
            throw new NotImplementedException();
        }

        public event EventHandler DoM1;
        public event EventHandler DoM2;

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public string CustomColumnDefinition
        {
            get { throw new NotImplementedException(); }
        }

        public bool UsePricelevelDetection
        {
            get { throw new NotImplementedException(); }
        }

        public void InitializePreferences()
        {
            DoSomeInitialization();
        }
    }

Can i apply any pattern for this scenario so as to refactor it?

EDIT: I can not do without this hierarchy, as in can not remove any of the interfaces.

Thanks for your interest.

+2  A: 

Hi,

You don't necessarily need to provide working implementations. In your sample it looks like your IPreferencesReader doesn't need IStartStop so can you simply remove the inclusion of it?

If you want to hide an interface method from an implementing type (ie, you won't see it on PreferencesReaderBase objects) you can implement the interface explicity:

void IStart.Start() { }

You will then only be able to call these interface methods by casting your PreferencesReaderBase references to IStart references.

Adam
Removed the working (real) code.About explicit implementation, that won't solve my problem. Since the interface still remains fat (asks for a lot of work at user side.)
Amby
Not really, they can implement the interface in the IDE with stubs that either return default values or throw exceptions. If they aren't meant to be used I would argue the exception are an adequate way to go. Your example doesn't show what interfaces are required and what interfaces aren't.
Adam
If the IStartStop interface isn't required, as I mentioned in my answer you could just remove it from the IPreferencesReader interface - unless it needs to be there for another reason.
Adam
@Adam: IStartStop is indeed needed, other part of the infrastucture controls these managers using start.stop.
Amby
Then the only thing I can suggest is to break down the classes into more classes, and define what situation they are to be used so that the relevant classes can have the interfaces on them. You could always place the interfaces on classes deriving PreferencesReaderBase instead of on the base class itself.
Adam
+1  A: 

I think you need to look into why you can't break up your interface heirarchy. You say the heirarchy is necessary, yet some classes will not need to implement all of the methods. This implies that the heirarchy should not be necessary!

If IPreferencesReader does not need to implement the M1 method, then it really isn't an IStart. The contract that it is making is an invalid one.

Remember that classes can inherit multiple interfaces. Assuming you break up the inheritance heirarchy, then if PreferencesReaderBase does IStop stuff but not IStart stuff, you can declare it as :

public class PreferencesReaderBase : IPreferencesReader, IStop

If for whatever reason you really can't split up this interface, you could consider splitting up the implementation classes.

class Start
{
  M1() 
  {

  }
}

class Stop
{
  M2()
  { 

  }
}

public class PreferencesReaderBase : IPreferencesReader
{
  private Start start = new Start();
  private Stop stop = new Stop()
  public void M1()
  {
      this.start.M1();
  }


  public void M2()
  {
      this.stop.M2();
  }
}

This would at least keep the main functional classes tidy. Each class does one thing, so the Single Responsibility Principle is maintained.

The fat interface class is then a just skeleton class that could then remain largely untouched through the development iterations.

Mongus Pong
+1  A: 

Use an "Adapter" pattern - not the one that wikipedia identifies, so maybe my terminology is non-standard - but like Java's MouseAdapter:

An abstract adapter class for receiving mouse events. The methods in this class are empty. This class exists as convenience for creating listener objects.

...

Extend this class to create a MouseEvent listener and override the methods for the events of interest. (If you implement the MouseListener interface, you have to define all of the methods in it. This abstract class defines null methods for them all, so you can only have to define methods for events you care about.)

Just write an abstract class that holds empty implementations of all the necessary interfaces; subclass it and override the methods that are relevant to your needs.

The full fat interface still exists; it's still implemented (via inheritance) by your class - but the code of your class will only include what's important.

Carl Manaster