0

全て、

うまくいけば、簡単な質問です。多数のコレクションと HashMaps を保持するクラスを実装する最良の方法を考えています。クラスは、クラス外でいつ変更されたかを知る必要があります。つまり、アイテムの追加/削除/変更です。現時点では、各コレクション/ハッシュマップをクラスのパブリック ゲッターとして公開する必要があります。

したがって、私の基本的なクラスは次のようになります...

public class MyClass {

    protected final HashMap<String, String> _values = new HashMap<String, String>();
    protected final ArrayList<MyOtherClass> _other = new ArrayList<MyOtherClass>();
    protected final ArrayList<MyOtherClass2> _other2 = new ArrayList<MyOtherClass2>();

    // ... implementation


    public HashMap<String, String> getValues() {
        return _values;
    }

    public ArrayList<MyOtherClass> getMyOtherClassList() {
        return _other;
    }

    public ArrayList<MyOtherClass2> getMyOtherClassList2() {
        return _other2;
    }

    public String getContent() {
        // build the content based on other/other2...
        StringBuilder sb = new StringBuilder();
        // iterate through both collections to build content...
        // ...
        return sb.toString();
    }
}

public getMyOtherClass {
    public String name;   // has getter and setter
    public String value;  // has getter and setter
}

public getMyOtherClass2 {
    public String name;   // has getter and setter
    public String value;  // has getter and setter
    public String somethingElse;  // has getter and setter
}

コンテンツの長さに基づいて _values にキー/値を追加したい

_values.add("Length", getContent().length);

したがって、長さの値は、_other および _other2 に追加される内容に基づいて動的になります。

これに関する問題は、_values と _other を public getter で公開することであり、クラス外の何かがそれらを変更できることです。クラスは、アイテムが変更されたかどうかを知りません。

私が考えることができるいくつかの解決策は、コレクション/ハッシュマップを読み取り専用にすることです-しかし、これは実行時例外をスローします-この場合、コンパイラーにそれらが読み取り専用であることを示して例外をスローさせたいのですが、私はしませんこれが可能かどうかはわかりません。

もう 1 つの方法は、コレクション/マップごとに追加/削除を追加し、それに応じて Length プロパティを更新することです。ただし、MyOtherClass で値が変更された場合でも、MyClass はそれを認識しません。

または、独自の Hashmap/List/Collection を作成して、アイテムがいつ追加/削除されたかを判断し、getMyOtherClass、getMyOtherClass2 にプロパティ変更リスナーを設定することもできます。

これに対する良い解決策はありますか?

ありがとう、

アンデス

4

3 に答える 3

1

実装をオーバーライドし、親で更新関数をトリガーするメソッドmap/listにコールバックを挿入します。 また、実装への参照を直接作成するのは悪い形式です - これはより良いです (推論のためにポリモーフィズムを読んでください):add/update/remove

private Map<String,String> myMap = new HashMap<String,String>();
private List<String> myList = new List<String>();
于 2012-08-17T12:23:05.480 に答える
1

この場合、Observerデザイン パターンのいくつかの基本を利用して、オブジェクトにマップを「監視」させ、マップに加えられた各変更を登録することができます。

Map と List を含む別のオブジェクトを含むオブジェクトを作成すると、1 つのマップと 2 つのリストがあるため、これらの「観測可能な」オブジェクトが 3 つあることになります。クラスに「ObservableMap」と「ObservableList」という名前を付けましょう。抽象クラス「ObservableObject」を作成して、前述のクラスで拡張することもできます。

これらのオブジェクトは Map/List 実装をオーバーライドしません。追跡するメソッドをラップして状態を登録し、コレクションを変更するための呼び出しを派生させることによって、ラッパーとしてのみ機能します。たとえば、ObservableMap クラスのコードをいくつか投稿します (マップをインスタンス化して<String,String>いますが、必要に応じてここでもジェネリックを使用できます)。

public Class ObservableMap extends ObservableObject{
    private Map<String,String> map = new LinkedHashMap<String,String>();
    private Watcher observer = new Watcher();

    //Example of one of the wrapper methods (the other ones are like this one)
    public void putObject(String key, String value) {
        watcher.notifyPut(); //You can name the method the way you like and even pass
                             //the new key/value pair to identify what has been added.
        map.put(key,value);
    }
}

ここで、Watcher クラスは、変更を登録するクラスです。これは完全に新しいオブジェクト (この場合のように) にするか、インターフェイスを作成して既存のクラスに実装し、Observable オブジェクトのウォッチャーとして設定できるようにすることができます。

于 2012-08-17T12:36:24.890 に答える
0

あなたが何を求めているのか100%確信が持てません。他の人が言及したように、属性への変更を2つのクラスに追跡しようとしている場合は、オブザーバーパターンを実装し、set メソッドで通知を発生させます。元に戻すメカニズムの実装に成功した別の方法は、aspectJ またはその他の AOP (アスペクト指向プログラミング) ツールを使用して、設定されたメソッドをインターセプトし、必要な通知/更新をそのように実行することです。

または、 getXXX 操作へのアクセスのみを提供するインターフェイスを定義し、モデルからそれらを返すようにします。これにより、何もデータを変更できなくなります。

于 2012-08-17T12:48:07.227 に答える