Java | Comparator をクラス化してテスト可能にする実務パターン

Java Java
スポンサーリンク

では「複数の Comparator を戦略パターンとして切り替える実務例」を紹介します。これは、状況に応じてソートルールを差し替えたいときに便利です。


戦略パターンの考え方

  • Comparator を戦略(Strategy)としてクラス化
    → ソートルールを独立した部品にする。
  • 利用側は必要な Comparator を選んで適用
    → 「名前順」「年齢順」「部署順」などを切り替え可能。
  • テスト可能性
    → 各 Comparator を単体テストで検証できる。

サンプルコード

エンティティクラス

class Employee {
    private String department;
    private int age;
    private String name;

    public Employee(String department, int age, String name) {
        this.department = department;
        this.age = age;
        this.name = name;
    }

    public String getDepartment() { return department; }
    public int getAge() { return age; }
    public String getName() { return name; }

    @Override
    public String toString() {
        return department + " - " + age + " - " + name;
    }
}
Java

戦略パターン用 Comparator クラス群

import java.util.Comparator;

// 名前順
class NameComparator implements Comparator<Employee> {
    @Override
    public int compare(Employee e1, Employee e2) {
        return e1.getName().compareTo(e2.getName());
    }
}

// 年齢順
class AgeComparator implements Comparator<Employee> {
    @Override
    public int compare(Employee e1, Employee e2) {
        return Integer.compare(e1.getAge(), e2.getAge());
    }
}

// 部署順 → 名前順
class DepartmentComparator implements Comparator<Employee> {
    @Override
    public int compare(Employee e1, Employee e2) {
        int dep = e1.getDepartment().compareTo(e2.getDepartment());
        if (dep != 0) return dep;
        return e1.getName().compareTo(e2.getName());
    }
}
Java

利用側(戦略切り替え)

import java.util.*;

public class StrategySortExample {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("Sales", 30, "Tanaka"),
            new Employee("HR", 25, "Sato"),
            new Employee("Sales", 25, "Suzuki"),
            new Employee("HR", 30, "Kato"),
            new Employee("Sales", 30, "Ando")
        );

        // 戦略を切り替えてソート
        System.out.println("=== 名前順 ===");
        employees.stream().sorted(new NameComparator()).forEach(System.out::println);

        System.out.println("\n=== 年齢順 ===");
        employees.stream().sorted(new AgeComparator()).forEach(System.out::println);

        System.out.println("\n=== 部署→名前順 ===");
        employees.stream().sorted(new DepartmentComparator()).forEach(System.out::println);
    }
}
Java

実行例(出力イメージ)

=== 名前順 ===
Ando - Sales - 30
Kato - HR - 30
Sato - HR - 25
Suzuki - Sales - 25
Tanaka - Sales - 30

=== 年齢順 ===
Sato - HR - 25
Suzuki - Sales - 25
Ando - Sales - 30
Tanaka - Sales - 30
Kato - HR - 30

=== 部署→名前順 ===
HR - 25 - Sato
HR - 30 - Kato
Sales - 25 - Suzuki
Sales - 30 - Ando
Sales - 30 - Tanaka

実務メリット

  • 柔軟性: ソートルールを簡単に切り替え可能。
  • テスト容易性: 各 Comparator を単体テストで検証できる。
  • 拡張性: 新しいソートルールを追加するだけで利用側は変更不要。
Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました