Javaのゲッター:常に特定のメソッドを実行します
質問
毎回呼び出されるメソッドを定義する方法はありますI呼んでもらう?
私は、オブジェクトの連絡先を持っており、updateLastUsed()を設定する必要はありません。私のメンバー約30ゲッターます。
で解決
私は、AOPを示唆しているだろうが、それは我々が話しているJ2MEだ場合は、最も可能性が高いほう手動で30のアクセサのそれぞれに「onGetCalledを()」を挿入して、あなたがそのメソッド内で必要なものは何でもコーディングしています。あなたが将来的にそれを必要とする場合に呼び出される(またはプロパティにアクセス)されているメソッドの名前を渡したいことがあります。
他のヒント
の代わりにあなたのプロパティのゲッターにアクセスするには、入力として、プロパティ名をとり1つの一般的なゲッターを作成することができます。あなたの特性のタイプが異なる場合は戻り値の型がObjectである必要があるだろう。
この一般ゲッターでは、プロパティのゲッターとupdateLastUsed()メソッドを呼び出します。安全のためには、すべてのプロパティのゲッターをプライベートにする。
あなたが(穿孔)すべてのメソッドへのコールに追加する、またはタイプのゲッターと一致するように(例えばAspectJの、例えば以下)AOPのいくつかのフォームを使用しupdateLastUsed()メソッドを呼び出すことができます。
編集:いくつかの人々は30のゲッターを指摘しているが、コードの臭いであり、他のメソッドを呼び出すと、副作用です。最初の文は、公正な指標ではなく、ルールです。あなたが2種類以上に責任を分離することができた場合、私がチェックするアドバイスとしてそれを残すだろうと、さらに情報がなく、タイプのこの種を持っている多くの理由が考えられます。
副作用について他の点は、または関連してもしなくてもよいです。それはSENSはゲッターメソッドに適用することができ、多くの横断的関心事があります。例えば、ロギング、認証、およびキャッシングのために。 updateLastUsed例示的な方法は、()ので、質問の資格のない批判は、私の意見では不当され、キャッシング戦略の一部である可能性があります。
次のようにAspectJの中でポイントカットとアドバイスを実装する方法の例があります:
package test;
public aspect TestAspect {
/**
* Match all getters of test.Contact and bind the target.
*/
protected pointcut contactGetters(Contact contact) :
execution(* test.Contact.get*()) && target(contact);
/**
* Before execution of each getter, invoke the updateLastUsed() method
* of the bound target.
*/
before(Contact contact): contactGetters(contact) {
contact.updateLastUsed();
}
}
AOPのようなものは、これを行うために必要とされるであろう。私は、J2MEにこれ以外であること、サポートどれだけ知っていません>。
AOPのほかに、あなたがjava.lang.reflect.Proxy
、またはバイトコード操作を使用することができます...
ではなく、J2MEの
私はupdateLastUsed()30回の呼び出しをお勧めします。
これは、アスペクト指向プログラミング(AOP)のための仕事のように見えます。
タグ
get*
で始まる何のために実行される側面を定義します
「新しい」AspectJの5のものを使用すると、メソッドの本体を実行するポイントカット@Before
を呼び出す持っているあなたのゲッターに注釈を付けることができるように縦横ポイントカットを定義するためのアノテーションの使用をサポートしています。
ゲッターヘッダーへのメソッド呼び出しを追加する正規表現を使用します。
検索:
\w+ get\w+\s*\(\)\s*\{(\s*)
で置き換えます:
\0updateLastUsed();\1
これらの表現は、「検索/置換」ダイアログで「すべて置換」を使用してのEclipse 3.5(ガリレオ)を用いて試験した。
は、使用エディタが複数行マッチングをサポートしている必要があります(または、あなたがそれを有効にする必要が)あることに注意してください。 EmEditorの8.05のために、私はあることを、検索文字列を変更する必要がありました。
\w+ get\w+\s*\(\)\s*\{\s*(\n\s*)
改行を明示的に一致されるようになっています。あるとして置換文字列が残っています。
あなたは空想何かをすることができますが、正直これはすぐに退屈なコードを繰り返すことができますように、マクロは、編集に追加された理由です。
私は、すべてのゲッターによって呼び出されるメソッドを作成し、(それが法によって異なるために必要な場合)、その後の呼び出しを作成するために、マクロを使用します。これは、すべて一度だけ行う必要があり、その後、あなたはそれを忘れて...
ここでの方法です。それはかなりありませんが、繰り返しにそれを好むかもしれない:
public class GetterTest extends TestCase {
private static class Thing {
public int accessCount;
private String name;
private int age;
private <T> T get(T t) {
accessCount++;
return t;
}
public String getName() {
return get(name);
}
public int getAge() {
return get(age);
}
}
public void testGetIncrementsAccessCount() throws Exception {
Thing t = new Thing();
assertEquals(0, t.accessCount);
t.getName();
assertEquals(1, t.accessCount);
t.getAge();
assertEquals(2, t.accessCount);
}
}
もちろん、私のget()は、ちょうどaccessCountをインクリメントされ、あなたが他のいくつかの行動をお勧めしますが、アイデアがあります。
私は、オブジェクトが目的のメソッドを呼び出すためにproxifyだと思います。