2

私は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つのクラスでまったく同じです。インターフェイスはライブラリの一部です。インターフェイスを変更したり、新しいインターフェイスを宣言したりすることはできません。

この重複を削除できるように、このコードをリファクタリングしたいと思います。この機能を含む共通クラスを作成し、これらの各クラスから共通クラスを呼び出すことを考えました。

提案してください。

4

5 に答える 5

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

(これは、デリゲートを使用して、複数のアダプター・クラスを作成する必要をなくします。最良のアプローチは、正確な状況によって異なります。)

于 2013-01-18T10:00:42.473 に答える
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();
于 2013-01-18T10:02:30.757 に答える
0
public abstract class XX : X
{
    public void M1()

    {

    }

    public void M2()
    {

    }
}

public interface X : A, B, C
{
}
于 2013-01-18T10:03:38.103 に答える
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 */ }
}

コメントが言うように-ここのandメソッドに複製さM1M2たコードを入れてください。M1ImplM2Impl

Aこれで、このベースを、BおよびC実装に再利用できます。

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

私はここで、AまたはBまたは何かの多くの実装がある可能性があることに基づいて作業しました。したがって、それらのそれぞれに共通の開始点が必要です。そうでない場合は、それを廃止しA1Baseて単に呼び出すことができますA1

于 2013-01-18T10:04:10.460 に答える
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を実装することとは異なることを意味する場合があります。

追加のインターフェースまたは共通基本クラスを追加することはやり過ぎであり、不要な結合を追加します。前に述べたように、メソッドの実装の重複を避ける必要があるだけの場合は、ヘルパークラスが最も簡単でクリーンなソリューションです。

于 2013-01-18T12:33:52.757 に答える