學(xué)習(xí)筆記:設(shè)計(jì)模式之工廠模式

本文僅供學(xué)習(xí)交流使用晒衩,侵權(quán)必刪嗤瞎。
不作商業(yè)用途,轉(zhuǎn)載請注明出處浸遗。

WHAT 什么是工廠

工廠模式是一種創(chuàng)建型的設(shè)計(jì)模式猫胁。工廠模式細(xì)分的話會(huì)被分為簡單工廠、工廠方法和抽象工廠這三類跛锌。
我的理解工廠模式就是將子類的實(shí)例化邏輯交給一個(gè)工廠類執(zhí)行弃秆。工廠類利用了面向?qū)ο蠖鄳B(tài)和封裝的特性,將創(chuàng)建對象的邏輯封裝在一個(gè)工廠類中髓帽,然后利用多態(tài)的特性菠赚,根據(jù)條件判斷創(chuàng)建具體的子類的實(shí)例。

簡單工廠

簡單工廠.png

簡單工廠,子類創(chuàng)建邏輯都封裝到一個(gè)工廠類的創(chuàng)建方法中郑藏,簡單明了衡查。但是如果子類對象過多,存在大量邏輯判斷必盖,并將所有的創(chuàng)建邏輯都寫在一個(gè)方法中拌牲,可讀性比較差。此外歌粥,添加子類就需要改動(dòng)原來創(chuàng)建邏輯代碼塌忽,違反開閉原則,而且創(chuàng)建邏輯代碼會(huì)隨著子類的添加而不斷膨脹失驶。

工廠方法

工廠方法.png

工廠方法,每個(gè)子類的創(chuàng)建都對應(yīng)一個(gè)工廠類土居。如果創(chuàng)建實(shí)例邏輯復(fù)雜,能夠較好將所有創(chuàng)建邏輯分開嬉探,提高可讀性擦耀,工廠類職責(zé)更加單一,并且符合開閉原則涩堤。但如果每添加一個(gè)子類都要添加一個(gè)對應(yīng)的工廠類眷蜓,那么就會(huì)造成類個(gè)數(shù)過多。此外胎围,工廠類的創(chuàng)建會(huì)耦合到調(diào)用函數(shù)中吁系,這個(gè)問題我們可以通過一個(gè)工廠容器解決芹敌,將工廠放到工廠容器我們直接使用即可。

抽象工廠

抽象工廠.png

抽象工廠垮抗,為一類系列的產(chǎn)品創(chuàng)建對象。每個(gè)實(shí)際工廠創(chuàng)建實(shí)際一系列的產(chǎn)品對象碧聪,工廠類是基于產(chǎn)品系列區(qū)分開的冒版。這樣能有效減少工廠類的個(gè)數(shù)。但依然違反了開閉原則逞姿,每次添加一個(gè)產(chǎn)品辞嗡,那么每個(gè)對應(yīng)的實(shí)際工廠都需要做修改。
不過應(yīng)對這種情況我們可以使用反射和配置文件的方式滞造,創(chuàng)建的對象我們可以添加到配置文件续室。創(chuàng)建過程交給框架,既符合開閉原則又符合依賴倒置原則

WHY 為什么使用工廠

  1. 這種模式能降低了客戶端與產(chǎn)品類的耦合度谒养,客戶端創(chuàng)建一個(gè)產(chǎn)品實(shí)例只需要通過調(diào)用工廠類的創(chuàng)建方法即可挺狰。如果對象實(shí)例化邏輯。
  2. 將創(chuàng)建邏輯封裝到工廠類中买窟,對調(diào)用者透明丰泊,調(diào)用者無需關(guān)注復(fù)雜的對象創(chuàng)建邏輯,并且能讓原來的方法職責(zé)更單一始绍,代碼更簡潔瞳购,提高了代碼的可讀性。
  3. 將創(chuàng)建對象代碼邏輯統(tǒng)一封裝在工廠類中亏推,提高了代碼的復(fù)用性

HOW 工廠的實(shí)現(xiàn)(JAVA)

簡單工廠

舉例背景:通過簡單工廠創(chuàng)建不同類型的配置文件解析器

  • 解析器類
/**
 * 解析器接口類
 */
public interface IConfigParser {
    void parse();
}


/**
 * 解析器類型
 */
public enum ParserType {
    JSON,
    XML,
    YAML;
}


/**
 * json配置文件解析器
 */
public class JsonConfigParser implements IConfigParser {
    @Override
    public void parse() {
        System.out.println("json");
    }
}


/**
 * xml配置文件解析器
 */
public class XmlConfigParser implements IConfigParser {
    @Override
    public void parse() {
        System.out.println("xml");
    }
}


/**
 * yaml配置文件解析器
 */
public class YamlConfigParser implements IConfigParser {
    @Override
    public void parse() {
        System.out.println("yaml");
    }
}
  • 簡單工廠類
public class SimpleFactory {

