(Builder)建造者模式的Java实现
生活随笔
收集整理的這篇文章主要介紹了
(Builder)建造者模式的Java实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
建造者模式(Builder):將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 使用場景: 1、當創建復雜對象的算法應該獨立于該對象的組成部分以及它們的裝配方式時。 2、當構造過程必須允許被構造的對象有不同的表示時。 通用類圖: ? 舉例:我們生活當中有許多設備都是以組裝的形式存在的,例如臺式電腦,那么有些廠商就會推出一些具有默認配置的組裝電腦主機(這里可以用到模板方法模式來實現),顧客可以購買默認配置的產品,也可以要求廠商重新組裝一部不同配置不同組裝方式的主機。此時,我們就可以使用建造者模式來滿足特殊顧客的要求了。 注意到這個例子中廠商是重新組裝一部主機,即關注點是主機的每個組成部分,這就符合上面Builder模式給出的使用場景了。 具體類圖如下: 簡單代碼實現如下: //抽象產品類,使用了模板方法模式,不同產品有不同的“組成部分part”?
abstract?class?AbstractProduct{?
??protected?abstract?void?part01();?
??protected?abstract?void?part02();?
??protected?abstract?void?part03();?
????
??//模板方法給出了默認的組裝方式,生成默認的產品?
??public?final?AbstractProduct defaultProduct() {?
????part01();?
????part02();?
????part03();?
????return?this;//返回當前對象,即默認組裝方式的產品?
??}?
}?
//具體的產品A、B,不同產品實現了不同的“組成部分part”?
class?ConcreteProductA?extends?AbstractProduct{?
??protected?void?part01() {?
????System.out.println("產品A :part01() ...");?
??}?
??protected?void?part02() {?
????System.out.println("產品A :part02() ...");?
??}?
??protected?void?part03() {?
????System.out.println("產品A :part03() ...");?
??}?
}?
class?ConcreteProductB?extends?AbstractProduct{?
??protected?void?part01() {?
????System.out.println("產品B :part01() ...");?
??}?
??protected?void?part02() {?
????System.out.println("產品B :part02() ...");?
??}?
??protected?void?part03() {?
????System.out.println("產品B :part03() ...");?
??}?
}?
//抽象建造者,制定每一種產品應該實現的組合方式buildPart()和生產buildProduct()的標準?
abstract?class?AbstractBuilder{?
??public?abstract?void?buildPart();?
??public?abstract?AbstractProduct buildProduct();?
}?
/*?
* 具體建造者,如果對于默認產品(即當調用抽象產品中的defaultProduct()方法)不滿意時,?
* 可以不調用它來獲得產品,而是使用具體的建造者來改變產品的生產組裝方式,以得到不同的產品?
*/?
class?ConcreteBuilderA?extends?AbstractBuilder{?
??private?AbstractProduct productA =?new?ConcreteProductA();?
????
??public?void?buildPart() {?
????this.productA.part03();?
????this.productA.part02();?
????this.productA.part01();?
??}?
????
??public?AbstractProduct buildProduct() {?
????return?this.productA;?
??}?
}?
class?ConcreteBuilderB?extends?AbstractBuilder{?
??private?AbstractProduct productB =?new?ConcreteProductB();?
????
??public?void?buildPart() {?
????this.productB.part02();?
????this.productB.part01();?
????//特地省略掉產品B中的一個組成部分,例如該部分的功能顧客不需要?
//????this.productB.part03();?
??}?
????
??public?AbstractProduct buildProduct() {?
????return?this.productB;?
??}?
}?
//導演類,預先持有各個產品的建造者,為需要不同于默認產品的用戶提供不同的組裝方式?
class?Director{?
??private?AbstractBuilder builderA =?new?ConcreteBuilderA();?
??private?AbstractBuilder builderB =?new?ConcreteBuilderB();????
????
??public?AbstractProduct getProductA() {?
????this.builderA.buildPart();?
????return?this.builderA.buildProduct();?
??}?
????
??public?AbstractProduct getProductB() {?
????this.builderB.buildPart();?
????return?this.builderB.buildProduct();?
??}?
}?
//測試類?
public?class?Client {?
??public?static?void?main(String[] args) {?
????System.out.println("利用模板方法模式獲得默認的產品A");?
????AbstractProduct defualtProductA =?new?ConcreteProductA().defaultProduct();????
?????
????System.out.println("\n利用Director類獲得不同組裝方式的產品A");?
????Director director =?new?Director();?
????director.getProductA();?
?????
????System.out.println("\n利用Director類獲得不同組裝方式的產品B");?
????director.getProductB();?
??}?
} 測試結果:
其實在這個例子當中,產品類那一部分用到了上一篇文章講到的模板方法模式,即defaultProduct()提供了一個產品的默認組成部分的組裝方式。 但是這里我有個疑問,AbstractProduct類中根據模板方法模式提供的的所謂默認組裝方式只是打印出幾句測試的話而已,又不是真正返回一個具體產品,但是上面例子中那樣返回一個當前對象(return?this;)的處理方式不知道是否合理? 另外,在寫了這幾篇關于用Java代碼實現設計模式的文章之后,發現這個建造者Builder模式似乎是結合了抽象工廠模式、模板方法模式。上面一段已經說過我的疑惑,至于抽象工廠模式,我個人是覺得上面代碼例子中的Director類就很類似抽象工廠的具體工廠類了,但是Director類還要負責build一下產品的組裝方式才返回一個產品,也許就是這個“build一下”才顯得建造者模式關注于產品各個部分的組裝,而抽象工廠模式僅僅只是關注于一個最終產品的生成。 之前看過一句話說大概是說:計算機方面的任何一個問題如果難以解決,都可以通過增加一個中間層來處理。現在想了一下,好像Abstract?Factory和Builder模式都是運用了這一“原理”來達到想要的效果。譬如Abstract?Factory中有個抽象工廠類,Builder中有個Director類,說到底也就是封裝隱藏某些細節,并從實現和使用這兩者之間解耦出來吧。 我覺得,一定要先理解了各個模式的關注點和適用場景之后才能更好地把握這些吧。 可能這幾個模式都是創建型的模式而且我沒有什么實戰經驗才會使得我對于這些有點混淆了...不怕,在它們全部實現的過程中一點點思考,慢慢地運用到實際當中去應該就會逐漸明白的了。
本文轉自 xxxx66yyyy 51CTO博客,原文鏈接:http://blog.51cto.com/haolloyin/333155,如需轉載請自行聯系原作者
abstract?class?AbstractProduct{?
??protected?abstract?void?part01();?
??protected?abstract?void?part02();?
??protected?abstract?void?part03();?
????
??//模板方法給出了默認的組裝方式,生成默認的產品?
??public?final?AbstractProduct defaultProduct() {?
????part01();?
????part02();?
????part03();?
????return?this;//返回當前對象,即默認組裝方式的產品?
??}?
}?
//具體的產品A、B,不同產品實現了不同的“組成部分part”?
class?ConcreteProductA?extends?AbstractProduct{?
??protected?void?part01() {?
????System.out.println("產品A :part01() ...");?
??}?
??protected?void?part02() {?
????System.out.println("產品A :part02() ...");?
??}?
??protected?void?part03() {?
????System.out.println("產品A :part03() ...");?
??}?
}?
class?ConcreteProductB?extends?AbstractProduct{?
??protected?void?part01() {?
????System.out.println("產品B :part01() ...");?
??}?
??protected?void?part02() {?
????System.out.println("產品B :part02() ...");?
??}?
??protected?void?part03() {?
????System.out.println("產品B :part03() ...");?
??}?
}?
//抽象建造者,制定每一種產品應該實現的組合方式buildPart()和生產buildProduct()的標準?
abstract?class?AbstractBuilder{?
??public?abstract?void?buildPart();?
??public?abstract?AbstractProduct buildProduct();?
}?
/*?
* 具體建造者,如果對于默認產品(即當調用抽象產品中的defaultProduct()方法)不滿意時,?
* 可以不調用它來獲得產品,而是使用具體的建造者來改變產品的生產組裝方式,以得到不同的產品?
*/?
class?ConcreteBuilderA?extends?AbstractBuilder{?
??private?AbstractProduct productA =?new?ConcreteProductA();?
????
??public?void?buildPart() {?
????this.productA.part03();?
????this.productA.part02();?
????this.productA.part01();?
??}?
????
??public?AbstractProduct buildProduct() {?
????return?this.productA;?
??}?
}?
class?ConcreteBuilderB?extends?AbstractBuilder{?
??private?AbstractProduct productB =?new?ConcreteProductB();?
????
??public?void?buildPart() {?
????this.productB.part02();?
????this.productB.part01();?
????//特地省略掉產品B中的一個組成部分,例如該部分的功能顧客不需要?
//????this.productB.part03();?
??}?
????
??public?AbstractProduct buildProduct() {?
????return?this.productB;?
??}?
}?
//導演類,預先持有各個產品的建造者,為需要不同于默認產品的用戶提供不同的組裝方式?
class?Director{?
??private?AbstractBuilder builderA =?new?ConcreteBuilderA();?
??private?AbstractBuilder builderB =?new?ConcreteBuilderB();????
????
??public?AbstractProduct getProductA() {?
????this.builderA.buildPart();?
????return?this.builderA.buildProduct();?
??}?
????
??public?AbstractProduct getProductB() {?
????this.builderB.buildPart();?
????return?this.builderB.buildProduct();?
??}?
}?
//測試類?
public?class?Client {?
??public?static?void?main(String[] args) {?
????System.out.println("利用模板方法模式獲得默認的產品A");?
????AbstractProduct defualtProductA =?new?ConcreteProductA().defaultProduct();????
?????
????System.out.println("\n利用Director類獲得不同組裝方式的產品A");?
????Director director =?new?Director();?
????director.getProductA();?
?????
????System.out.println("\n利用Director類獲得不同組裝方式的產品B");?
????director.getProductB();?
??}?
} 測試結果:
| 利用模板方法模式獲得默認的產品A 產品A?:part01()?... 產品A?:part02()?... 產品A?:part03()?... 利用Director類獲得不同組裝方式的產品A 產品A?:part03()?... 產品A?:part02()?... 產品A?:part01()?... 利用Director類獲得不同組裝方式的產品B 產品B?:part02()?... 產品B?:part01()?... |
本文轉自 xxxx66yyyy 51CTO博客,原文鏈接:http://blog.51cto.com/haolloyin/333155,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的(Builder)建造者模式的Java实现的全部內容,希望文章能夠幫你解決所遇到的問題。