設(shè)計(jì)模式之簡(jiǎn)單工廠模式(Simple Factory Pattern)
2024-07-21 02:16:29
供稿:網(wǎng)友
 
工廠模式
the factory pattern
 
 在面向?qū)ο螅╫o)程序中,我們經(jīng)常看到的一種模式就是簡(jiǎn)單工廠模式(simple factory pattern)。簡(jiǎn)單工廠模式根據(jù)提供給它的數(shù)據(jù),返回幾個(gè)可能類中的一個(gè)類的實(shí)例。通常它返回的類都有一個(gè)共同的父類和共同的方法,但每個(gè)方法執(zhí)行的認(rèn)為不同,而且根據(jù)不同的數(shù)據(jù)進(jìn)行了優(yōu)化。簡(jiǎn)單工廠模式實(shí)際上不屬于23個(gè)gof模式,但它可以作為工廠方法模式(factory method)的一個(gè)引導(dǎo)。
 
工廠模式如何工作
 
為了便于理解簡(jiǎn)單工廠模式,可以看下圖: 
工廠類(creator)角色:該角色是工廠方法模式的核心,含有按照一定商業(yè)邏輯創(chuàng)建產(chǎn)品。工廠類在客戶端的直接調(diào)用下創(chuàng)建產(chǎn)品對(duì)象,它往往由一個(gè)具體類實(shí)現(xiàn)。
抽象產(chǎn)品(product)角色:擔(dān)任這個(gè)角色的類是工廠方法模式所創(chuàng)建的對(duì)象的父類,或它們共同擁有的接口。抽象產(chǎn)品角色可以用一個(gè)接口或者抽象類實(shí)現(xiàn)。
具體產(chǎn)品(concrete product)角色:工廠方法模式所創(chuàng)建的任何對(duì)象都是這個(gè)角色的實(shí)例,具體產(chǎn)品角色由一個(gè)具體類實(shí)現(xiàn)。
 
 在上圖中,類x為一個(gè)基類,類xy和xz派生自類x, xfactory類根據(jù)你提供給它的值來(lái)決定返回那個(gè)子類的實(shí)例,我們定義了getclass方法,接受一些值,并根據(jù)這個(gè)值返回x類的其中一個(gè)實(shí)例。返回它們當(dāng)中的哪一個(gè)與程序員無(wú)關(guān)。因?yàn)樗鼈兌己邢嗤姆椒ǎ遣煌膶?shí)現(xiàn),它可能是很復(fù)雜的功能,但通常都很簡(jiǎn)單。
類
 現(xiàn)在,我們寫兩個(gè)簡(jiǎn)單的類,用于實(shí)現(xiàn)將一個(gè)字符串分割為兩部分,假設(shè)我們有一個(gè)輸入窗體,允許用戶輸入他的姓名,可我們通過(guò)簡(jiǎn)單工廠模式namefactory類來(lái)自動(dòng)判斷用戶輸入的firstname和lastname之間到底是空格還是逗號(hào)。如果是逗號(hào)或空格我們就將其分割為兩部分。
 先定義一個(gè)簡(jiǎn)單的類。
public class nameclass
 protected lname, frname as string
 
 public function getfirst() as string
 return frname
 end function
 
 public function getlast() as string
 return lname
 end function
end class
下面編寫兩個(gè)派生類: 
firstfirst類、lastfirst類
它們實(shí)現(xiàn)了基類nameclass,并在構(gòu)造函數(shù)中將名字分成了兩部分。
 
firstfirst類
 
public class firstfirst
 inherits nameclass
 public sub new(byval nm as string)
 dim i as integer
 i = nm.indexof(" ")
 if i > 0 then
 frname = nm.substring(0, i).trim()
 lname = nm.substring(i + 1).trim()
 else
 frname = ""
 lname = nm
 end if
 end sub
end class
 
lastfirst類
 
public class lastfirst
 inherits nameclass
 public sub new(byval nm as string)
 dim i as integer
 i = nm.indexof(",")
 if i > 0 then
 lname = nm.substring(0, i).trim()
 frname = nm.substring(i + 1).trim()
 else
 frname = ""
 lname = nm
 end if
 end sub
end class
 
構(gòu)造簡(jiǎn)單工廠
 
 現(xiàn)在很容易給出簡(jiǎn)單工廠類。只檢測(cè)逗號(hào)是否存在,然后返回其中的一個(gè)類的實(shí)例。
 
public class namefactory
 public function getnamer( _
 byval nm as string) as nameclass
 dim i as integer
 i = nm.indexof(",")
 if i > 0 then
 return new lastfirst(nm)
 else
 return new firstfirst(nm)
 end if
 end function
end class
 
使用簡(jiǎn)單工廠
 
 我們具體實(shí)現(xiàn)如下:
 
 "執(zhí)行"按鈕的 click事件:
 
 dim nm as string
 dim i as integer
 nm = txname.text
 dim nmer as nameclass
 nmer = new namefactory().getnamer(nm)
 txlast.text = nmer.getlast()
 txfirst.text = nmer.getfirst() 
 
 我們已經(jīng)構(gòu)造了一個(gè)簡(jiǎn)單的用戶接口,并且允許用戶輸入名字。運(yùn)行如圖:
 
 
用戶輸入名字然后點(diǎn)擊”執(zhí)行”按鈕,這個(gè)名字被namefactory接收,并根據(jù)不同的類型(由逗號(hào)、空格分隔),返回不同子類的實(shí)例。這里不需要知道使用的是哪一個(gè)派生類的實(shí)例,工廠(namefactory)為我們提供了這個(gè)類,所需要知道的就是它有兩個(gè)(getfirst、getlast)方法。這就是我們所說(shuō)的隱藏了具體類。