    public static IConfigParser createParser(ParserType type) {
         
        if (type == null) {
            return null;
        }

        if (type == ParserType.JSON) {
            return new JsonConfigParser();
        } else if (type == ParserType.YAML) {
            return new YamlConfigParser();
        } else if (type == ParserType.XML) {
            return new XmlConfigParser();
        } else {
            throw new IllegalArgumentException("");
        }
    }
}

工廠方法

舉例背景:舉例背景:通過工廠方法創(chuàng)建不同類型的配置文件解析器

  • 解析器類同簡單工廠一樣

  • 工廠類

/**
 * 工廠類接口
 */
public interface IFactory {

    IConfigParser createParser();
}


/**
 * Json解析器工廠
 */
public class JsonConfigParserFactory implements IFactory {
    @Override
    public IConfigParser createParser() {
        return new JsonConfigParser();
    }
}


/**
 * Xml解析器工廠
 */
public class XmlConfigParserFactory implements IFactory {
    @Override
    public IConfigParser createParser() {
        return new XmlConfigParser();
    }
}


/**
 * Yaml解析器工廠
 */
public class YamlConfigParserFactory implements IFactory {
    @Override
    public IConfigParser createParser() {
        return new YamlConfigParser();
    }
}

抽象工廠

舉例背景:根據(jù)不同的數(shù)據(jù)庫類型学赛,創(chuàng)建不同的對象。因?yàn)椴煌臄?shù)據(jù)庫吞杭,有可能對數(shù)據(jù)庫操作也是不一樣的盏浇。我們將對數(shù)據(jù)庫的操作封裝在對應(yīng)的對象中,那么每次根據(jù)數(shù)據(jù)庫類型創(chuàng)建對應(yīng)的對象

  • 對象接口類
public interface IUser {

    long insert(IUser user);

    IUser getUser(String id);
}


public interface IDepartment {

    long insert(IDepartment department);

    IDepartment getDepartment(String id);
}

  • 對象實(shí)現(xiàn)類


public class SqlServerUser implements IUser {
    @Override
    public long insert(IUser user) {
        System.out.println("sqlserver user insert");
        return 1;
    }

    @Override
    public IUser getUser(String id) {
        return new SqlServerUser();
    }
}


public class SqlServerDepartment implements IDepartment {
    @Override
    public long insert(IDepartment department) {
        System.out.println("sqlserver department insert");
        return 1L;
    }

    @Override
    public IDepartment getDepartment(String id) {
        return new SqlServerDepartment();
    }
}


public class MysqlUser implements IUser {
    @Override
    public long insert(IUser user) {
        System.out.println("mysql user insert");
        return 1L;
    }

    @Override
    public IUser getUser(String id) {
        return new MysqlUser();
    }
}


public class MysqlDepartment implements IDepartment {
    @Override
    public long insert(IDepartment department) {
        System.out.println("mysql department insert");
        return 1L;
    }

    @Override
    public IDepartment getDepartment(String id) {
        return new MysqlDepartment();
    }
}
  • 工廠類
/**
 * 抽象工廠類
 */
public abstract class AbstractFactory {

    public abstract IUser createUser();

    public abstract IDepartment createDepartment();
}


/**
 * Mysql工廠類
 */
public class MysqlFactory extends AbstractFactory {
    @Override
    public IUser createUser() {
        return new MysqlUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new MysqlDepartment();
    }
}


/**
 * SqlServer工廠類
 */
public class SqlServerFactory extends AbstractFactory {
    @Override
    public IUser createUser() {
        return new SqlServerUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new SqlServerDepartment();
    }
}

持續(xù)更新...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篇亭,一起剝皮案震驚了整個(gè)濱河市缠捌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌译蒂,老刑警劉巖曼月,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柔昼,居然都是意外死亡哑芹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門捕透,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聪姿,“玉大人碴萧,你說我怎么就攤上這事∧┕海” “怎么了破喻?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盟榴。 經(jīng)常有香客問我曹质,道長,這世上最難降的妖魔是什么擎场? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任羽德,我火速辦了婚禮,結(jié)果婚禮上迅办,老公的妹妹穿的比我還像新娘宅静。我一直安慰自己,他們只是感情好站欺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布姨夹。 她就那樣靜靜地躺著,像睡著了一般镊绪。 火紅的嫁衣襯著肌膚如雪匀伏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天蝴韭,我揣著相機(jī)與錄音够颠,去河邊找鬼。 笑死榄鉴,一個(gè)胖子當(dāng)著我的面吹牛履磨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庆尘,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼剃诅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驶忌?” 一聲冷哼從身側(cè)響起矛辕,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎付魔,沒想到半個(gè)月后聊品,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡几苍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年翻屈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妻坝。...
    茶點(diǎn)故事閱讀 38,687評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伸眶,死狀恐怖惊窖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情厘贼,我是刑警寧澤界酒,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布,位于F島的核電站嘴秸,受9級特大地震影響盾计,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赁遗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望族铆。 院中可真熱鬧岩四,春花似錦、人聲如沸哥攘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逝淹。三九已至耕姊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間栅葡,已是汗流浹背茉兰。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欣簇,地道東北人规脸。 一個(gè)月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像熊咽,于是被迫代替她去往敵國和親莫鸭。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評論 2 349