2016-09-12 10 views
1

以下のようにJavaインターフェイスでメソッドをオーバーロードするのは正しいですか?そしてあなたのサブクラスで必要なメソッドを使用しますか?そうでない場合は、それを行うより良い方法があります、親切に提案してください。Javaインターフェイスのオーバーロードメソッド

interface IEmployees{ 
    public List<String> getEmployees(List<String> employees, List<String> departments); 
    public List<String> getEmployees(List<String> employees, String name); 
} 

class EmployeesByDept implements IEmployees{ 
    public List<String> getEmployees(List<String> employees, List<String> departments){ 
     // select employees belonging to depts in list and return. 
    } 
    public List<String> getEmployees(List<String> employees, String name){ 
     throw new UnsupportedOperationException(); 
    } 
} 

class EmployeesByName implements IEmployees{ 
    public List<String> getEmployees(List<String> employees, List<String> departments){ 
     throw new UnsupportedOperationException(); 
    } 
    public List<String> getEmployees(List<String> employees, String name){ 
     // select employees with name in list and return. 
    } 
} 
+0

"それは正しい"とはどういう意味ですか? – Mena

+0

メソッドの1つだけが許可されている場合は、インターフェイスを2つに分割します。それ以外に、インターフェイスが1つのクラスで実装されているメソッドを1つしか持たない場合は、そのインターフェイスが必要かどうかを自問するかもしれません。 – Thomas

+0

表現する 'IEmployees' *とは何ですか?答えは本当にそれに依存します。それは:1a)すべての既知の従業員のリスト、1b)知られているすべての従業員の任意のサブセット、または2)従業員を持つ組織ですか? –

答えて

0

まあ、はい、いいえ、それは依存します。

一般的に、適切な場合には、ほとんどの場合それが確かに存在します。

