設計模式詳解——工廠模式(一)

本篇文章介紹一種設計模式——工廠模式。工廠模式是用來封裝對象的創(chuàng)建恨樟,減少應用程序和具體類之間的依賴半醉,促進松耦合。根據(jù)工廠模式的應用特性劝术,一共分為三種子模式:簡單工廠模式缩多,工廠方法模式和抽象工廠模式。本篇文章主要介紹簡單工廠模式养晋。本篇文章內(nèi)容參考《JAVA與模式》之簡單工廠模式衬吆。

一、簡單工廠模式簡介

1.定義

簡單工廠模式(Simple Factory Pattern):又稱為靜態(tài)工廠方法(Static Factory Method)模式绳泉,它屬于類創(chuàng)建型模式逊抡。在簡單工廠模式中,可以根據(jù)參數(shù)的不同返回不同類的實例。簡單工廠模式專門定義一個類來負責創(chuàng)建其他類的實例冒嫡,被創(chuàng)建的實例通常都具有共同的父類拇勃。

2.使用動機

考慮一個簡單的軟件應用場景:一個軟件系統(tǒng)可以提供多個外觀不同的按鈕(如圓形按鈕、矩形按鈕孝凌、菱形按鈕等)方咆, 這些按鈕都源自同一個基類,不過在繼承基類后不同的子類修改了部分屬性從而使得它們可以呈現(xiàn)不同的外觀蟀架。

如果我們希望在使用這些按鈕時瓣赂,不需要知道這些具體按鈕類的名字,只需要知道表示該按鈕類的一個參數(shù)片拍,并提供一個調(diào)用方便的方法煌集,把該參數(shù)傳入方法即可返回一個相應的按鈕對象,此時捌省,就可以使用簡單工廠模式苫纤。

二、簡單工廠模式結(jié)構(gòu)

1.模式結(jié)構(gòu)

簡單工廠模式包含如下角色:

●Factory:工廠角色
工廠角色負責實現(xiàn)創(chuàng)建所有實例的內(nèi)部邏輯

●Product:抽象產(chǎn)品角色
抽象產(chǎn)品角色是所創(chuàng)建的所有對象的父類所禀,負責描述所有實例所共有的公共接口

●ConcreteProduct:具體產(chǎn)品角色
具體產(chǎn)品角色是創(chuàng)建目標方面,所有創(chuàng)建的對象都充當這個角色的某個具體類的實例。

2.時序圖

①先調(diào)用工廠類中的靜態(tài)方法createProduct()

②根據(jù)傳入產(chǎn)品類型參數(shù)色徘,獲得具體的產(chǎn)品對象

③返回產(chǎn)品對象并使用

三、簡單工廠的使用實例

以登錄功能來說操禀,假如應用系統(tǒng)需要支持多種登錄方式如:口令認證褂策、域認證(口令認證通常是去數(shù)據(jù)庫中驗證用戶,而域認證則是需要到微軟的域中驗證用戶)颓屑。那么自然的做法就是建立一個各種登錄方式都適用的接口斤寂,如下圖所示:


抽象產(chǎn)品Login

public interface Login {
    //登錄驗證
    public boolean verify(String name , String password);
}

具體產(chǎn)品DomainLogin

public class DomainLogin implements Login {

    @Override
    public boolean verify(String name, String password) {
        // TODO Auto-generated method stub
        /**
         * 業(yè)務邏輯
         */
        return true;
    }
}

**具體產(chǎn)品PasswordLogin **

public class PasswordLogin implements Login {

    @Override
    public boolean verify(String name, String password) {
        // TODO Auto-generated method stub
        /**
         * 業(yè)務邏輯
         */
        return true;
    }
}

工廠類LoginManager
根據(jù)調(diào)用者不同的要求,創(chuàng)建出不同的登錄對象并返回揪惦。而如果碰到不合法的要求遍搞,會返回一個Runtime異常。

public class LoginManager {
    public static Login factory(String type){
        if(type.equals("password")){
            
            return new PasswordLogin();
            
        }else if(type.equals("passcode")){
            
            return new DomainLogin();
            
        }else{
            /**
             * 這里拋出一個自定義異常會更恰當
             */
            throw new RuntimeException("沒有找到登錄類型");
        }
    }
}

測試調(diào)用

public class Test {
    public static void main(String[] args) {
        String loginType = "password";
        String name = "name";
        String password = "password";
        Login login = LoginManager.factory(loginType);
        boolean bool = login.verify(name, password);
        if (bool) {
            /**
             * 業(yè)務邏輯
             */
        } else {
            /**
             * 業(yè)務邏輯
             */
        }
    }
}

假如不使用簡單工廠模式則驗證登錄Servlet代碼如下:

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        String loginType = "password";
        String name = "name";
        String password = "password";
        //處理口令認證
        if(loginType.equals("password")){
            PasswordLogin passwordLogin = new PasswordLogin();
            boolean bool = passwordLogin.verify(name, password);
            if (bool) {
                /**
                 * 業(yè)務邏輯
                 */
            } else {
                /**
                 * 業(yè)務邏輯
                 */
            }
        }
        //處理域認證
        else if(loginType.equals("passcode")){
            DomainLogin domainLogin = new DomainLogin();
            boolean bool = domainLogin.verify(name, password);
            if (bool) {
                /**
                 * 業(yè)務邏輯
                 */
            } else {
                /**
                 * 業(yè)務邏輯
                 */
            }    
        }else{
            /**
             * 業(yè)務邏輯
             */
        }
    }
}

