構造對象的方式過於複雜,不如將之抽離出來。好比,構造器參數過多
這樣說也有點抽象,舉個例子吧。html
好比 很是熱門的消息隊列RabbitMQ 的 AMQP.BasicPropertiesjava
由於它的屬性比較多,因此構造函數也是挺嚇人的。程序員
我看到也不太想調用。
若是如今要構造一條消息安全
在沒有 builder 模式以前,是這樣構造的多線程
new AMQP.BasicProperties("text/plain",null,null,2,1,null,null,null,null,null,null,null,null,null);
痛苦啊!!!不信,你本身也能夠嘗試構造一下。ide
而用了 Builder 模式後。函數
new AMQP.BasicProperties.Builder() .contentType("text/plain") .deliveryMode(2) .priority(1) .build();
舒暢!!!ui
很簡單。this
BasicProperties
中添加一個叫Builder
的內部類BasicProperties
類是徹底一致的Builder
實例在調用build
函數的時候,再調用BasicProperties
的構造函數構造對象。代碼以下線程
public static class BasicProperties{ private String contentType; private String contentEncoding; private Map<String,Object> headers; private Integer deliveryMode; private Integer priority; //... 還有不少屬性 public BasicProperties( String contentType, String contentEncoding, Map<String,Object> headers, Integer deliveryMode, //... String clusterId){ this.contentType = contentTypel; this.contentEncoding = contentEncoding; //... } public static final class Builder { private String contentEncoding; private Map<String,Object> headers; private Integer deliveryMode; private Integer priority; //.. 和BasicProperties的字段一致的。 public Builder contentType(String contentType){ this.contentType = contentType; return this; } public Builder contentEncoding(String contentEncoding){ this.contentEncoding = contentEncoding; return this; } public BasicProperties build() { return new BasicProperties ( contentType contentEncoding, //還有不少屬性 ); } } }
Builder 模式的好處
壞處
若是不用 Builder 模式,有其餘的作法嗎?
好比,上面的例子,我構造的消息只需 投遞模式(delivery mode)、優先級(priority)、 content-type ,專門爲這幾個參數弄個專門的構造函數,能夠嗎?
調用就變成這樣了。
new AMQP.BasicProperties("text/plain",2,1)
能夠,
BasicProperties p = new AMQP.BasicProperties(); p.setContentType("text/plain"); p.setDeliveryMode(2); p.setPriority(1);
在《effective java》中就探討過這個可能,書中是這樣說的
由於構造過程被分到幾個調用中,在構造過程當中 javaBean 可能處於不一致的狀態。類沒法僅僅經過檢驗構造器參數的有效性來保證一致性。試圖使用處於不一致狀態的對象,將致使失敗,這種失敗與包含錯誤的代碼截然不同,所以它調試起來十分困難。與此相關的另外一點不足在於,javaBeans 模式阻止了把類作成不可變的可能,這須要程序員付出格外的努力來確保它的線程安全。
這話就有點摸不着頭腦,什麼意思
其實意思是大概的,
以上