Builder 的應用

改造前

當前正在開發工會宣戰的一個系統,需要存儲宣戰記錄。但是記錄包括很多數據,開始使用構造方法傳遞參數。

DeclareWarUnionInfo(CrossAllianceService crossAllianceService, long unionId, long acceptUnionId, long warTime,
                        long declareHumanId, String declareHumanName) {
        this.crossAllianceService = crossAllianceService;

        crossDeclareWarInfoDB = new CrossDeclareWarInfoDB();
        crossDeclareWarInfoDB.setId(Port.applyId());
        crossDeclareWarInfoDB.setUnionId(unionId);
        crossDeclareWarInfoDB.setAcceptUnionId(acceptUnionId);
        crossDeclareWarInfoDB.setAccept(EDeclare.NOT_ACCEPT.getIndex());
        crossDeclareWarInfoDB.setWartime(warTime);
        crossDeclareWarInfoDB.setDeclareHumanId(declareHumanId);
        crossDeclareWarInfoDB.setDeclareHumanName(declareHumanName);
        crossDeclareWarInfoDB.setDatetime(Port.getTime());
        crossDeclareWarInfoDB.persist();
    }


    /**
     * 使用數據庫對象初始化
     * @param crossAllianceService
     * @param crossDeclareWarInfoDB
     */
    DeclareWarUnionInfo(CrossAllianceService crossAllianceService, CrossDeclareWarInfoDB crossDeclareWarInfoDB) {
        this.crossAllianceService = crossAllianceService;
        this.crossDeclareWarInfoDB = crossDeclareWarInfoDB;
    }

構造方法參數一堆,創建的時候要傳入一堆參數。

DeclareWarUnionInfo createDeclareWarUnionInfo = new DeclareWarUnionInfo(this, unionId, opponentUnionId,
                warTime, declareHumanId, declareHumanName);

// 方式2
DeclareWarUnionInfo declareWarUnionInfo = new DeclareWarUnionInfo(this, db);

變爲Builder

寫完之後,總是覺得這種方法不是很好。後來想到了EffectiveJava 中講到的Builder,突然豁然開朗,這個時候其實運用這種方法可能獲得很好的效果。於是開始改造。

public class DeclareWarUnionInfo {

    ...

    /**
     * DeclareWarUnionInfo 構造器
     */
    static class Builder {
        private final CrossAllianceService crossAllianceService;
        private long unionId;
        private long acceptUnionId;
        private EDeclare eDeclare = EDeclare.NOT_ACCEPT;
        private long warTime;
        private long declareHumanId;
        private String declareHumanName;
        private long dateTime;
        private CrossDeclareWarInfoDB crossDeclareWarInfoDB;

        Builder(CrossAllianceService crossAllianceService, long unionId, long acceptUnionId) {
            this.crossAllianceService = crossAllianceService;
            this.unionId = unionId;
            this.acceptUnionId = acceptUnionId;
        }

        Builder(CrossAllianceService crossAllianceService, CrossDeclareWarInfoDB crossDeclareWarInfoDB) {
            this.crossAllianceService = crossAllianceService;
            this.crossDeclareWarInfoDB = crossDeclareWarInfoDB;
        }

        Builder addWarTime(long val) {
            warTime = val;
            return this;
        }

        Builder addDeclareHumanId(long val) {
            this.declareHumanId = val;
            return this;
        }

        Builder addDeclareHumanName(String val) {
            this.declareHumanName = val;
            return this;
        }

        Builder addDateTime(long val) {
            this.dateTime = val;
            return this;
        }

        DeclareWarUnionInfo build() {
            return new DeclareWarUnionInfo(this);
        }
    }

    
    ...
}

構造方法,進行private,防止直接new對象。只能通過帶有Builder參數的構造方法在內部類Builder中實例化。(crossDeclareWarInfoDB是一個數據庫對象,當傳入此對象時是在從數據庫載入對象。另外一種方式就創建對象,並且保存數據庫)

/**
     * 構造函數,此類僅能通過Builder創建
     * @param builder 構造器
     */
    private DeclareWarUnionInfo(Builder builder) {
        crossAllianceService = builder.crossAllianceService;

        if (builder.crossDeclareWarInfoDB == null) {
            crossDeclareWarInfoDB = new CrossDeclareWarInfoDB();
            crossDeclareWarInfoDB.setId(Port.applyId());
            crossDeclareWarInfoDB.setUnionId(builder.unionId);
            crossDeclareWarInfoDB.setAcceptUnionId(builder.acceptUnionId);
            crossDeclareWarInfoDB.setAccept(builder.eDeclare.getIndex());
            crossDeclareWarInfoDB.setWartime(builder.warTime);
            crossDeclareWarInfoDB.setDeclareHumanId(builder.declareHumanId);
            crossDeclareWarInfoDB.setDeclareHumanName(builder.declareHumanName);
            crossDeclareWarInfoDB.setDatetime(builder.dateTime);
            crossDeclareWarInfoDB.persist();
        } else {
            crossDeclareWarInfoDB = builder.crossDeclareWarInfoDB;
        }

    }

創建對象:

// 方式1:
DeclareWarUnionInfo declareWarUnionInfo = new DeclareWarUnionInfo.Builder(this, db).build();


// 方式2:
DeclareWarUnionInfo createDeclareWarUnionInfo = new DeclareWarUnionInfo.Builder(this, unionId, acceptUnionId)
                .addWarTime(warTime)
                .addDeclareHumanId(humanId)
                .addDeclareHumanName(humanName)
                .build();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章