如何在不杀死C#中的OOPS的情况下重构以下代码

时间:2013-01-18 09:56:50

标签: c#

我有3个接口,其中2个方法各自执行相同的工作。

Interface A
{
   Void M1()
   Void M2()
}

Interface B
{
   Void M1()
   Void M2()
}

Interface C
{
   Void M1()
   Void M2()
}

现在,有3个类实现了这些接口。

Public Class A1:A
{
  Public void M1()
  {

  }
  Public void M2()
  {

  }
}

Public Class B1:B
{
  Public void M1()
  {

  }
  Public void M2()
  {

  }
}

Public Class C1:C
{
  Public void M1()
  {

  }
  Public void M2()
  {

  }
}

M1和M2的功能在3个类中完全相同。接口是库的一部分,我无法更改接口,也无法声明新接口。

我想重构此代码,以便可以删除此重复项。我想到创建一个包含此功能的公共类,然后从每个类中调用公共类。

请建议。

5 个答案:

答案 0 :(得分:2)

听起来你应该声明自己的接口,然后创建一个适配器 - 或者可能是多个适配器。例如:

public interface IUnified
{
    void M1();
    void M2();
}

public class UnifiedAdapter : IUnified
{
    private Action m1;
    private Action m2;

    public UnifiedAdapter(A a)
    {
        m1 = () => a.M1();
        m2 = () => a.M2();
    }

    public UnifiedAdapter(B b)
    {
        m1 = () => b.M1();
        m2 = () => b.M2();
    }

    public UnifiedAdapter(C c)
    {
        m1 = () => c.M1();
        m2 = () => c.M2();
    }

    public M1()
    {
        m1();
    }

    public M2()
    {
        m2();
    }
}

(这使用委托来避免创建多个适配器类。最好的方法取决于您的具体情况。)

答案 1 :(得分:0)

public class BaseClass : A, B, C
{
   public void M1()
   {    
   }

   public void M2()
   {    
   }
}

然后继承BaseClass:

public class A1 : BaseClass
{
}

public class B1 : BaseClass
{
}

public class C1 : BaseClass
{
}

A1仍将实施接口AB1将实现接口B。与C1相同。因此,您现有的所有代码都将继续有效:

A a = new A1();
a.M1();

答案 2 :(得分:0)

public abstract class XX : X
{
    public void M1()

    {

    }

    public void M2()
    {

    }
}

public interface X : A, B, C
{
}

答案 3 :(得分:0)

考虑到奇怪的限制(如果你真的可以建议尝试改变接口),我认为这是你能做到的最好的:

public class Base : A, B, C {
  public void M1(){}
  public void M2(){}
}

现在从A1,B1和C1继承Base。

但是,如果A不能或不应该是B,那么此模式将不起作用。

因此,您确实必须选择下一个最好的东西 - 具有共同功能的共同基础:

public class Base {
  protected void M1Impl() { /* put your common implementation in here */ }
  protected void M2Impl() { /* put your common implementation in here */ }
}

正如评论所说 - 将重复的M1M2代码放在M1ImplM2Impl方法中。

现在,您可以为ABC实施重用此基础:

//common base for any implementation of A
//repeat for B and C
public class A1Base : Base, A
{ 
  public void M1() { M1Impl(); }
  public void M2() { M2Impl(); }      
}

public class A1 : A1Base { }

我在此基础上工作,您可能有许多AB或其他任何实现,因此您需要为每个实现一个共同的起点。如果情况并非如此,那么您可以取消A1Base,只需将其称为A1

答案 4 :(得分:0)

如果您只想避免复制这些方法的实现,那么您的初始方法是正确的。

public class HelperClass
{
   public static void M1()
   {
      // implementation code
   }
   public static void M2()
   {
      // implementation code
   }
}

public class A1:A
{
   public void M1()
   {
       HelperClass.M1();
   }
   public void M2()
   {
       HelperClass.M2();
   }
}

public class B1:B
{
   public void M1()
   {
       HelperClass.M1();
   }
   public void M2()
   {
       HelperClass.M2();
   }
}

public class C1:C
{
   public void M1()
   {
       HelperClass.M1();
   }
   public void M2()
   {
       HelperClass.M2();
   }
}

即使接口A,B和C具有相同的方法,它们也可能具有不同的语义,并且将它们作为单独的接口可能是有意义的。也就是说,制作类实现A可能意味着与实现B不同,即使它们的方法具有相同的签名。

添加额外的接口或公共基类是过度的,并增加了不必要的耦合。正如我之前所说,如果你只需要避免重复方法的实现,那么帮助类是最简单,最干净的解决方案。