代码之家  ›  专栏  ›  技术社区  ›  Chathuranga Chandrasekara

定义同名方法时可以使用的最佳设计是什么?

  •  5
  • Chathuranga Chandrasekara  · 技术社区  · 14 年前

    有这样的设计问题。

    假设您有一组实现类似方法但不相同方法的类。

    示例:类有这样的方法。

    void Add(string str);
    void Delete(string str);
    List<string> GetInfo(string name);
    

    另一个类,ClassB有以下方法。

    void Add(Dictionary Info);
    void Delete(string str);
    Dictionary GetInfo(string name);
    

    因此,这些方法的性质相似,但返回类型/输入参数不同。如果我开发一个保持一致性的接口,我只能在那里定义删除操作。另外,我可以考虑一组独立类,它们之间没有任何关系(当然没有接口实现),但我认为这不是一个好的设计。

    1. 我可以使用什么方法来实现这一点?
    2. 我不熟悉通用接口。在这种情况下有帮助吗?如果是这样,我将学习并使用它们。
    5 回复  |  直到 13 年前
        1
  •  8
  •   Cheng Chen    14 年前

    您可以在这里使用通用接口。一个例子:

    interface IModifiable<T>
    {
      void Add(T Info);
      void Delete(T item);
      T GetInfo(string name);
    }
    public class MyClass : IModifiable<List<string>>
    {
       public void Add(List<string> list)
       { 
          //do something
       }
    
       public void Delete(List<string> item)   {  }
       public List<string> GetInfo(string name)  {  }
    }
    
        2
  •  3
  •   Mark Byers    14 年前

    如果你能稍微改变一下你的设计,仿制药将对你有所帮助:

    interface IFoo<TKey, TValue>
    {
        void Add(TKey name, TValue value);
        void Delete(TKey name);
        IEnumerable<TValue> GetInfo(TKey name);
    }
    

    这并不完全符合您的示例,但非常接近。如果您不能进行这种更改,那么我会说您的类没有足够的相似性,以至于它们没有一个公共接口是有意义的。

    您还应该注意到,这种设计非常类似于IDicotory或iLookup接口。也许您可以使用现有的接口,而不是创建一个新的接口。

        3
  •  1
  •   Alex Lockwood Nigel Hawkins    13 年前
    public interface IInt<T> {
        void Add(T val);
        void Delete(string str);
        T GetInfo(string name);
    }
    
        4
  •  0
  •   jgauffin    14 年前

    我认为这些接口没有问题。但是,如果在同一个类中实现这两个接口,我确实会看到一个问题。这样做会打破单一责任原则。

    阅读更多信息: http://www.objectmentor.com/resources/articles/srp.pdf

    你也可以阅读这本关于一些设计原则的好书: http://cdn.cloudfiles.mosso.com/c82752/pablos_solid_ebook.pdf

        5
  •  0
  •   luckyluke    14 年前

    这个问题定义得很明确,但根据我的理解,你有几种可能性 首先使用泛型方法定义

    public void Detele<T>(T toDelete); //optional : where T 
    

    并在通用接口中定义它(如果是抽象类,则为抽象类)

    否则,一个非常古老但仍然完好的技术就是方法重载。可以使用相同的名称定义多个方法,但使用不同的参数。.NET在streamreader、toString等类中大量使用此模式

    从您提供的签名来看,您可能会发现它的用途。

    第三种选择(尽管更难编码)是使用lambda表达式。

    Add<T,P>(Action<T,P> addingAction, T source, P param) ( addingAction(source,param); );
    //this is naive p.Add(q) it can be arbitralily more complicated
    aObject.Add( (p,q) => p.Add(q), myObj, myParam);
    

    通过这种方式,您可以定义一个通用的添加操作,然后将其封装到对象中。我提供的签名很容易更改。另外,您可能不希望立即执行该操作,而是将其安排为延迟执行,或者异步执行。lambda表达式的可能性是无限的。

    另外,我还提供了一个使用操作委托的实现。您可以很容易地将此代码转换为使用表达式类,通过该类,您可以在代码执行期间构建自己的委托(并在初始化之后缓存它们,因为这是一个相当慢的过程,即反射和其他东西)。我强烈建议尽可能滥用委托和表达式。

    当心 乌卡斯

    推荐文章