11

私は、千の太陽の火のように燃える情熱を持った JavaBeans パターンを嫌います。なんで?

  • 詳細。2009 年です。プロパティに 7 LOC を記述する必要はありません。彼らがイベントリスナーを持っている場合は、あなたの帽子を握ってください.
  • タイプ セーフな参照はありません。プロパティを参照するタイプ セーフな方法はありません。Java の重要な点は、それが型安全であることであり、その最も一般的なパターンは型安全ではありません。

私が欲しいのは次のようなものです:

class Customer {
    public Property<String> name = new Property();
}

私は主に Web 開発者なので、JPA と Wicket のサポートが必要です。

Javabean 列車から降りるのを手伝ってください!

4

11 に答える 11

10

そこにある宣言にかなり近いと思います(スケッチについては以下を参照)。ただし、Bean 以外のアプローチを使用すると、JavaBeans プロトコルが有効であると想定するほとんどのツールで提供されるサポートが失われる可能性があります。親切にしてください。以下のコードは私の頭の上から外れています...

public class Property<T> {
    public final String name;
    T value;
    private final PropertyChangeSupport support;

    public static <T> Property<T> newInstance(String name, T value, 
                                              PropertyChangeSupport support) {
        return new Property<T>(name, value, support);
    }

    public static <T> Property<T> newInstance(String name, T value) {
        return newInstance(name, value, null);
    }

    public Property(String name, T value, PropertyChangeSupport support) {
        this.name = name;
        this.value = value;
        this.support = support;
    }

    public T getValue() { return value; }

    public void setValue(T value) {
        T old = this.value;
        this.value = value;
        if(support != null)
            support.firePropertyChange(name, old, this.value);
    }

    public String toString() { return value.toString(); }
}

そして先に進んでそれを使用してください:

public class Customer {
    private final PropertyChangeSupport support = new PropertyChangeSupport();

    public final Property<String> name = Property.newInstance("name", "", support);
    public final Property<Integer> age = Property.newInstance("age", 0, support);

    ... declare add/remove listenener ...
}


Customer c = new Customer();
c.name.setValue("Hyrum");
c.age.setValue(49);
System.out.println("%s : %s", c.name, c.age);

そのため、プロパティの宣言は 1 行のコードで済み、プロパティ変更のサポートが含まれるようになりました。メソッド setValue() と getValue() を呼び出したので、まだ Rhino などのようにコード化する Bean のように見えますが、簡潔にするために、get() と set() だけを追加できます。残りは読者の演習として残します。

  • シリアル化を適切に処理する
  • null 値のチェックを処理する
  • オートボクシングのオーバーヘッドが気になる場合は、アトミック型の特殊化を追加してください。
  • ?? もっと落とし穴があると確信している

また、(通常は匿名クラスとして) サブクラス化し、 setValue() をオーバーライドして、追加のパラメーター チェックを提供できることにも注意してください。

「文字列参照」から本当に逃れることはできないと思います。それがリフレクションのすべてであるからです。

悲しいことに、この時代では、これはまだアセンブリでのプログラミングのようなものです...選択肢があれば、Groovy、C#などはまだより良い選択かもしれません。

于 2009-01-14T01:43:30.110 に答える
5

で私のBeanアノテーションをチェックしてください

http://code.google.com/p/javadude/wiki/Annotations

基本的にあなたは次のようなことをします:

@Bean(
  properties={
    @Property(name="name"),
    @Property(name="phone", bound=true),
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
  }
)
public class Person extends PersonGen {}

これらの余分なget/setなどのメソッドをすべて自分で定義するのではなく。

equals / hashCode、オブザーバー、デリゲート、ミックスインなどを定義する他の属性があります。

これは、Eclipseまたはコマンドラインビルド(たとえば、ant)で実行される一連の注釈と注釈プロセッサです。プロセッサは、生成されたすべてのコードを含むスーパークラスを生成します(アノテーションプロセッサは、アノテーションを含むクラスを変更できません、ところで)

于 2009-01-14T22:20:05.137 に答える
3

Groovyは動的に型付けされた JVM ベースの (そして Java と完全に互換性のある) 言語であり、「実際の」プロパティを備えています。

于 2009-01-13T23:12:50.633 に答える
1

Web の場合は、JSON (JavaScript Object Notation)をお勧めします。

