本文主要介紹了 Builder的用法。分享給大家參考之用。具體如下:
最近在看Mybatis
的源碼, 在閱讀解析 XML
設定檔的過程中, 發現使用到了建造者(Builder)模式。因此, 打算重溫該設計模式。
假設我們需要畫一個小人, 我們可能會有以下的建構子定義:
public Person(HeadType headType, HairType hairType, HairColor hairColor, FaceType faceType, BodyType bodyType, ArmType amrType, LegType legTyype) { }
看到這麼一個建構函數, 估計我們自己以後回來看的時候都懵了, 這麼多參數, 導致我們後續的維護也很麻煩。
而建構模式就可以解決這類的問題。
目標是畫一個小人
Builder
先定義抽象的PersonBuilder
。這個類別定義了畫小人需要的步驟, 這樣每個透過PersonBuilder
產生的物件本質上就都是一樣的了, 只不過個性上可以不一樣。
abstract class PersonBuilder { protected Graphics graphics; public PersonBuilder(Graphics graphics) { this.graphics = graphics; } public abstract void buildHead(); public abstract void buildBody(); public abstract void buildArmLeft(); public abstract void buildArmRight(); public abstract void buildLegLeft(); public abstract void buildLegRight(); }
Builder
類別在定義一個特定的實作類別PersonFatBuilder
。類別繼承PersonBuilder
, 並實作了抽象方法。
public class PersonFatBuilder extends PersonBuilder { public PersonFatBuilder(Graphics graphics) { super(graphics); } @Override public void buildHead() { graphics.drawOval(50, 20, 30, 30); graphics.drawArc(50, 30, 10, 5, 45, 135); graphics.drawArc(70, 30, 10, 5, 45, 135); graphics.drawArc(60, 35, 10, 5, 200, 135); } @Override public void buildBody() { graphics.drawRect(55, 50, 20, 50); } @Override public void buildArmLeft() { graphics.drawLine(55, 50, 40, 100); } @Override public void buildArmRight() { graphics.drawLine(75, 50, 90, 100); } @Override public void buildLegLeft() { graphics.drawLine(55, 100, 45, 150); } @Override public void buildLegRight() { graphics.drawLine(75, 100, 85, 150); } }
Director
類別該類別負責特定的建造過程, 對建成什麼樣不關心。
public class PersonDirector { private PersonBuilder personBuilder; public PersonDirector(PersonBuilder personBuilder) { this.personBuilder = personBuilder; } public void drawPerson() { personBuilder.buildHead(); personBuilder.buildBody(); personBuilder.buildArmLeft(); personBuilder.buildArmRight(); personBuilder.buildLegLeft(); personBuilder.buildLegRight(); } }
建立一個窗口,將小人畫出來。
public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { // 创建窗口对象 JFrame frame = new JFrame(); frame.setVisible(true); frame.setTitle("画人"); frame.setSize(250, 300); // 设置窗口关闭按钮的默认操作(点击关闭时退出进程) frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 把窗口位置设置到屏幕的中心 frame.setLocationRelativeTo(null); frame.setContentPane(new JPanel(){ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); PersonThinBuilder thinBuilder = new PersonThinBuilder(g); PersonDirector director = new PersonDirector(thinBuilder); director.drawPerson(); } }); } }); }
結果如下:
將複雜物件的建構與它的表示分離, 使得同樣的建構過程可以創造不同的表示。
換句話說, 讓你創造不同種類的對象, 同時又能避免建構函數的污染。當物件有多種類型時, 此模式非常有用。或是在創建物件時涉及到很多的步驟。
引用《大話設計模式》的一個圖
抽象類別Builder
:為創建Product
物件而抽象的介面。
繼承類別ConcreateBuilder
:具體的建造者, 建構和組裝各個元件。
具體產品類別Product
:我們需要建造的物件。
Director
: 用來建立產品的, 其內部有Builder
類型的成員變數。
Director
不需要知道 Product
的內部細節, 它只提供所需的資訊給建造者,由具體的建造者ConcreateBuilder
處理從而完成產品的建構。
建造者模式將複雜的產品創建過程分散到了不同的物件中, 從而實現對產品創建過程更精確的控制, 創建過程更加清晰。
每個特定的建造者都可以創造出完整的產品對象, 而且是相互獨立的。因此, 調用端可以透過不同的具體建造者就可以得到不同的物件。當有新的產品出現時, 不需要改變原有程式碼, 只需要增加一個建造者即可。
現在如果我們想建造一個胖小人,有五官的。那我們只需要加入一個PersonFatBuilder
類別就可以了, 不需要改原有程式碼。
public class PersonFatBuilder extends PersonBuilder { public PersonFatBuilder(Graphics graphics) { super(graphics); } @Override public void buildHead() { graphics.drawOval(50, 20, 30, 30); graphics.drawArc(50, 30, 10, 5, 45, 135); graphics.drawArc(70, 30, 10, 5, 45, 135); graphics.drawArc(60, 35, 10, 5, 200, 135); } @Override public void buildBody() { graphics.drawRect(55, 50, 20, 50); } @Override public void buildArmLeft() { graphics.drawLine(55, 50, 40, 100); } @Override public void buildArmRight() { graphics.drawLine(75, 50, 90, 100); } @Override public void buildLegLeft() { graphics.drawLine(55, 100, 45, 150); } @Override public void buildLegRight() { graphics.drawLine(75, 100, 85, 150); } }
結果:
相關推薦:
【oracle教學】Starting with Oracle Warehouse Builder 11g Rel
yii Query Builder (yii 查詢建構器) 官方指南翻譯
以上是Java設計模式-建造者(Builder)模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!