9

多くのインスタンス フィールドを持つ (Java) クラスがあります (その多くはオプションです)。すべてのフィールド (したがってクラス) を不変にしたいと考えています。そのため、クラスのインスタンスを構築するために Builder パターンを使用したいと思います。

Builder パターンを使用してクラスのインスタンスを作成するように myBatis を構成できますか? myBatis にマップを返させ、そのマップを使用してコード内のインスタンスをビルドできることはわかっています。ただし、Java Beans とコンストラクターを使用してインスタンスを作成する方法と同様に、このマッピングを構成する (または何らかの規則を使用する) 方法を探しています。

編集(例を含めるため)

次に例を示します。

package com.example.model;

// domain model class with builder
public final class CarFacts {

    private final double price;
    private final double numDoors;
    private final String make;
    private final String model;
    private final String previousOwner;
    private final String description;

    public static class Builder {
        // required params
        private final double price;
        private final String make;
        private final String model;

        // optional params
        private final String previousOwner;
        private final String description;
        private final double numDoors;

        public Builder(double price, String make, String model) {
            this.price = price;
            this.make = make;
            this.model = model;
        }

        public Builder previousOwner(String previousOwner) {
            this.previousOwner = previousOwner;
            return this;
        }
        // other methods for optional param

        public CarFacts build() {
            return new CarFacts(this);
        }
    }

    private CarFacts(Builder builder) {
        this.price = builder.price;
        //etc.
    }
}

次に、次のようなマッパーがあります。

<!-- this doesn't work but I think h3adache suggest that I could have the resultType
be com.example.model.CarFacts.Builder and use the Builder constructor. But I'm not sure how
I would call the methods (such previousOwner(String)) to populate optional params -->

<mapper namespace="com.example.persistence.CarFactsMapper">
  <select id="selectCarFacts" resultType="com.example.model.CarFacts">
    select *
    from CarFacts
  </select>
    
</mapper>

最後に、マッパー インターフェイスがあります。

package com.example.persistence.CarFactsMapper;

public interface CarFactsMapper {
    List<CarFacts> selectCarFacts();
}

また、myBatis を介して静的ファクトリ メソッドを使用してインスタンスを作成できるようにしたいと考えています。例えば:

public final class Person {

    private final String lastName;
    private final String firstName;

    private Person(String lastName, String firstName) {
        this.lastName = lastName;
        this.firstName = firstName;
    }

    public Person newInstance(String lastName, String firstName) {
        return new Person(lastName, firstName);
    }
}

具体的には、myBatis に newInstance(String, String) を呼び出させるにはどうすればよいですか?

4

1 に答える 1

-1

ビルダーまたは静的ファクトリ メソッドを使用する必要はありません。はい、不変性を維持しようとしている場合、これらのパターンは確かに役立ちます。変更が発生する可能性があるためです。たとえば、build() (新しい不変インスタンスを作成するため) への呼び出しの前にビルダーが変更されているため、「インスタンス間」と言いましょう。

ただし、不変性は、特定のインスタンスの構築方法とは無関係です。変更可能なクラスのビルダーと静的ファクトリ メソッドを作成しても、どこにも行きません。建設の時点では、すべてのオブジェクトはまだ変更されていないため、本当に重要なのは次に何が起こるかです (ビルダーと工場が去った後)。

あなたがする必要があるのは、クラス自体に焦点を当て、このクラスは不変であると考えるだけです。通常の myBatis マッピングで問題ないはずです。ビルダーを作成する時間を節約できます。

そうです-あなたのクラスは不変ですか、そうです、すべてのフィールドが最終的であり、プリミティブ型または文字列(Javaでは不変です!)のいずれかであるためです。他の非プリミティブ フィールドがある場合は、それらを final にする必要があり (技術的には final を記述する必要はありませんが、フィールドが実際に再割り当てされない限り、それをお勧めします)、それらのクラスをこれらのルールの再帰に従ってください。

これが役に立てば幸いです。伝えたいポイントは、ビルダー パターンとファクトリ メソッドは構築を管理するのに適していますが、無料で不変性を提供するわけではなく、常にコンストラクターを作成する必要があるということです。

于 2013-04-06T07:17:31.663 に答える