軽量のデータ交換フォーマット

. JSON?Beanトランスレータへの参照を次に示します。

于 2009-01-14T00:06:08.623 に答える
1

初めて C# を使用したときはプロパティが気に入りましたが、VS 2008 でしばらく使用した後では、set-/get-methods の方が好きだと言わざるを得ません。

主なポイントは、私の個人的な働き方です。新しいクラスがあり、それで何ができるか知りたい場合は、classname.set と入力するだけで、変更できる「プロパティ」が Eclipse に表示されます。get も同様です。多分それはVSのやり方が悪いだけかもしれませんが、設定したいプロパティが読み取り専用であることをコンパイルした後に確認するために、このitelisenseの長いリスト(最初にプロパティを表示するのではなく、すべてが混在しています)をスクロールする必要があります。 ..ド!

はい、Java では多くの行が必要ですが、属性を記述して IDE に「getter と setter を作成してください」と伝えるだけです。しかし、これらのメソッドは多くのスペースを使用する傾向があるため、IDE で折りたたむことができる領域を Java にも作成したいと考えています。

于 2009-07-27T13:35:42.193 に答える
0

これを試したら:

interface IListenable {
    void addPropertyChangeListener( PropertyChangeListener listener );
    void removePropertyChangeListener( PropertyChangeListener listener );
}

abstract class MyBean extends IListenable {
    public abstract void setName(String name);
    public abstract String getName();

    // more things
}

public class JavaBeanFactory {

   public <T> Class<T> generate(Class<T> clazz) {
      // I used here CGLIB to generate dynamically a class that implements the methods:
      // getters
      // setters
      // addPropertyChangeListener
      // removePropertyChangeListener
   }
}

私はそれを次のように使用しました(これは単なる例です):

public class Foo {
    @Inject
    public Provider<MyBean> myBeanProvider;

    public MyBean createHook(MyBean a) {
        final MyBean b  = myBeanProvider.get();
        a.addPropertyChangeListener(new PropertyChangeListener() {
             public void propertyChange(PropertyChangeEvent evt) {
                 b.setName((String) evt.getNewValue());
             }
        });
        return b;
    }
}
于 2009-01-14T12:39:56.930 に答える
0

また、記述した DSL から .java クラスを作成するコード ジェネレーターを構築することもできます。クラスの名前、必要なプロパティ、およびそれらのタイプを説明する何らかのマークアップを作成できます。次に、JavaBeans を生成するプログラムでそのファイルを処理します。または、アノテーションを使用して、ASM などを使用してクラス ファイルを後処理し、アクセサーとミューテーターを挿入することもできます。また、Spring はこれらの種類の機能のいくつかを提供すると信じていますが、私はそれらを使用していません。

于 2009-01-13T23:15:46.540 に答える
0

モデル エンティティ (JPA でアノテーションを付けたもの) で JavaBean プロパティを頻繁に使用して、それらを (JFace を使用して) UI にデータバインドできるようにします。

残念ながら、2 番目の問題の解決策はありません (おそらく、プロパティ名を含む定数の定義を除いて)。

リスナーのボイラープレートを生成するために行うことは、モデル エンティティを、リフレクションを使用してそれを処理する AbstractJavaBean スーパークラスから拡張することです。次に、セッターを次のように書き直す必要があることを除いて、ゲッター/セッターを作成するデフォルトの方法を使用できます。

public void setRemarks(String remarks) {
    set("remarks", remarks);
}

次に、AbstractJavaBean.set は (Apache commons beanutils を介して) リフレクションを使用して、その getter を介してプロパティ「remarks」の古い値を読み取り、新しい値を「remarks」と呼ばれるフィールドに設定し、古い値と新しい値を使用してプロパティ変更イベントを発生させます。 . 実際、このアイデアを拡張して、プロパティ「birthDate」が変更されたときに「年齢」が変更されるなど、プロパティの 1 つが変更に基づいているときに、依存する「派生」プロパティがプロパティの変更を自動的に起動できるようにすることができます。このロジックはすべて、AbstractJavaBean 内の 1 か所にコーディングして、任意のモデル オブジェクトで使用できます。

于 2013-05-02T13:10:02.987 に答える
0

JBoss のSEAMフレームワークを試してみてください。気に入るはずです。

于 2009-01-14T07:50:30.870 に答える