Javaのデザインパターン:ビルダー(ビルダー)モード

基本コンセプト

ビルダーモードは、複雑なオブジェクトの作成スキーマを作成するためのステップバイステップです。ビルドプロセスを示し、分離部材が開口するように、複雑なオブジェクトとそのコンポーネントのモデルを構築するプロセスは、切り離します。

シナリオ

  • オブジェクトの作成プロセスは複雑であり、または順番や組み合わせは(あなたがGOF「デザインモード」を参照してくださいすることができます古典的なビルダーモード)の依存関係を持って作成します。
  • 多くのオブジェクトを作成するために必要なパラメータ、および多くのオプションのパラメータが含まれ(バリアントビルダーモードを、あなたは、「効果的なJavaの」ビルダーの項を参照することができます)。

サンプルコード

このセクションでは、バリアントビルダーモード、次のサンプルコードを焦点:

public class RobustPerson {
    // 必要参数
    private final int id; // 所有属性都被final修饰
    private final String name;

    // 可选参数
    private final int age;
    private final String gender;
    private final double height;
    private final int weight;

    private RobustPerson(Builder builder) { // 构造方法私有,即客户端不能直接创建RobustPerson对象
        this.id = builder.id;
        this.name = builder.name;
        this.age = builder.age;
        this.gender = builder.gender;
        this.height = builder.height;
        this.weight = builder.weight;
    }

    public static final class Builder {
        // 必要参数
        private final int id; // 必要属性被final修饰
        private final String name;

        // 可选参数
        private int age;
        private String gender;
        private double height;
        private int weight;

        public Builder(int id, String name) { this.id = id; this.name = name; } // 必要参数通过构造方法赋值

        public Builder age(int age) { this.age = age; return this; } // 可选参数通过同名方法赋值
        public Builder gender(String gender) { this.gender = gender; return this; }
        public Builder height(double height) { this.height = height; return this; }
        public Builder weight(int weight) { this.weight = weight; return this; }

        public RobustPerson build() {
            RobustPerson person = new RobustPerson(this);
            // 复杂业务语义校验,对于校验不通过场景,抛出异常
            if (person.height != 0 && person.weight != 0) { // Builder对象并非线程安全的,不能用this.xxx校验
                double bmi = person.weight / (person.height * person.height);
                if (bmi < 18 || bmi > 25) { // 身体质量指数(BMI)低于18或高于25时表示不健康
                    throw new IllegalArgumentException(person.name+" NOT A ROBUST PERSON!");
                }
            }
            return person;
        }
    }

    public Builder toBuilder() { // 克隆
        return new Builder(this.id, this.name).age(this.age)
                .gender(this.gender).height(this.height).weight(this.weight);
    }

    @Override
    public String toString() {
        return name + "{" + "id=" + id + ", age=" + age + ", gender='" + gender + '\'' +
                ", height=" + height + "m, weight=" + weight + "kg}";
    }
}

次のようにテストクラスは次のとおりです。

public class BuilderTest {
    public static void main(String[] args) {
        RobustPerson jack = new RobustPerson.Builder(1, "Jack")
                .age(18).gender("male").height(1.70).weight(65).build();
        System.out.println(jack);

        System.out.println("Jack keeps eating too much...");
        System.out.println(jack.toBuilder().weight(80).build());
    }
}

出力を実行した後:

Jack{id=1, age=18, gender='male', height=1.7m, weight=65kg}
Jack keeps eating too much...
Exception in thread "main" java.lang.IllegalArgumentException: Jack NOT A ROBUST PERSON!
    at builder.RobustPerson$Builder.build(RobustPerson.java:48)
    at builder.BuilderTest.main(BuilderTest.java:14)

主な特徴

サンプルコードセクションを結合、オブジェクト・モデルを作成するように見えるビルダーは、以下の特性を有します。

  • RobustPersonクラスのコンストラクタはプライベートですつまり、クライアントが直接RobustPersonオブジェクトを作成することはできません。
  • RobustPerson不変クラス(スレッドセーフ):すべての属性は、コンストラクタで設定された最終修正、パラメータ値であり、(任意の方法ゲッター)は、外部セッターメソッドを提供しません。
  • ビルダーとRobustPerson静的内部クラスのメンバ変数は、同一の建設方法、オプションのパラメータによって同じ名前の加工方法で修正されたプロセス・パラメータ必要ビルダー最終を有します。
  • RobustPersonオブジェクトを作成するビルダー()メソッドの呼び出しRobustPersonプライベートコンストラクタで構築し、クライアントは、ビルド()メソッドによって(したがって無効な状態を回避する)オブジェクトを作成することができます。
  • Builderオブジェクトはスレッドセーフではありませんあなたがテスト用に作成したビルド()メソッドを対応オブジェクトRobustPersonパラメータに制約を課す必要がある場合RobustPersonオブジェクト。
  • 複数のオブジェクトを作成し、ほとんどの属性値が同じであるオブジェクト場合)toBuilder(によって容易にかつ効率的に複製することができる再び、異なる属性のための唯一の設定値。
  • チェーン呼び出し、使用ビルダーモード可読性より良いを。

ビルダーモードだけでなく、必然的に自身の欠点。例えば:

  • あなたは、オブジェクトが最初にそのビルダーを作成する必要があります作成する前に、(チェーンはターゲットクラス定義されたビルダーのコールカテゴリをモデル化することができる場合にのみ必要)メモリを消費します。
  • 長いプレゼンス定型コード(又はInnerBuilderロンボクウィジェットによって自動的に生成することができる)ビルダーモード。

業界の慣行

  • StringBuilder(JDK)
  • JobBuilder(石英-2.3.0.jar)
  • SessionFactoryBuilder等(休止コア-5.3.6.Final.jar)

おすすめ

転載: www.cnblogs.com/clover-toeic/p/11580905.html