Partager via


Mike chews me out for including optional operations on an interface

Mike, another dev on the C# took issue (aka slapped me around) with the way my current interface is being built.  He doesn't approve of an Add method that can possibly fail.  He thinks that if the interface declares it then it's something that should be expected to succeed in most cases.  There may be times when it could fail, but having a method be optional and then always fail seems like a bad smell to him.  Because of this he thinks I should refactor the interface into a ICollection interface which presents a non-mutable view over the elements (i.e. Contains, IsEmpty) and a IMutableCollection which extends ICollection and adds the mutating operations.  What do you think about that pattern?  Note: each opreation (Clear, Add, Remove) is independently optional.  So would i need IGrowableCollection, IShrinkableCollection, etc.?  I.e. I might have a collection that implemented Add, but didn't want to implement remove (like a Queue which only allowed removing of the head, not of arbitrary elements).

It seems to me that this explodes the interface hierachy immensely.  It also makes it difficult when you want to take an object that is an aggregate of many interfaces.  You could say:

void Foo<T>(T t) where T : IGrowableCollection, IShrinkableCollection

But this gets pretty unweildy fast.  Anyone have any pointers to work done in this area and the benefits/drawbacks they faced?

Comments

  • Anonymous
    May 17, 2004
    There's a similar question with our IOptional implementation - why does it include a Value property that is optional?
  • Anonymous
    May 17, 2004
    The comment has been removed
  • Anonymous
    May 17, 2004
    Jesse: could you explain this a little more? Where do i include this boolean value?
  • Anonymous
    May 17, 2004
    Jay: I agree. IOptional doesn't need Value. The code should have been:

    Some<A> some = reference.Target as Some<A>;
    if (some != null)
    {
    return some.Value;
    }
  • Anonymous
    May 17, 2004
    The comment has been removed
  • Anonymous
    May 17, 2004
    The comment has been removed
  • Anonymous
    May 17, 2004
    Cyrus, Stack is its own class because forcing its functionality into Queue would not make sense. Much like you introducing optional functionality into your base interface. Both Stack and Queue implement IColletion (among others) but are two separate classes, even though they differ in a single functionality.

    And yes, IGrowable with Add, IShrinkable with Remove and IYourCollection with whatever is going to be common and always implemented.
  • Anonymous
    May 17, 2004
    The comment has been removed
  • Anonymous
    May 17, 2004
    In CLR you can implement multiple interfaces, so in your case it would be:

    class MyClass: IClearable, IGrowable
    {
    }

    And I'm not saying extract every single optional piece into its own interface, just group them logicaly. Clearable interface would probably implement both Clear and Delete (where Delete would probably be inhereted from shrinkable interface).

    Just curious - could you go into a little detail how come all these operations are optional?
  • Anonymous
    May 17, 2004
    The comment has been removed
  • Anonymous
    May 17, 2004
    The comment has been removed
  • Anonymous
    May 17, 2004
    The comment has been removed
  • Anonymous
    May 18, 2004
    Hey if you want totally fine-grained classes, you could always build a class with delegates instead of methods. That way you could assign whichever methods you want on a class-by-class basis.
  • Anonymous
    May 18, 2004
    er, make that instance-by-instance basis
  • Anonymous
    May 18, 2004
    Damien: this is what I am doing with classes. However, do you have a recomendation on how to do this with the interface?
  • Anonymous
    May 18, 2004
    Brian: Argue all you want. The reason I'm blogging about this is because I am unsure what the best design choices are. In fact, I'm becoming increasingly convinved that there are no best design choices here, only a set of tradeoffs to be made.

    The reason I am doing this is because I'm unsastisifed with the current set of BCL collections (that were written by MS programmers). I find them almost always not meeting my needs (which in general refer to flexibility, extensibility and consistancy). Getting feedback and different opinions are necessary so that when I make choices I can understand the issues involved.

    Thanks a lot for your advice! I'll definitely be discussing it with Mike.
  • Anonymous
    September 02, 2005
    nice to be seen