定義:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。編程
類型:建立類模式ide
類圖:測試
四個要素ui
代碼實現:this
//通常狀況下,這個類的構造很複雜,或者屬性超級多。可組合多種形式的示例 public class Service { private String provider; private String user; private String pwd; public String getProvider() { return provider; } public void setProvider(String provider) { this.provider = provider; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public void sendMsg(String msg) { System.out.println("經過" + this.provider + "發送消息:" + msg); } } public interface Builder { void setProvider(String provider); void setAccount(String user, String pwd); Service getService(); } public class ConcreteBuilder implements Builder { private Service service = new Service(); @Override public void setProvider(String provider){ this.service.setProvider(provider); } @Override public void setAccount(String user, String pwd) { this.service.setUser(user); this.service.setUser(pwd); } @Override public Service getService() { return this.service; } } public class Director { private Builder builder = new ConcreteBuilder(); public Service getApnsNoticeService() { builder.setProvider("APNS"); builder.setAccount("notice_apns_user", "notice_apns_pwd"); return builder.getService(); } public Service getJpushNoticeService() { builder.setProvider("極光"); builder.setAccount("notice_jpush_user", "notice_jpush_pwd"); return builder.getService(); } public Service getMontnetsSmsService() { builder.setProvider("夢網"); builder.setAccount("sms_montnets_user", "sms_montnets_pwd"); return builder.getService(); } public Service getEtonenetSmsService() { builder.setProvider("移通"); builder.setAccount("sms_etonenet_user", "sms_etonenet_pwd"); return builder.getService(); } } public class Client { public static void main(String[] args) { String msg = "Hello World!"; Director director = new Director(); Service apnsNoticeService = director.getApnsNoticeService(); apnsNoticeService.sendMsg(msg); Service jpushNoticeService = director.getJpushNoticeService(); jpushNoticeService.sendMsg(msg); Service montnetsSmsService = director.getMontnetsSmsService(); montnetsSmsService.sendMsg(msg); Service etonenetSmsService = director.getEtonenetSmsService(); etonenetSmsService.sendMsg(msg); } }
建造者模式的優勢spa
首先,建造者模式的封裝性很好。使用建造者模式能夠有效的封裝變化,在使用建造者模式的場景中,通常產品類和建造者類是比較穩定的,所以,將主要的業務邏輯封裝在導演類中對總體而言能夠取得比較好的穩定性。code
其次,建造者模式很容易進行擴展。若是有新的需求,經過實現一個新的建造者類就能夠完成,基本上不用修改以前已經測試經過的代碼,所以也就不會對原有功能引入風險。對象
建造者模式與工廠模式的區別blog
咱們能夠看到,建造者模式與工廠模式是極爲類似的,整體上,建造者模式僅僅只比工廠模式多了一個「導演類」的角色。在建造者模式的類圖中,假如把這個導演類看作是最終調用的客戶端,那麼圖中剩餘的部分就能夠看做是一個簡單的工廠模式了。get
與工廠模式相比,建造者模式通常用來建立更爲複雜的對象,由於對象的建立過程更爲複雜,所以將對象的建立過程獨立出來組成一個新的類——導演類。也就是說,工廠模式是將對象的所有建立過程封裝在工廠類中,由工廠類向客戶端提供最終的產品;而建造者模式中,建造者類通常只提供產品類中各個組件的建造,而將具體建造過程交付給導演類。由導演類負責將各個組件按照特定的規則組建爲產品,而後將組建好的產品交付給客戶端。
總結
建造者模式與工廠模式相似,他們都是建造者模式,適用的場景也很類似。通常來講,若是目標實例(產品)的建造很複雜,那麼請用工廠模式;若是目標實例(產品)的建造更復雜,那麼請用建造者模式。