タスク間で TaskKey を共有するには、どちらが優れていますか? 他に良い方法はありますか?
way1 はキー オブジェクトによって共有されます。このように、クライアント コード (タスク キュー) は、タスク テーブルを構成するために簡単に記述できます。ただし、すべてのタスクは、TaskKey オブジェクトを格納するためにメモリを浪費する必要があります。
class TaskKey {
int key1;
int key2;
// key3...
TaskKey(int key1, int key2) {
this.key1 = key1;
this.key2 = key2;
}
}
abstract class Task implements Cloneable {
TaskKey key;
int taskData;
Task(TaskKey key) {
this.key = key;
}
int getKey1() {
return key.key1;
}
int getKey2() {
return key.key2;
}
Task newInstance(int taskData) {
Task task = (Task) clone();
task.taskData = taskData;
return task;
}
abstract void doSomething();
}
class TaskQueue {
Task[][] taskTable;
void addTask(Task task) {
taskTable[task.getKey1()][task.getKey2()] = task;
}
void config() {
addTask(new Task(new TaskKey(1, 1)) {
void doSomething() {}
});
addTask(new Task(new TaskKey(1, 2)) {
void doSomething() {}
});
addTask(new Task(new TaskKey(2, 1)) {
void doSomething() {}
});
}
Queue<Task> queue;
void put(int key1, int key2, int taskData) {
Task task = taskTable[key1][key2];
queue.add(task.newInstance(taskData));
}
}
way2 タスククラスで共有。このように、クライアントコード(Task Queue)はタスクテーブルのconfigに書き込む(TaskのgetKey()メソッドをオーバーライドする)のが面倒です。ただし、すべてのタスクが TaskKey オブジェクトを格納するためにメモリを浪費する必要はありません。これは、キー情報が具体的な Task クラスによって共有されるためです。
abstract class Task implements Cloneable {
int taskData;
abstract int getKey1();
abstract int getKey2();
abstract void doSomething();
Task newInstance(int taskData) {
Task task = (Task) clone();
task.taskData = taskData;
return task;
}
}
class TaskQueue {
Task[][] taskTable;
void addTask(Task task) {
taskTable[task.getKey1()][task.getKey2()] = task;
}
void config() {
addTask(new Task() {
int getKey1() { return 1; }
int getKey2() { return 1; }
void doSomething() {}
});
addTask(new Task() {
int getKey1() { return 1; }
int getKey2() { return 2; }
void doSomething() {}
});
addTask(new Task() {
int getKey1() { return 2; }
int getKey2() { return 1; }
void doSomething() {}
});
}
Queue<Task> queue;
void put(int key1, int key2, int taskData) {
Task task = taskTable[key1][key2];
queue.add(task.newInstance(taskData));
}
}
別の方法1と方法2
interface TaskExecutor {
void exec(Task task);
}
class TaskKey {
int key1;
int key2;
int key3;
TaskExecutor executor;
}
class Task /*another way1*/ {
TaskKey key;
int taskData;// in fact it is not only a int
int getKey1() { // because i need to retrieve key1 from a task
return key.key1;
}
// also get methods for key2 key3
void exec(){
key.executor.exec(this);
}
}
class Task /*another way2*/ {
public final int key1;
public final int key2;
public final int key3;
private final TaskExecutor executor;
int taskData;
void exec(){
executor.exec(this);
}
}