我可以用来定义具有相同名称的方法的最佳设计是什么?

时间:2010-11-19 09:48:09

标签: c# .net oop design-patterns interface

有这样的设计问题。

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

示例:ClassA有这样的方法。

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);

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

  
      
  1. 我可以用什么方法来实现这个?
  2.   
  3. 我是通用接口的新手。这种情况有帮助吗?如果是这样,我将学习并实施它们。
  4.   

5 个答案:

答案 0 :(得分:8)

您可以在此处使用通用界面。一个例子:

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)  {  }
}

答案 1 :(得分:3)

如果你可以稍微改变你的设计,泛型会帮助你:

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

这不太适合你的例子,但非常接近。如果你不能做出这个改变那么我会说你的类不够相似,以至于他们有一个共同的界面是有意义的。

您还应注意,此设计与IDictonary或ILookup界面非常相似。也许您可以使用现有界面而不是创建新界面。

答案 2 :(得分:1)

public interface IInt<T> {
    void Add(T val);
    void Delete(string str);
    T GetInfo(string name);
}

答案 3 :(得分:0)

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

在此处阅读更多内容:http://www.objectmentor.com/resources/articles/srp.pdf

您还可以阅读这本关于一些设计原则的优秀书籍: http://cdn.cloudfiles.mosso.com/c82752/pablos_solid_ebook.pdf

答案 4 :(得分:0)

这个问题非常明确,但从我的理解中你有几种可能性 首先使用通用方法定义

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表达式的可能性是Endless。

此外,我提供了一个使用Action委托的实现。您可以轻松地将此代码转换为使用Expression类,通过该类可以在代码执行期间构建您自己的委托(并在初始化后缓存它们,因为它是一个非常缓慢的过程,即反射和填充。)我强烈建议滥用委托和表达式如果可能的话。

保重 卢卡斯