初步認知:建造者模式
阿新 • • 發佈:2018-12-14
在講述這個模式之前,我們先看一個案例:建造小人(只需要建造的小人有頭、身子、四肢即可)
public class DrawPeople extends JFrame { //DrawSee構造方法 public DrawPeople() { setBounds(0, 0, 500, 500);//窗體起始位置 setVisible(true);//窗體是否可見 setLayout(null); //窗體佈局 setResizable(false);//窗體是否可進行拖動設定大小 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } // 獲取專門用於在視窗介面上繪圖的物件 Graphics jg = this.getGraphics(); // 繪製區域 paintComponents(jg); } //畫一個人 public void paintComponents(Graphics g) {try { g.drawArc(150, 50, 30, 30, 0, 360);//畫頭 g.drawArc(145, 80, 40, 50, 0, 360);//畫身子 g.drawLine(150, 80, 130, 130); g.drawLine(180, 80, 200, 130); g.drawLine(160, 130, 145, 180); g.drawLine(170, 130, 185, 180); } catch (Exception e) { e.printStackTrace(); } } } 測試方法public class Test { public static void main(String[] args) { new DrawPeople(); } }
繪製結果如下圖所示
那我現在需要繪製一個比較瘦的人,怎麼辦?
正常程式設計師都會想:這還不簡單,把這個類複製一份,把繪製引數改下不就行了。
那萬一複製的時候少複製了一行,讓小人缺胳膊少腿怎麼辦?
這對一個人來說可是巨大的損失,誰都不想讓身體殘缺不全。這個問題怎麼解決呢?
下面介紹建造者模式:http://www.runoob.com/design-pattern/builder-pattern.html
將一個複雜物件的構建與他的表示分離,使得同樣的構建過程可以建立不同的表示。
那怎麼用建造者模式呢?
以畫小人為例,我們需要畫頭、身體、左手、右手、左腳、右腳,所以我們先定義一個抽象的建造人的類,把這個過程穩定住,不讓任何人遺忘當中的任何一步。
public interface PersonBuilder { public abstract void buildHead(); public abstract void buildBody(); public abstract void buildArmLeft(); public abstract void buildArmRight(); public abstract void buildLegLeft(); public abstract void buildLegRight(); }
然後我們需要建造一個胖的人,就讓這個胖子類取繼承這個抽象類,那就必須去重寫這些抽象方法了,否則編譯器也不讓你通過。
public class PersonFatBuilder extends JFrame implements PersonBuilder{ private Graphics g; public PersonFatBuilder() { setBounds(0, 0, 500, 500);//窗體起始位置 setVisible(true);//窗體是否可見 setLayout(null); //窗體佈局 setResizable(false);//窗體是否可進行拖動設定大小 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } // 獲取專門用於在視窗介面上繪圖的物件 this.g = this.getGraphics(); // 繪製遊戲區域 paintComponents(this.g); } @Override public void buildHead() { g.drawArc(150, 50, 30, 30, 0, 360);//畫頭 } @Override public void buildBody() { g.drawArc(145, 80, 40, 50, 0, 360);//畫身子 } @Override public void buildArmLeft() { g.drawLine(150, 80, 130, 130); } @Override public void buildArmRight() { g.drawLine(180, 80, 200, 130); } @Override public void buildLegLeft() { g.drawLine(160, 130, 145, 180); } @Override public void buildLegRight() { g.drawLine(170, 130, 185, 180); } }
瘦子類也是用類似的程式碼去實現這個類就可以了。
但現在只是保證胖子類擁有了頭身手腳方法,但依然無法保證這些方法一定會被呼叫,怎麼辦?
我們還缺少建造者模式中一個重要的類,指揮者(Director),用它來控制建造過程,也用它來隔離使用者與建造過程的關聯。
public class PersonDirector { private PersonBuilder pb; //使用者告訴指揮者,我需要什麼樣的小人 public PersonDirector(PersonBuilder pb){ this.pb = pb; } //根據使用者的選擇建造小人 public void createPerson(){ pb.buildHead(); pb.buildBody(); pb.buildArmLeft(); pb.buildArmRight(); pb.buildLegLeft(); pb.buildLegRight(); } }
測試方法
public class Test { public static void main(String[] args) { PersonFatBuilder pfb = new PersonFatBuilder(); PersonDirector pd = new PersonDirector(pfb); pd.createPerson(); } }
PersonDirector類的目的就是根據使用者的選擇來一步步建造小人,而建造的過程在指揮者這裡完成,使用者就不需要知道了,而且,每個建造過程都是一定要做的,保證了建造流程的正確性,這樣,缺胳膊少腿的情況就不會出現了。
做個比喻:Builder像是圖紙,PersonFatBuilder是具體的施工人員,PersonDirector就是個監工,保證施工過程正確有序。