可以看到非常麻煩器腋,代碼重復很多溪猿,而且不利于擴展維護。

四纫塌、簡單工廠模式優(yōu)缺點

優(yōu)點:

通過使用工廠類诊县,外界不再需要關心如何創(chuàng)造各種具體的產(chǎn)品,只要提供一個產(chǎn)品的名稱作為參數(shù)傳給工廠措左,就可以直接得到一個想要的產(chǎn)品對象依痊,并且可以按照接口規(guī)范來調(diào)用產(chǎn)品對象的所有功能(方法)。

構(gòu)造容易怎披,邏輯簡單胸嘁。

缺點:

1.簡單工廠模式中的if else判斷非常多瓶摆,完全是Hard Code,如果有一個新產(chǎn)品要加進來性宏,就要同時添加一個新產(chǎn)品類赏壹,并且必須修改工廠類,再加入一個 else if 分支才可以衔沼, 這樣就違背了 “開放-關閉原則”中的對修改關閉的準則了蝌借。當系統(tǒng)中的具體產(chǎn)品類不斷增多時候,就要不斷的修改工廠類指蚁,對系統(tǒng)的維護和擴展不利菩佑。

2.一個工廠類中集合了所有的類的實例創(chuàng)建邏輯,違反了高內(nèi)聚的責任分配原則凝化,將全部的創(chuàng)建邏輯都集中到了一個工廠類當中稍坯,所有的業(yè)務邏輯都在這個工廠類中實現(xiàn)。什么時候它不能工作了搓劫,整個系統(tǒng)都會受到影響瞧哟。因此一般只在很簡單的情況下應用,比如當工廠類負責創(chuàng)建的對象比較少時枪向。

3.簡單工廠模式由于使用了靜態(tài)工廠方法勤揩,造成工廠角色無法形成基于繼承的等級結(jié)構(gòu)。

適用環(huán)境

在以下情況下可以使用簡單工廠模式:

工廠類負責創(chuàng)建的對象比較少:由于創(chuàng)建的對象較少秘蛔,不會造成工廠方法中的業(yè)務邏輯太過復雜陨亡。

客戶端只知道傳入工廠類的參數(shù),對于如何創(chuàng)建對象不關心:客戶端既不需要關心創(chuàng)建細節(jié)深员,甚至連類名都不需要記住负蠕,只需要知道類型所對應的參數(shù)。

五倦畅、簡單工廠模式在Java中的應用

①JDK類庫中廣泛使用了簡單工廠模式遮糖,如工具類java.text.DateFormat,它用于格式化一個本地日期或者時間叠赐。

public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Locale
locale);

②Java加密技術(shù)
獲取不同加密算法的密鑰生成器:

KeyGenerator keyGen=KeyGenerator.getInstance("DESede");

創(chuàng)建密碼器:

Cipher cp=Cipher.getInstance("DESede");
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欲账,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子燎悍,更是在濱河造成了極大的恐慌敬惦,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谈山,死亡現(xiàn)場離奇詭異俄删,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門畴椰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臊诊,“玉大人,你說我怎么就攤上這事斜脂∽パ蓿” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵帚戳,是天一觀的道長玷或。 經(jīng)常有香客問我,道長片任,這世上最難降的妖魔是什么偏友? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮对供,結(jié)果婚禮上位他,老公的妹妹穿的比我還像新娘。我一直安慰自己产场,他們只是感情好鹅髓,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著京景,像睡著了一般窿冯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上醋粟,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天靡菇,我揣著相機與錄音,去河邊找鬼米愿。 笑死,一個胖子當著我的面吹牛鼻吮,可吹牛的內(nèi)容都是我干的育苟。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼椎木,長吁一口氣:“原來是場噩夢啊……” “哼违柏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起香椎,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤漱竖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后畜伐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體馍惹,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了万矾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悼吱。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖良狈,靈堂內(nèi)的尸體忽然破棺而出后添,到底是詐尸還是另有隱情,我是刑警寧澤薪丁,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布遇西,位于F島的核電站,受9級特大地震影響严嗜,放射性物質(zhì)發(fā)生泄漏粱檀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一阻问、第九天 我趴在偏房一處隱蔽的房頂上張望梧税。 院中可真熱鬧,春花似錦称近、人聲如沸第队。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凳谦。三九已至,卻和暖如春衡未,著一層夾襖步出監(jiān)牢的瞬間尸执,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工缓醋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留如失,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓送粱,卻偏偏與公主長得像褪贵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抗俄,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 設計模式匯總 一脆丁、基礎知識 1. 設計模式概述 定義:設計模式(Design Pattern)是一套被反復使用、多...
    MinoyJet閱讀 3,949評論 1 15
  • 一個UML類圖 類之間的關系 類的繼承結(jié)構(gòu)表現(xiàn)在UML中為:泛化(generalize)與實現(xiàn)(realize) ...
    僚機KK閱讀 649評論 0 0
  • 創(chuàng)建型模式 抽象工廠模式(abstract facroty) 3.1模式動機 在工廠方法模式中具體工廠負責生產(chǎn)具體...
    僚機KK閱讀 745評論 0 2
  • 摘錄 設計模式一 工廠模式Factory 在面向?qū)ο缶幊讨? 最通常的方法是一個new操作符產(chǎn)生一個對象實例,ne...
    西江月閱讀 471評論 0 2
  • 昨天吃晚飯時动雹,媽媽偶然問起你上次在課上看書槽卫,后來被老師沒收的事情。你說還在老師那里胰蝠,你還沒有足夠的上課積分來換回來...
    喬預閱讀 1,626評論 0 0