Java ビルダーパターンのサブクラス作成とインスタンス化

Android
Java

多くのコンストラクタやオプションパラメーターが必要なクラスを作成するときにBuilderというデザインパターンがあります。
私はEffective Javaで紹介されているパターンを利用しています。
非常に美しくクラスが作れる素晴らしいパターンですね。

さて、で、Builderパターンで作成したクラスのサブクラスをどうするの?
という疑問がありまして、下記に答えがありましたが、日本語情報があまりなかったので、書いておきます。

http://stackoverflow.com/questions/17164375/subclassing-a-java-builder-class

Offer(オファー)というクラスがあり、そのサブクラスでDone(成約)というものがあります。
まずは、Offerで利用するビルダーでジェネリクスを利用するように変更します。

 public class Offer {
 
    private final String offer_id;
    private final int offer_price;
    protected final ArrayList<Delivery> delivery_list;
    private final int bid_number;
    private final int more_number;
    private final MatchRate match_rate;
    private final boolean is_bid;
    private final boolean is_more;
    private final boolean is_matched;
    private final String winner_id;
    private final String status;
    private final boolean is_approved; //成約しているかどうか
    private final String bidder_id;
 
    protected final int max_weight;
    protected final int number_of_delivery;
    protected final int number_of_sender;
    protected final int take_over;
    protected final boolean is_pack;
    protected final int company_id;
    protected final String company_name;
    protected final double company_review;
 
    protected final int pack_id;
    protected final Pack pack;
 
    public static class Builder<T extends Builder> {
 
        //必須パラメーター
        private final String offer_id;
        private final int offer_price;
        private final ArrayList<Delivery> delivery_list;
 
        //オプションパラメーター 初期値を設定
        private int bid_number = 0;
        private int more_number = 0;
        private MatchRate match_rate = MatchRate.NOT_GOOD;
        private boolean is_bid = false;
        private boolean is_more = false;
        private boolean is_matched = false;
        private String winner_id;
        private String status;
        private boolean is_approved;
        private String done_id;
        private String bidder_id = null;
 
        private int max_weight;
        private int number_of_delivery = 0;
        private int number_of_sender = 0;
        private int take_over = 0;
        private boolean is_pack = false;
        private int company_id;
        private String company_name;
        private double company_review;
        private int pack_id;
        private Pack pack;
 
        /**
         * @param offer_id
         * @param offer_price
         * @param delivery_list
         */
        public Builder(String offer_id, int offer_price, ArrayList<Delivery> delivery_list) {
            this.offer_id = offer_id;
            this.offer_price = offer_price;
 
            this.delivery_list = delivery_list;
 
        }
 
        public T bid_number(int val) {
            bid_number = val;
            return (T)this;
        }
 
        public T more_number(int val) {
            more_number = val;
            return (T)this;
        }
 
        public T match_rate(MatchRate val) {
            match_rate = val;
            return (T)this;
        }
 
        public T is_bid(boolean val) {
            is_bid = val;
            return (T)this;
        }
 
        public T is_more(boolean val) {
            is_more = val;
            return (T)this;
        }
 
        public T is_matched(boolean val) {
            is_matched = val;
            return (T)this;
        }
 
        public T status(String val) {
 
            status = val;
            return (T)this;
        }
 
        public T winner_id(String val) {
            winner_id = val;
 
            if (winner_id != null) {
 
                is_matched = true;
            }
 
            return (T)this;
        }
 
        public T is_approved(boolean val) {
            is_approved = val;
            return (T)this;
        }
 
        public T done_id(String val) {
            done_id = val;
            return (T)this;
        }
 
        public T bidder_id(String val) {
            bidder_id = val;
            return (T)this;
        }
 
        public T max_weight(int val) {
            max_weight = val;
            return (T)this;
        }
 
        public T number_of_delivery(int val) {
            number_of_delivery = val;
            return (T)this;
        }
 
        public T number_of_sender(int val) {
            number_of_sender = val;
            return (T)this;
        }
 
        public T take_over(int val) {
            take_over = val;
            return (T)this;
        }
 
        public T is_pack(boolean val) {
            is_pack = val;
            return (T)this;
        }
 
        public T company_id(int val) {
            company_id = val;
            return (T)this;
        }
 
        public T company_name(String val) {
            company_name = val;
            return (T)this;
        }
 
        public T company_review(double val){
            company_review = val;
            return (T)this;
        }
 
        public T pack_id(int val) {
            pack_id = val;
            return (T)this;
        }
 
        public T pack(Pack val) {
            pack = val;
            return (T)this;
        }
 
        public Offer build() {
            return new Offer(this);
        }
 
    }
 
    protected Offer(Builder builder) {
 
        offer_id = builder.offer_id;
        offer_price = builder.offer_price;
        delivery_list = builder.delivery_list;
        bid_number = builder.bid_number;
        more_number = builder.more_number;
        match_rate = builder.match_rate;
        is_bid = builder.is_bid;
        is_more = builder.is_more;
        is_matched = builder.is_matched;
        is_approved = builder.is_approved;
        bidder_id = builder.bidder_id;
        status = builder.status;
        winner_id = builder.winner_id;
 
        max_weight = builder.max_weight;
        number_of_delivery = builder.number_of_delivery;
        number_of_sender = builder.number_of_sender;
        take_over = builder.take_over;
        is_pack = builder.is_pack;
        company_id = builder.company_id;
        company_name = builder.company_name;
        company_review = builder.company_review;
        pack_id = builder.pack_id;
        pack = builder.pack;
    }
 
    public String getOfferId() {
        return offer_id;
    }
 
    public int getOfferPrice() {
        return offer_price;
    }
 
 // 後は省略
 
 }

Doneクラスは次のようにします。

 public class Done extends Offer{
 
    private final String done_id;
    private final boolean is_canceled;
 
     public static class Builder extends Offer.Builder<Builder> {
 
        //必須パラメーター
        private String done_id;
        private boolean is_canceled;
 
        /**
         * @param offer_id
         * @param offer_price
         * @param delivery_list
         */
        public Builder(String offer_id, int offer_price, ArrayList<Delivery> delivery_list) {
            super(offer_id, offer_price, delivery_list);
        }
 
        public Builder Done(String done_id, boolean is_canceled) {
 
            this.done_id = done_id;
            this.is_canceled = is_canceled;
 
            return this;
 
        }
 
        public Done build() {
            return new Done(this);
        }
 
   }
 
    protected Done(Builder builder) {
        super(builder);
        done_id = builder.done_id;
        is_canceled = builder.is_canceled;
    }
 
    public String getDone_id(){
 
        return done_id;
    }
 
 
 }

いやー、こういうことを考える、頭の良い人がいるもんですね!!
パチパチパチパチ[smile]

Doneをインスタンスにする場合は、次のようにnewします。

        Done done = new Done.Builder(offer_id, offer_price, delivery_list)
                .winner_id(winner_id)
                .number_of_delivery(receiver_number)
                .number_of_sender(sender_number)
                .max_weight(max_weight)
                .take_over(take_over)
                .is_pack(is_pack)
                .pack_id(getPackId(data, context))
                .pack(pack)
                .Done(done_id, false) 
                .build();
カテゴリーJava

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です