あなたのケースでは、はおそらくではありません。多くの問題がより根本的な設計上の問題になります。だから、それが表示され、あなたのスニペットを読み取ることによって、可能性はIEmployeesであることを、次のとおりです。

  1. システム内のすべての従業員のセット(例えば、会社のプロジェクトやのために働くすべての従業員)、または
  2. 従業員の任意のリスト(1を含むだけでなく、例えば、検索結果など、セマンティックList<Employee>の同等、または
  3. 例えば、それに関連する従業員のリスト(プロジェクトを有する構築物、又は組織)。

しかし、あなたは言う:

実際には従業員フィルタクラスです。これは他のフィルタクラスに継承され、インタフェース内のオーバーロードされたメソッドのいずれかを実装します。

最初の小さな問題はインターフェイス名自体です。 IEmployeesは空中にたくさん残っていますが、名前を付け加えると、さらに自己記述的で説明的なものになります。 IEmployeeFilter、物事がもう少し明らかに一緒に来始める。おそらく従業員名

  • することにより、部門
  • ことで

    • 他人
    :だから

    今あなたは、「フィルタ」を持っており、あなたが複数の独立したフィルタ戦略を持ってしようとしている表示されます

    これらは個別のフィルタであり、インターフェイスにはというフィルタが定義されています。したがって、は、より適切に2つの別々のサブクラスとして構成されます

    だからまずすべてのインターフェイスはである必要があります。すべてのフィルタに共通するものはです。フィルタリングがどのように行われるかは、一般的な側面ではありません。フィルタリング自体はです。したがって、次の点を考慮してください:

    interface IEmployeeFilter { 
        public List<String> getEmployees (List<String> employees); 
    } 
    

    フィルタは意味があり、1つの一般的な方法があります。:

    class EmployeeNameFilter implements IEmployeeFilter { 
    
        private String name; 
    
        public EmployeeNameFilter (String name) { 
         this.name = name; 
        } 
    
        @Override 
        public List<String> getEmployees (List<String> employees) { 
         return employees filtered appropriately 
        } 
    
    } 
    

    そして:

    class EmployeeDepartmentFilter implements IEmployeeFilter { 
    
        private List<String> departments; 
    
        public EmployeeDepartmentFilter (List<String> departments) { 
         departments = new ArrayList<String>(departments); 
        } 
    
        @Override 
        public List<String> getEmployees (List<String> employees) { 
         return employees filtered appropriately 
        } 
    
    } 
    

    は次に使用すると、1つのインターフェイスを使用する準備ができているときは常に同じです:

    List<String> employees = ...; 
    IEmployeeFilter filter = new EmployeeNameFilter("bob"); // or... 
    // IEmployeeFilter filter = new EmployeeDepartmentFilter(...); 
    
    List<String> results = filter.getEmployees(employees); // <- interface always the same 
    

    ポイントは、インターフェイスは、ツールとして存在しています仕事を楽にする。そのインターフェースを実装しているクラスがたくさんあるが、それらがすべて異なる部分を実装している状況に遭遇すると、インターフェースの目的を打ち始めることになり、基本的な変更が必要であるという良いヒントですあなたのデザインで作ることができます。

    つまり、より一般的な経験則は、次のようになります。インターフェイスが仕事を困難にしている場合や、コードを複雑にする場合は、何か問題があります。それ以外の場合は、何か正しいことをしています。意味を成し

    希望。

  • +0

    さらに別のオプションは、単一の従業員の合格/不合格基準を定義するインターフェイスです。 'インターフェースのフィルター{public boolean isAcceptable(String employee); } 'など、他の場所では、リストをループして結果リストを作成することでそれを適用するメソッドを持つことができます。 'publicリスト filterEmployees(リスト従業員、フィルターフィルター){...}'。 –

    2

    私の意見では、インタフェースをこのようにオーバーロードすると、は、実装クラスで不要な/無駄なコードが生成されるので、良い考えではありません。

    従って私はあなたがきれいにあなたのケースに一致するインターフェイスを実装することができますので、

    interface IEmployees { 
    } 
    
    interface IEmployeesByDept extends IEmployees { 
        public List<String> getEmployees(List<String> employees, List<String> departments); 
    } 
    
    interface IEmployeesByName extends IEmployees { 
        public List<String> getEmployees(List<String> employees, String name); 
    } 
    

    この方法のように2つのまたは3の異なるインターフェースを書くことをお勧めします。

    +0

    これは、アプリケーションにとって適切な場合には、別の良い戦略です(例:派生フィルタは、カテゴリごとに複数の実装を持つ「名前別」と「部門別」という一般的なカテゴリに分けることができます)。 ! –

    +1

    空の 'IEmployees'はここでは必要ないかもしれないと主張するかもしれませんが(あなたはそれをどうしますか?)、特定のインターフェースの名前は、とにかく1つだけの実装があるかもしれないことを示しています。 (特定のインタフェースの複数の実装がないと仮定して)実装自体 – Thomas

    0

    あなたのユースケースは、契約を表し、すべての

    アン界面における界面の使用を保証するものではありません。契約書には2つの要件を満たすことができると定義されています。 の場合は、契約の両方の部分を提供することはできません。インターフェースをまったく使用しないでください。

    はまた、私は強く、あなたが代替的な方法これらの従業員のリストを取得するを持っているもう一つの理由インタフェースを使用しないを疑います。

    代替ソリューション

    私はあなたのIEmployeesXXXクラスが何の状態変数を持っていない推測しています。これは、メソッドがオブジェクトのリストを取得して返すユーティリティメソッドであることを示す良い指標です。

    は、あなたはそれ古典的なユーティリティクラス、すなわちabstract final classstatic方法で行う必要があります。ここで

    は、独自のコードを使用した例ですが、ウィッヒはクリーナーくらいになった:

    public abstract final class Employeesutility{ 
        public static List<String> getEmployees(List<String> employees, List<String> departments){ 
         // select employees belonging to depts in list and return. 
        } 
        public static List<String> getEmployees(List<String> employees, String name){ 
         // select employees with name in list and return. 
        } 
    } 
    

    注意事項は、私は非常にユーティリティクラスを好きではない、私はむしろ豊かで、中間クラスになるだろう前方

    を行きます内部表現、および提案されたインタフェースメソッドを公開する豊富なコレクションが含まれています。しかし、あなたのユースケースでは、これはおそらくDB全体を複製していることを意味します(あなたが持っていると推測します)。真の従業員クラスを作成することを決定した場合は、それを考慮してください。

    関連する問題