1

私は当初、列挙型 [タスクのリストを格納する] を API に渡す単一のチーム向けに設計されたコードを持っています。この API は、この列挙型の使用を他の多くのクラスに伝達します。

現在、このコードを複数のチームで使用する必要があるタスクがあり、それらは列挙型の形式で独自のタスク セットを渡すことができます。

現在の実装を考えると、列挙型は他の列挙型を拡張できないため、コードを完全にオーバーホールする複数のチームをサポートすることは現実的ではないと思います。

大規模な変更なしでこれを実装する方法はありますか?

4

4 に答える 4

3

しかし...列挙型はインターフェースを実装できます。次に例を示します。

public interface Task {
    int getPriority(); // just for example
    // plus whatever methods define a task
}

public enum Team1Task implements Task {
    Task1(1),
    Task2(3);
    private final int priority;
    private Team1Task(int priority) {
        this.priority = priority;
    }
    public int getPriority() {
        return priority;
    }
}

これで、Java ジェネリック カンフーを使用して、適切な列挙型にバインドされたジェネリック パラメータを指定できます。

public class TaskProcessor<T extends Enum<T> & Task> {
    public void process(T task) {
        // do something with task
    }
}

使用するには:

TaskProcessor<Team1Task> p = new TaskProcessor<Team1Task>();
p.process(Team1Task.Open); // will only accept a Team1Task instance

参考までに、ジェネリックの好奇心として、代わりにこの境界を使用して同じことを達成できます。

public class TaskProcessor<T extends Enum<? extends Task>> {

実際の効果に違いは見られませんが、上で結ばれた交差点の明快さと見慣れたパターンに欠けていることがわかります。詳細については、この質問を参照してください。

于 2013-02-08T13:24:51.193 に答える
2

列挙型を一般的に回避する作業の多くを行うのは比較的簡単です。

これは、大幅に削減された例です。定義型としてTableを取る汎用データベースクラスを定義します。enum Columnは、テーブル内のenum列を定義します。定義型はenum、非常に便利なトリックであるインターフェースも実装する です。

public class Table<Column extends Enum<Column> & Table.Columns> {
  // Name of the table.
  protected final String tableName;
  // All of the columns in the table. This is actually an EnumSet so very efficient.
  protected final Set<Column> columns;

  /**
   * The base interface for all Column enums.
   */
  public interface Columns {
    // What type does it have in the database?
    public Type getType();
  }

  // Small list of database types.
  public enum Type {
    String, Number, Date;
  }

  public Table(String tableName,
               Set<Column> columns) {
    this.tableName = tableName;
    this.columns = columns;
  }

}

次のようなものを使用して、実際のテーブルを作成できます。

public class VersionTable extends Table<VersionTable.Column> {

  public enum Column implements Table.Columns {
    Version(Table.Type.String),
    ReleaseDate(Table.Type.Date);

    final Table.Type type;

    Column(Table.Type type) {
      this.type = type;
    }

    @Override
    public Type getType() {
      return type;
    }
  }

  public VersionTable() {
    super("Versions", EnumSet.allOf(Column.class));
  }
}

これは本当に些細な例ですが、少し手を加えるだけで、多くのenum作業を親クラスに簡単に移動できることに注意してください。

この手法は、ジェネリックを使用するときに取得するタイプ セーフ チェックを保持します。

于 2013-02-08T13:10:18.870 に答える
1

列挙型はインターフェイスを実装できます。タスクに適した適切なインターフェースを考え出すことをお勧めします。列挙型にインターフェイスを実装させると、コードは引き続き正常に機能します。他のチームは、必要なインターフェイスの実装 (独自の列挙型またはその他) を使用できます。(注意してください、コードがなければ、非常に明確な推奨事項を作成するのは困難です)。

于 2013-02-08T13:26:26.037 に答える
0

おそらくこれに列挙型を使用するべきではありませんが、必要に応じて、ヘルパークラス、または相互に拡張するクラスのセットにロジックを実装し、列挙型をその周りの薄いラッパーにすることができます。

public enum MyTaskEnum {
    A, B, C;

    private final TaskEnumHelper helper = new TaskEnumHelper();

    public void foo (int x, int y)
    {
        helper.foo (x, y);
    }
}
于 2013-02-08T12:52:47.683 に答える