设计模式:(生成器模式)
1.定義
建造者模式(Builder Pattern)使用多個(gè)簡(jiǎn)單的對(duì)象一步一步構(gòu)建成一個(gè)復(fù)雜的對(duì)象。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。
一個(gè) Builder 類(lèi)會(huì)一步一步構(gòu)造最終的對(duì)象。該 Builder 類(lèi)是獨(dú)立于其他對(duì)象的。
簡(jiǎn)單來(lái)說(shuō):生成器模式就是將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的使用分離,使用同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。
2.概述
如果一個(gè)類(lèi)中有若干個(gè)成員變量是其他類(lèi)聲明的對(duì)象,那么該類(lèi)創(chuàng)建的對(duì)象就可以包含若干個(gè)其他對(duì)象作為其成員。習(xí)慣上把一個(gè)對(duì)象中的成員對(duì)象稱(chēng)作為它中的組件。
例如,Geometry類(lèi)中含有Triangle、Rectangle和Circle類(lèi)聲明的對(duì)象,那么Geometry類(lèi)就可以創(chuàng)建一個(gè)由三角形、矩形和圓形成的幾何圖形,三角形,矩形和圓形就是當(dāng)前幾何圖形中的組件。
但是,在編寫(xiě)Geometry類(lèi)的構(gòu)造方法的代碼時(shí)可能遇到如下的問(wèn)題:
1.有些用戶(hù)并不需要Geometry類(lèi)所創(chuàng)建的對(duì)象含有其全部組件,即不希望當(dāng)前圖形實(shí)例化它含有的全部組件,如果在Geometry類(lèi)的構(gòu)造方法中創(chuàng)建了Triangle、Rectangle和Circle聲明的對(duì)象就無(wú)法滿(mǎn)足這些用戶(hù)的需求。
2.有些用戶(hù)對(duì)所創(chuàng)建的Geometry對(duì)象中的組件是由特殊的要求,比如某個(gè)用戶(hù)要求Geometry對(duì)象中的三角形是等邊的,矩形是正方的;某個(gè)用戶(hù)要求Geometry對(duì)象中三角形必須是直角的,等等。
顯然,如果一個(gè)對(duì)象由很多組件構(gòu)造,我們無(wú)法在構(gòu)造方法中進(jìn)行硬編碼來(lái)滿(mǎn)足各種用戶(hù)對(duì)組件結(jié)構(gòu)的要求。
因此,按著面向抽象的原則,我們不應(yīng)該在Geometry類(lèi)的構(gòu)造方法中進(jìn)行任何的編碼,而是將Geometry對(duì)象的構(gòu)造過(guò)程分成若干個(gè)步驟,即根據(jù)當(dāng)前組件的個(gè)數(shù),在一個(gè)接口中定義若干個(gè)方法,每個(gè)方法負(fù)責(zé)創(chuàng)建Geometry對(duì)象的一個(gè)組件,而實(shí)現(xiàn)該接口的類(lèi)將負(fù)責(zé)創(chuàng)建Geometry對(duì)象,也就是說(shuō),將Geometry對(duì)象的創(chuàng)建過(guò)程封裝在另一個(gè)類(lèi)中。
3.應(yīng)用場(chǎng)景
1、需要生成的對(duì)象具有復(fù)雜的內(nèi)部結(jié)構(gòu)。
2、需要生成的對(duì)象內(nèi)部屬性本身相互依賴(lài)。
4.模式的結(jié)構(gòu)與使用
生成器模式的結(jié)構(gòu)中包括四種角色。
1.產(chǎn)品(product):具體生成器要構(gòu)造的復(fù)雜對(duì)象;
2.抽象生成器(Builder):抽象生成器是一個(gè)接口,該接口除了為創(chuàng)建一個(gè)Product對(duì)象的各個(gè)組件定義了若干個(gè)方法外,還要定義返回Product對(duì)象的方法;
3. 具體生成器(ConcreteBuilder):實(shí)現(xiàn)了Builder接口的類(lèi),具體生成器將實(shí)現(xiàn)Builder接口所定義的方法。;
4. 指揮者(Director):指揮者是一個(gè)類(lèi),該類(lèi)需含有Builder接口聲明的變量。指揮者的職責(zé)是負(fù)責(zé)向用戶(hù)提供具體生成器,即指揮者將請(qǐng)求具體生成器來(lái)構(gòu)造用戶(hù)所需要的Product對(duì)象,如果所請(qǐng)求的具體對(duì)象生成器成功德構(gòu)造出Product對(duì)象,指揮者就可以讓該具體生成器返回所構(gòu)造的Product對(duì)象。
1.生成器模式的UML類(lèi)圖
2.結(jié)構(gòu)的描述
以下通過(guò)一個(gè)簡(jiǎn)單的問(wèn)題來(lái)描述生成器模式所涉及的各個(gè)角色。
這個(gè)簡(jiǎn)單的問(wèn)題就是創(chuàng)建含有按鈕,標(biāo)簽和文本框組件的容器。不同用戶(hù)對(duì)容器有不同的要求,比如某些用戶(hù)希望容器中只含有按鈕和標(biāo)簽(不含文本框),某些用戶(hù)希望容器只含有按鈕和文本框(不含標(biāo)簽)等。另外,用戶(hù)對(duì)組件在容器中的順序位置也有不同的要求,比如某些用戶(hù)要求組件在容積中從左到右的排列順序是按鈕,標(biāo)簽,文本框,而某些用戶(hù)要求從左到右的排列順序是標(biāo)簽,文本框,按鈕等。
顯然不能再容器的構(gòu)造方法中編寫(xiě)有關(guān)創(chuàng)建按鈕,標(biāo)簽和文本框的代碼,也不能編寫(xiě)排列這些組件位置的代碼。以下使用生成器模式為用戶(hù)創(chuàng)建所需要的容器,具體如下所示:
1.產(chǎn)品(Product)
產(chǎn)品角色是PanelProduct類(lèi),該類(lèi)的代碼如下:
在該類(lèi)定義了三個(gè)組件,包括按鈕,標(biāo)簽以及文本框,在該類(lèi)沒(méi)有定義構(gòu)造函數(shù)。
2.抽象生成器(Builder)
抽象生成器是Builder接口,其代碼如下所示:
在里面分別定義了實(shí)例化組件的方法,以及得到一個(gè)由各組件組合生成的JPanel 方法。
3.具體生成器(Concretebuilder)
這里主要有兩個(gè)生成器ConcreteBuilderOne與ConcreteBuilderTwo類(lèi),代碼如下所示:
在里面實(shí)現(xiàn)了Builder接口,重寫(xiě)了Builder的抽象方法,以及得到一個(gè)具體擁有自己個(gè)性化組件順序的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類(lèi),代碼如下所示:
在該類(lèi)中引用了Builder變量,通過(guò)該抽象變量的getPanel()方法得到具體的具有個(gè)性化的組件組合的排列順序。
5.測(cè)試程序
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.結(jié)果展示
5.生成器模式的優(yōu)點(diǎn)
1.生成器模式將對(duì)象的構(gòu)建過(guò)程封裝在具體生成器中,用戶(hù)使用不同的具體生成器就可以得到該對(duì)象的不同表示。
2.生成器模式將對(duì)象的構(gòu)建過(guò)程從創(chuàng)建該對(duì)象的類(lèi)中分離出來(lái),使的用戶(hù)無(wú)須了解該對(duì)象的具體組件內(nèi)。
3.可以更加精細(xì)有效地控制對(duì)象的構(gòu)造過(guò)程。生成器將對(duì)象的構(gòu)造過(guò)程分解到若干個(gè)步驟,這就使程序可以更加精細(xì),有效地控制整個(gè)對(duì)象的構(gòu)造。
4.生成器模式將對(duì)象的構(gòu)造過(guò)程與創(chuàng)建該對(duì)象類(lèi)解耦,使對(duì)象的創(chuàng)建更加靈活有彈性。
5.當(dāng)增加新的具體生成器時(shí),不必修改指揮者的代碼,即該模式滿(mǎn)足開(kāi)閉原則。
總結(jié)
以上是生活随笔為你收集整理的设计模式:(生成器模式)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: FFmpeg连载2-分离视频和音频
- 下一篇: as400 c语言程序,AS400上的C