web-dev-qa-db-ja.com

インタビューの質問-何千ものクラスによって実装されているインターフェースにメソッドを追加する

何千ものクラスで実装されているInterface Xを使用しているシナリオがあります。ここで、そのインターフェイスXに新しいメソッドを追加したいと思います。つまり、すべてのクラスでメソッドのオーバーライドの問題を解決するために、最小限の方法で変更を加える方法です。

回答にJava 8のデフォルトメソッドを追加しないでください。

3
Atul

この状況で私が最初に試みることは、インターフェースの変更をまったく回避することです。元のインターフェースから派生した拡張インターフェースを追加し、新しいメソッドを追加して、「拡張インターフェース」タイプのオブジェクトを取得することを期待する新しいメソッドと組み合わせて、そのインターフェースをsesにするコードを作成できます。 。

それが不可能な場合、たとえば、利害関係のあるコードがコントロールの外にあるため、インターフェイスとすべての派生の間の継承階層に、新しいメソッドのデフォルト実装を持つ抽象クラスを追加できます。何千ものクラスの場合でも、コードベースに必要な変更は、グローバル検索/置換を使用して、または何かを壊すリスクの低い小さなスクリプトまたはヘルパープログラムを作成することによって、おそらく数時間で行うことができます。

このアプローチのどちらがより良いかは、コードベースのどの部分を実際に変更できるか、および「最小の方法」が実際に何を意味するかによって異なります。

12
Doc Brown

コメントは正しいです。本当に数千のクラスがあり、共通の基本クラスがない場合、それは最初に解決する必要があるコードのにおいです。共通のインターフェイスを共有するが、コードがまったくないクラスはまれです。

それ以外の場合は、ツールを使用します。たとえば、C#用のResharperは、インターフェイスを実装するすべてのクラスでそのメソッドを実際に実装するオプションを提供します。それは明らかに行われる作業の一部にすぎませんが、少なくともコンパイルはまだです。文字通り何千ものクラスの場合、独自のツールを作成することは、手動で行うよりも先に来ると思います。

2
nvoigt

これは私が業界で見た慣習です。

  • それらは、たとえばInterface2のように番号が付加された新しいインターフェースを作成し、これに古いインターフェースのメソッドを含めます。
  • 古いインターフェースを非推奨にする
  • 大幅な見直しが行われると、新しいパッケージが追加される可能性が高くなります(Java JDKがファイルとIO in nio)。これは、インターフェイスから数を削除し、別のパッケージに新しいインターフェイスを用意するときです

このアプローチでは、インターフェイスに新しいメソッドを使用できます。新しいインターフェイスを実装するさまざまな方法に非常に柔軟なソリューションを使用できます。

  • 既存のユーザーを壊すことはありません。
  • これは、古いインターフェースが廃止された後に実際に削除される前に、変更を統合および/または実験できるバッファー期間を提供します。
1
InformedA

コードを変更する方法を決定する前に、考慮すべきいくつかの問題があります。

サードパーティがこのインターフェイスを使用または実装するコードを作成した場合を考えてみましょう。これにより、必要なコード変更の管理の複雑さが大幅に増加するだけでなく、プロセスに政治的要素が追加され、他の企業の作業(およびコスト)が発生します。

このインターフェースはすでに多くのクラスで実装されているので、現在のインターフェースに変更を加えることに対する強力な指標です。この新しいインターフェイスメソッドのすべての実装への影響を考慮する必要があります。

これらのすべての実装がこの新しいメソッドを必要とせずに完了したという事実は、おそらくこれがこのインターフェイスの目的の核心ではないことを警告するフラグであり、これは独立しているため、新しい独立したインターフェイスとして実装する必要があります(ただし、関連する)オブジェクトの使用。独自のインターフェースが必要です。


つまり、このインターフェイスを使用するすべてのコードを制御すると仮定すると、新しいメソッドを明示的に実装するすべてのクラスに新しいメソッドを実装します。

例えば.

public class MyObject : ITheInterface
{
    public void ITheInterface.NewMethod(int age)
    {
        throw new NotImplemented("NewMethod needs to be implemented on MyObject");
    }
}

このようにメソッドを明示的に実装することにより、コードは、オブジェクトのITheInterfaceとして型指定された参照を使用している場合にのみ、新しい実装を呼び出します。

1
Michael Shaw

実装クラスをリファクタリングすることが許可されていない場合、2つの悪の小さい方は、メソッドをインターフェースに追加しないことです。既存のインターフェースとの互換性を壊す必要がある合理的な状況はありません。新しいメソッドは新しいインターフェイスに属し、それを使用する必要があるクラスはすべて新しいインターフェイスを実装する必要があります。おそらく、既存のインターフェースを実装するすべての1,000クラスが新しいメソッドを必要とするわけではありません。それらを強制すると、何トンもの空の実装になってしまいます。これは、コード。

あなたがこの質問に答えてしまう答えにかかわらず、私はあなたがこの会社で働きたいかどうか真剣に質問します。これが彼らにとって共通の関心事である場合、彼らは明らかに彼らが何をしているのか知らない。彼らが実際にこれらのタイプの問題を持っていない場合、彼らは無意味なインタビューの質問であなたの時間を無駄にしています。これから良いものは生まれません。

0
computerGuyCJ