前回の例は、対象となるオブジェクトが初期化後に変更されないため、再利用できることは明白でした。
今回は、アダプターの場合について考えます。
アダプターとは、内部で保持しているオブジェクトに対する代替のインターフェースを提供しながら、その内部で保持しているオブジェクトへの委譲を行っているオブジェクトです。
アダプターは内部で保持しているオブジェクトの状態以外の状態をもっていないため、ある特定のオブジェクトに対するアダプターのインスタンスを2つ以上生成する必要がありません。
MapインターフェースのkeySetメソッドは、そのマップ内の全てのキーから構成されているMapオブジェクトのsetビューを返します。
keySetメソッドの返すsetビューは、なんど呼び出さいても同一のインスタンスを返して問題ありません。
なぜなら、setビューが内包しているMapオブジェクトは、同一のインスタンスであるべきだからです。
setビュー経由で操作したMapオブジェクトの変更は、全てのsetビューで共有されるべきです。
以下はHashMapのkeySetメソッドの実装です。
------------------------------------------------------------
public Set keySet() {
Set ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
------------------------------------------------------------
HashMapのフィールド変数であるkeySetが初期化されていない場合のみKeySetのインスタンス化を行っています。
本項目は、オブジェクトの生成はコストがかかるため避けるべきである、ということを意味しているわけではありません。
コンストラクタで明示的な処理をしていないオブジェクトの生成はほとんどコストがかかりません。(家マシンでは100万回インスタンス化して、26ms程度)また、オブジェクトをつかいまわすことで、思わぬバグやセキュリティホールを埋め込む可能性があります。また、プログラムの保守性、可読性も低下する可能性があります。
明らかにコストがかかるオブジェクト(DBコネクション生成等)や、複数のオブジェクトを生成することに全く意味が無い場合に、オブジェクトを使いまわすべきです。
--> 終わり
0 件のコメント:
コメントを投稿