设计模式:(生成器模式)
1.定義
建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個復雜的對象。這種類型的設計模式屬于創建型模式,它提供了一種創建對象的最佳方式。
一個 Builder 類會一步一步構造最終的對象。該 Builder 類是獨立于其他對象的。
簡單來說:生成器模式就是將一個復雜對象的構建與它的使用分離,使用同樣的構建過程可以創建不同的表示。
2.概述
如果一個類中有若干個成員變量是其他類聲明的對象,那么該類創建的對象就可以包含若干個其他對象作為其成員。習慣上把一個對象中的成員對象稱作為它中的組件。
例如,Geometry類中含有Triangle、Rectangle和Circle類聲明的對象,那么Geometry類就可以創建一個由三角形、矩形和圓形成的幾何圖形,三角形,矩形和圓形就是當前幾何圖形中的組件。
但是,在編寫Geometry類的構造方法的代碼時可能遇到如下的問題:
1.有些用戶并不需要Geometry類所創建的對象含有其全部組件,即不希望當前圖形實例化它含有的全部組件,如果在Geometry類的構造方法中創建了Triangle、Rectangle和Circle聲明的對象就無法滿足這些用戶的需求。
2.有些用戶對所創建的Geometry對象中的組件是由特殊的要求,比如某個用戶要求Geometry對象中的三角形是等邊的,矩形是正方的;某個用戶要求Geometry對象中三角形必須是直角的,等等。
顯然,如果一個對象由很多組件構造,我們無法在構造方法中進行硬編碼來滿足各種用戶對組件結構的要求。
因此,按著面向抽象的原則,我們不應該在Geometry類的構造方法中進行任何的編碼,而是將Geometry對象的構造過程分成若干個步驟,即根據當前組件的個數,在一個接口中定義若干個方法,每個方法負責創建Geometry對象的一個組件,而實現該接口的類將負責創建Geometry對象,也就是說,將Geometry對象的創建過程封裝在另一個類中。
3.應用場景
1、需要生成的對象具有復雜的內部結構。
2、需要生成的對象內部屬性本身相互依賴。
4.模式的結構與使用
生成器模式的結構中包括四種角色。
1.產品(product):具體生成器要構造的復雜對象;
2.抽象生成器(Builder):抽象生成器是一個接口,該接口除了為創建一個Product對象的各個組件定義了若干個方法外,還要定義返回Product對象的方法;
3. 具體生成器(ConcreteBuilder):實現了Builder接口的類,具體生成器將實現Builder接口所定義的方法。;
4. 指揮者(Director):指揮者是一個類,該類需含有Builder接口聲明的變量。指揮者的職責是負責向用戶提供具體生成器,即指揮者將請求具體生成器來構造用戶所需要的Product對象,如果所請求的具體對象生成器成功德構造出Product對象,指揮者就可以讓該具體生成器返回所構造的Product對象。
1.生成器模式的UML類圖
2.結構的描述
以下通過一個簡單的問題來描述生成器模式所涉及的各個角色。
這個簡單的問題就是創建含有按鈕,標簽和文本框組件的容器。不同用戶對容器有不同的要求,比如某些用戶希望容器中只含有按鈕和標簽(不含文本框),某些用戶希望容器只含有按鈕和文本框(不含標簽)等。另外,用戶對組件在容器中的順序位置也有不同的要求,比如某些用戶要求組件在容積中從左到右的排列順序是按鈕,標簽,文本框,而某些用戶要求從左到右的排列順序是標簽,文本框,按鈕等。
顯然不能再容器的構造方法中編寫有關創建按鈕,標簽和文本框的代碼,也不能編寫排列這些組件位置的代碼。以下使用生成器模式為用戶創建所需要的容器,具體如下所示:
1.產品(Product)
產品角色是PanelProduct類,該類的代碼如下:
在該類定義了三個組件,包括按鈕,標簽以及文本框,在該類沒有定義構造函數。
2.抽象生成器(Builder)
抽象生成器是Builder接口,其代碼如下所示:
在里面分別定義了實例化組件的方法,以及得到一個由各組件組合生成的JPanel 方法。
3.具體生成器(Concretebuilder)
這里主要有兩個生成器ConcreteBuilderOne與ConcreteBuilderTwo類,代碼如下所示:
在里面實現了Builder接口,重寫了Builder的抽象方法,以及得到一個具體擁有自己個性化組件順序的getPanel()方法。
ConcreteBuilderOne.java
ConcreteBuilderTwo.java
import javax.swing.*; public class ConcreteBuilderTwo implements Builder{private PanelProduct panel;//容器public ConcreteBuilderTwo() {this.panel = new PanelProduct();}@Overridepublic void buildButton() {panel.button=new JButton("button");}@Overridepublic void buildLabel() {panel.label=new JLabel("label");}@Overridepublic void buildTextField() {panel.textField=new JTextField("textLabel");}@Overridepublic JPanel getPanel() {panel.add(panel.textField);panel.add(panel.label);panel.add(panel.button);return panel;} }4.指揮者
指揮者是Director類,代碼如下所示:
在該類中引用了Builder變量,通過該抽象變量的getPanel()方法得到具體的具有個性化的組件組合的排列順序。
5.測試程序
import javax.swing.*; public class Application {public static void main(String[] args) {Builder builder=new ConcreteBuilderOne();Director director = new Director(builder);JPanel panel = director.constructProduct();JFrame frameOne=new JFrame();frameOne.add(panel);frameOne.setBounds(12,12,200,120);frameOne.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);frameOne.setVisible(true);builder=new ConcreteBuilderTwo();director=new Director(builder);panel=director.constructProduct();JFrame jFrameTwo=new JFrame();jFrameTwo.add(panel);jFrameTwo.setBounds(212,12,200,120);jFrameTwo.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);jFrameTwo.setVisible(true);} }6.結果展示
5.生成器模式的優點
1.生成器模式將對象的構建過程封裝在具體生成器中,用戶使用不同的具體生成器就可以得到該對象的不同表示。
2.生成器模式將對象的構建過程從創建該對象的類中分離出來,使的用戶無須了解該對象的具體組件內。
3.可以更加精細有效地控制對象的構造過程。生成器將對象的構造過程分解到若干個步驟,這就使程序可以更加精細,有效地控制整個對象的構造。
4.生成器模式將對象的構造過程與創建該對象類解耦,使對象的創建更加靈活有彈性。
5.當增加新的具體生成器時,不必修改指揮者的代碼,即該模式滿足開閉原則。
總結
以上是生活随笔為你收集整理的设计模式:(生成器模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FFmpeg连载2-分离视频和音频
- 下一篇: 设计模式之-生成器模式