web-dev-qa-db-ja.com

複数のデフォルトメソッドを持つインターフェースORインターフェース+クラス

コードベースには、私が「出発点」として、多くのデフォルトのメソッドを持つ少数のインターフェースがあります。彼らはこのように見えます:

public interface HasXY {
   double getX();
   double getY();
   default double method1(double x, double y)  {...}
   default double method1(HasXY other)  {...}
   default double method2(double x, double y)  {...}
   default double method2(HasXY other)  {...}
   default double method3(double x, double y)  {...}
   default double method3(HasXY other)  {...}
   default double method4(double value)  {...}
   default double method5(double value)  {...}
}

現時点では、このコードをインターフェースとクラスにリファクタリングするオプションがあります。このリファクタリングの結果は、次のようになります。

public interface HasXY {
    XYPosition getXY();
}

public class XYPosition {
   double method1(double x, double y)  {...}
   double method1(XYPosition other)  {...}
   double method2(double x, double y)  {...}
   double method2(XYPosition other)  {...}
   double method3(XYPosition other)  {...}
   double method4(double value)  {...}
   double method5(double value)  {...}
}

「ソース」コードベースにはそのようなインターフェースがいくつかあり、多くのクラスがこれらのインターフェースのほんの一部を実装していることに注意してください(多くの多くのメソッドを持つオブジェクトにつながります)。私はまた、このリファクタリングをこれまで以上に簡単に行うことができる特別な瞬間にいます。

そのようなリファクタリングについてどう思いますか?スラムダンクは「すべき」ですか?時間の無駄だと思いますか? 「myObject.methodFromOneOfSeveralDifferentInterfaces()」を呼び出すことの簡潔さを失うため、それは実際に有害ですか?

4
Ivan

リファクタリングの意図はいいです。実装者から冗長性を取り除き、XYPosition関連のメソッドを独自のクラスにバンドルします。これは、多くのパラメーターを持つ関数を回避するためにパラメーターオブジェクトで行うのと同様です。クライアントが必要としないメソッドや使用しないメソッドについてクライアントに知らせてはならないというインターフェース分離原則に準拠している。

しかし、インターフェース(抽象化)は、コンクリーション(非抽象クラス)に依存すべきではありません。抽象化と具体化はどちらも抽象化に依存する必要があります。これは、依存関係逆転原理と呼ばれます。頻繁に変更されないもの(インターフェイス)は、頻繁に変更されるもの(実装)に依存するべきではなく、その逆です。したがって、私の提案は、XYPositionをインターフェイスにしてから、実装を具体的なXYPositionクラスに移動することです(別の名前を選択してください)。

5