sharing information among objects
<p>To share TaskKey among Tasks, which one is better? Are there other better way?</p>

<p>way1 share by a key object.In this way, The client code(Task Queue) is easier to write to config the task table. But every task has to waste memory to store the TaskKey object.</p>

<pre><code>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&lt;Task&gt; queue;
    void put(int key1, int key2, int taskData) {
        Task task = taskTable[key1][key2];
        queue.add(task.newInstance(taskData));
    }
}
</code></pre>

<p>way2 share by the task class.In this way, The client code(Task Queue) is troublesomely to write to config the task table(to override the getKey() method of Task). But every task do not need to waste memory to store the TaskKey object, because the key information are shared by the concrete Task class.</p>

<pre><code>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&lt;Task&gt; queue;
    void put(int key1, int key2, int taskData) {
        Task task = taskTable[key1][key2];
        queue.add(task.newInstance(taskData));
    }
}
</code></pre>

<p>another way1 and way2</p>

<pre><code>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);
    }
}
</code></pre>
