实现两个不同类的类似方法的最佳方法是什么?

时间:2015-10-01 19:41:16

标签: c# design-patterns

我有两个类(AB),它们在C#中实现了相同的接口(I)。该接口有5种方法可供实现。 AB中的两种方法的实现几乎相同,除了每个实现使用不同的变量。这是我班级的抽象布局。

class A : I
{
     Folder folder;
     void method()
     {
        //implementation uses ``folder``
     }

class B : I
{
     List list;
     void method()
     {
        //implementation uses ``list``
     }
}

因为Method的实现是相同的(除了一个参数),我想只实现一次Method。根据设计模式,最佳解决方案是什么?一个简单的选择是定义实现Method的第三个类,并获取一个参数(listfolder),然后在Method A内调用它}和B。还有其他解决办法吗?

------------ ---------------编辑

我不希望我的Method获得任何额外参数。在这种情况下,静态util类不是定义抽象类的更好选择吗?

3 个答案:

答案 0 :(得分:3)

您可以创建一个共享的抽象基类,该基类采用T泛型参数并实现I<T>。同样的T将传递给Method,它将在基类中实现:

public interface I<T>
{
    void Method(T t);
}

public abstract class Base<T> : I<T>
{
            public Base(T t)
            {
                  this.param = t;
            }

            private readonly T param;
    public void Method()
    {
        // Do stuff
    }
}

public class A : Base<Folder>
{
          public A(Folder folder) : base(folder)
          { }
}

public class B : Base<List>
{
          public B(List list) : base(list)
          { }
}

public class Folder { }
public class List { }

现在,你可以这样做:

static void Main()
{
    var a = new A(new Folder());
    a.Method();

    var b = new B(new File());
    b.Method();
}

答案 1 :(得分:0)

一种选择是使用抽象类而不是接口。当然这个类必须是通用的。

第二个选项是将方法提取到&#34;静态工具&#34;类和两者都使用这个&#34; utils&#34;。但这假设listfolder是相同接口的实例。

在我看来,第一个选项是最好的选择。

答案 2 :(得分:0)

如果方法的实现仅因变量的类型而不同,请考虑使用Template Method模式与通用基类相结合。

abstract class Base<T> : I
{
   public void method()
   {
       var items = GetItems();
       HandleItems(items);
   }

   protected abstract IEnumerable<T> GetItems();

   void HandleItems(IEnumerable<T> items)
   {
       // do something with a sequence
       foreach(var item in items) Console.WriteLine(item);
   }
}

class A : Base<FolderItem>
{
    Folder folder;

    protected overrides IEnumerable<FolderItem> GetItems() {return folder.Items;} 

}

class B : Base<ListItem>
{
    List list;

    protected overrides IEnumerable<ListItem> GetItems() {return list.Items;} 
}