2009-07-15 9 views
2

getメソッドを呼び出すたびに呼び出されるメソッドを定義する方法はありますか?Javaゲッター:常に特定のメソッドを実行する

私はオブジェクトの連絡先があり、updateLastUsed()を設定したくありません。私のメンバーのために約30名のゲッターで。

+2

オブジェクトのフィールドを更新することによって、ゲッターに副作用を導入しているので、これは少し不安です。 – akf

+0

申し訳ありませんが、私は母国語のスピーカーではありません。 「副作用を導入する」ことが何を意味するのか説明できますか? –

+1

本当に30ゲッターが必要ですか?これはクラスのようには思えませんが、データバンドルです。私の推測では、連絡先データは、連絡先を操作するすべてのものを含むクラスの中にラップされたハッシュ内にあるはずです。 getterを持つクラスを持つことは、データをコピーするためのすべてのコントロールのコードを書く必要があることを意味します(リフレクションを使用しない限り、これはまだハッシュより優れていません)。ハッシュではダイナミックバインディングを使用する方が簡単なので、データベースやGUIコントロールにフィールドをコピーするコードを書く必要はありません。 –

答えて

2

次のように

AspectJの中にポイントカットとアドバイスを実装する方法の例がありますあなたの30人のアクセサのそれぞれで "onGetCalled()"を呼び出し、そのメソッド内で必要なものをコーディングします。あなたが将来必要になる場合に備えて、呼び出されているメソッド(またはアクセスされたプロパティ)の名前を渡すことができます。

2

すべてのメソッドへの呼び出しを追加することができます(退屈な)、またはAOPの何らかの形式(例としては以下のAspectJ)を使用して型のゲッターにマッチさせ、updateLastUsed()メソッドを呼び出します。

編集:30人のゲッターがコードのにおいであり、別のメソッドを呼び出すことが副作用であると指摘しています。最初のステートメントは公平な指標ですが、ルールではありません。この種のタイプを持つ理由はたくさんありますが、それ以上の情報がなければ、責任を2つ以上のタイプに分けることができるかどうかを確認するアドバイスとして残しておきます。

その他の副作用については、関連性があるかもしれません。 getterメソッドに適用する感覚を作るのには、多数のクロスカッティングの問題があります。例えば、ロギング、認証、キャッシングなど。サンプルメソッドupdateLastUsed()はキャッシング戦略の一部である可能性があるので、私の意見では、質問に対する非適格な批判は不十分です。私は、AOPを示唆しているだろうが、それは我々が話しているJ2MEだ場合は、手動で挿入オフに最も可能性が高い方がよいでしょう

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(); 
    }  
} 
+0

30人のゲッターが既に(退屈な)マークを通過しています!あなたがこのクラスで何かするのは悪夢になるでしょう。ビジネスロジックがなければクラスはありません。ビジネスロジックを持っているなら、ゲッターは必要ありません。 –

1

これは、アスペクト指向プログラミング(AOP)の仕事のようです。 get*

で始まる何のために実行される側面「新」AspectJの5のものは、あなたが実行するポイントカット@Beforeを呼び出す持っているあなたのゲッターに注釈を付けることができるように縦横ポイントカットを定義するためのアノテーションの使用をサポートする定義

メソッドの本体

1

これを行うには、AOPのようなものが必要です。私はthis以外のJ2MEでどれだけうまくサポートされているのか分かりません。

1

AOPのほかに、私は)(updateLastUsedを呼び出して30回をお勧めしますJ2ME

java.lang.reflect.Proxy、またはバイトコード操作...

でもないを使用することができます。

3

プロパティのゲッターにアクセスする代わりに、プロパティ名を入力とする一般的なゲッターを1つ作成することができます。プロパティの型が異なる場合、戻り値の型はObjectである必要があります。

この一般的なゲッターでは、ゲッターとupdateLastUsed()メソッドを呼び出します。安全であるためには、すべての物件ゲッターを私的にする。

1

ここには方法があります。それはかなりありませんが、繰り返しにそれを好むかもしれない:

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をインクリメントされ、あなたが他のいくつかの行動をお勧めしますが、アイデアがあります。

+0

私のBlackberryはJava 1.4のみをサポートしているので、一般的なサポートはありません。しかし、あなたのサンプルのように。 +1 –

+0

Tをオブジェクトに置き換え、すべてのgetXメソッドでキャストを追加することで、ジェネリックスなしで行うことができます。 –

+0

プリミティブを除く(1.4ではオートボックスなし)。 –

1

正規表現を使用して、ゲッターヘッダーにメソッド呼び出しを追加します。

検索:

\w+ get\w+\s*\(\)\s*\{(\s*)

と交換してください:

\0updateLastUsed();\1

をこれらの表現は、 "すべて置換" を使用してのEclipse 3.5(ガリレオ)を用いて試験しました私n「検索/置換」ダイアログ。

使用するエディタでは、複数行の一致をサポートする必要があります(または有効にする必要があります)。新しい行が明示的に一致するように

\w+ get\w+\s*\(\)\s*\{\s*(\n\s*)

:EmEditorの8.05のために、私はあることを、検索文字列を変更する必要がありました。置換文字列はそのままです。

1

あなたは何か気になることがありますが、正直なところ、マクロがエディタに追加されているので、退屈なコードをすばやく繰り返すことができます。

私はメソッドをすべてのゲッターで呼び出すようにしてから、マクロを使用してコールを作成します(メソッドによって異なる必要がある場合)。これはすべて一度だけ行う必要がありますし、あなたはそれを忘れてしまいます...

0

私は、目的のメソッドを呼び出すためにオブジェクトをproxifyと言います。

関連する問題