二維碼
        企資網(wǎng)

        掃一掃關(guān)注

        當(dāng)前位置: 首頁(yè) » 企資快訊 » 辦公 » 正文

        略懂設(shè)計(jì)模式之工廠模式

        放大字體  縮小字體 發(fā)布日期:2021-09-04 09:43:37    作者:王恒    瀏覽次數(shù):25
        導(dǎo)讀

        前言工廠模式應(yīng)該是大家的老朋友了,相信很多朋友在學(xué)習(xí)和工作中一定遇到過,但是不一定很了解,這篇文章將通過幾個(gè)例子,帶大家一起進(jìn)一步了解工廠模式。簡(jiǎn)介工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計(jì)模

        前言


        工廠模式應(yīng)該是大家的老朋友了,相信很多朋友在學(xué)習(xí)和工作中一定遇到過,但是不一定很了解,這篇文章將通過幾個(gè)例子,帶大家一起進(jìn)一步了解工廠模式。


        簡(jiǎn)介


        工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計(jì)模式之一。 這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式 ,它提供了一種創(chuàng)建對(duì)象的最佳方式。

        在創(chuàng)建型模式中工廠模式是比較重要的一種,之所以名稱中包含“工廠”二字,是因?yàn)橛霉S代替了 new 操作,將對(duì)象實(shí)例化的過程交給工廠來實(shí)現(xiàn)。

        工廠模式關(guān)心的是最終創(chuàng)建的對(duì)象, 而不關(guān)心創(chuàng)建的過程。 舉個(gè)例子,好比您需要一輛汽車,可以直接從工廠里面提貨,而不用去管這輛汽車是怎么做出來的,以及這個(gè)汽車?yán)锩娴木唧w實(shí)現(xiàn)。

        工廠模式可以分為三類:

      1. 簡(jiǎn)單工廠模式 (Simple Factory)
      2. 工廠方法模式 (Factory Method)
      3. 抽象工廠模式 (Abstract Factory)

        其中簡(jiǎn)單工廠模式并不屬于23種 GOF 設(shè)計(jì)模式之一,而是將其看作工廠方法模式的一種特例,兩者歸為一類。


        簡(jiǎn)單工廠模式


        簡(jiǎn)單工廠模式又叫靜態(tài)工廠模式,由一個(gè)工廠類根據(jù)傳入的參數(shù),動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一個(gè)產(chǎn)品類(繼承自一個(gè)父類或接口)的實(shí)例。

        簡(jiǎn)單工廠模式的主要組成:

        工廠(Factory): 負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯,并提供一個(gè)外界調(diào)用的方法,創(chuàng)建所需的產(chǎn)品對(duì)象

        抽象產(chǎn)品(Product): 負(fù)責(zé)描述產(chǎn)品的公共接口

        具體產(chǎn)品(ConcreteProduct): 描述生產(chǎn)的具體產(chǎn)品

        這里我們就以生產(chǎn)汽車為例:


        首先定義產(chǎn)品,先想好要生產(chǎn)什么:

        // 汽車基類public abstract class Car {    // 輸出汽車信息    public abstract void printInfo();}// 比亞迪汽車public class BydCar extends Car{    @Override    public void printInfo() {        System.out.println("這是比亞迪汽車");    }}// 吉利汽車public class GeelyCar extends Car{    @Override    public void printInfo() {        System.out.println("這是吉利汽車");    }}

        然后定義工廠類,想好生產(chǎn)什么產(chǎn)品之后,就要建工廠了:

        // 汽車工廠類public class CarFactory {    // 生產(chǎn)汽車    public static Car productionCar(String brand) {        if ("geely".equals(brand)) {            return new GeelyCar();        } else if ("byd".equals(brand)) {            return new BydCar();        } else {            return null;        }    }}

        工廠建好了,有了比亞迪和吉利兩條生產(chǎn)線,就可以大膽生產(chǎn)汽車了:

        public class FactoryPatternDemo {    public static void main(String[] args) {        Car car = CarFactory.productionCar("byd");        car.printInfo();    }}// 輸出:這是比亞迪汽是不是很簡(jiǎn)單,這時(shí)候可能有朋友就要問了,那我想要紅旗汽車怎么辦,還得再創(chuàng)建一個(gè)紅旗汽車類,然后修改工廠類的判斷邏輯,顯然這是違背開閉原則的。

        是不是很簡(jiǎn)單,這時(shí)候可能有朋友就要問了,那我想要紅旗汽車怎么辦,還得再創(chuàng)建一個(gè)紅旗汽車類,然后修改工廠類的判斷邏輯,顯然這是違背開閉原則的。

        那么可不可以不修改工廠類里的邏輯呢?

        當(dāng)然可以,還有一種方式是通過反射來創(chuàng)建具體的產(chǎn)品,我們熟悉的 Spring 的 BeanFactory 就是采用反射的方式實(shí)現(xiàn)的。

        還是汽車工廠類,我們修改一下代碼:

        public class CarFactory {    public static Car productionCar(Class c){        Car car = null;        try {            car = (Car) Class.forName(c.getName()).newInstance();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        return car;    }}

        反射的方式看起來代碼簡(jiǎn)潔多了是吧,但是某些情況下并不合適,而且反射對(duì)程序性能也會(huì)有影響。

        簡(jiǎn)單工廠模式適用于業(yè)務(wù)簡(jiǎn)單的情況下,而對(duì)于復(fù)雜的業(yè)務(wù)環(huán)境可能就不太適用了。這個(gè)時(shí)候就要工廠方法模式登場(chǎng)了。


        工廠方法模式


        在簡(jiǎn)單工廠模式中,工廠負(fù)責(zé)所有產(chǎn)品的生產(chǎn),就像上面例子中,一個(gè)汽車工廠負(fù)責(zé)所有汽車的生產(chǎn)。而工廠方法模式則是將工廠類抽象化,把生成具體產(chǎn)品的任務(wù)分發(fā)給繼承抽象方法的具體的產(chǎn)品工廠。

        工廠方法模式的主要組成:

        抽象工廠(Abstract Factory):描述具體工廠的公共接口

        具體工廠(ConcreteFactory):描述具體工廠,創(chuàng)建產(chǎn)品的實(shí)例,供外界調(diào)用

        抽象產(chǎn)品(Product):負(fù)責(zé)描述產(chǎn)品的公共接口

        具體產(chǎn)品(ConcreteProduct):描述生產(chǎn)的具體產(chǎn)品

        我們還是以生產(chǎn)汽車為例:


        將簡(jiǎn)單工廠方法中的工廠類改為抽象工廠類,再創(chuàng)建具體工廠類來實(shí)現(xiàn)汽車的生產(chǎn)工作:

        // 抽象汽車工廠類public abstract class AbstractCarFactory {    // 生產(chǎn)汽車    abstract Car productionCar();}// 比亞迪汽車工廠public class BydCarFactory extends AbstractCarFactory{    @Override    Car productionCar()        return new BydCar();    }}// 吉利汽車工廠public class GeelyCarFactory extends AbstractCarFactory{    @Override    Car productionCar()        return new GeelyCar();    }}

        這下要生產(chǎn)什么品牌的汽車,就要交給具體的工廠了:

        public class FactoryPatternDemo {    public static void main(String[] args) {        AbstractCarFactory factory = new BydCarFactory();        Car car = factory.productionCar();        car.printInfo();    }}// 輸出:這是比亞迪汽車

        工廠方法模式看起來要比簡(jiǎn)單工廠模式更復(fù)雜一些,每增加一個(gè)新的產(chǎn)品就要增加一個(gè)工廠,但是他提高了系統(tǒng)的可擴(kuò)展性和可維護(hù)性,完全符合開閉原則。

        我們可能遇到的大部分業(yè)務(wù)需求使用工廠方法模式足以應(yīng)付,但是凡事都有特殊情況。當(dāng)產(chǎn)品種類更加復(fù)雜,存在產(chǎn)品族的時(shí)候,就要使用抽象工廠模式了。


        抽象工廠模式


        在介紹抽象工廠模式前,我們先了解下產(chǎn)品族是什么:位于不同產(chǎn)品等級(jí)結(jié)構(gòu)中,功能相關(guān)聯(lián)的產(chǎn)品組成的家族。

        沒有理解的話可以看下圖:


        圖中,比亞迪的商務(wù)汽車和吉利的商務(wù)汽車都屬于商務(wù)車產(chǎn)品族,運(yùn)動(dòng)車產(chǎn)品族同理。

        抽象工廠模式提供了一種方式,可以將同一產(chǎn)品族的單獨(dú)的工廠封裝起來。它是三種工廠模式里面最為抽象、最具一般性的。

        抽象工廠模式和工廠方法模式一樣,都符合開閉原則。但是不同的是,工廠方法模式在增加一個(gè)具體產(chǎn)品的時(shí)候,都要增加對(duì)應(yīng)的工廠。但是抽象工廠模式只有在新增一個(gè)類型的具體產(chǎn)品時(shí)才需要新增工廠。也就是說,工廠方法模式的一個(gè)工廠只能創(chuàng)建一個(gè)具體產(chǎn)品。而抽象工廠模式的一個(gè)工廠可以創(chuàng)建屬于一類類型的多種具體產(chǎn)品。工廠創(chuàng)建產(chǎn)品的個(gè)數(shù)介于簡(jiǎn)單工廠模式和工廠方法模式之間。

        抽象工廠模式的主要組成:

        抽象工廠(AbstractFactory):描述具體工廠的公共接口

        具體工廠(ConcreteFactory):描述具體工廠,創(chuàng)建產(chǎn)品的實(shí)例,供外界調(diào)用

        抽象產(chǎn)品(族)(AbstractProduct):描述抽象產(chǎn)品的公共接口

        具體產(chǎn)品(ConcreteProduct):描述具體產(chǎn)品的公共接口

        同樣以生產(chǎn)汽車為例:


        創(chuàng)建商務(wù)汽車產(chǎn)品族和運(yùn)動(dòng)汽車產(chǎn)品族相關(guān)類:

        // 商務(wù)汽車抽象類public abstract class BusinessCar {    public abstract void printInfo();}// 比亞迪商務(wù)汽車public class BydBusinessCar extends BusinessCar{    @Override    public void printInfo() {        System.out.println("這是比亞迪商務(wù)汽車");    }}// 吉利商務(wù)汽車public class GeelyBusinessCar extends BusinessCar{    @Override    public void printInfo(){        System.out.println("這是吉利商務(wù)汽車");    }}// 運(yùn)動(dòng)汽車抽象類public abstract class SportCar {    public abstract void printInfo();}// 比亞迪運(yùn)動(dòng)汽車public class BydSportCar extends SportCar{    @Override    public void printInfo() {        System.out.println("這是比亞迪運(yùn)動(dòng)汽車");    }}// 吉利運(yùn)動(dòng)汽車public class GeelySportCar extends SportCar{    @Override    public void printInfo(){        System.out.println("這是吉利運(yùn)動(dòng)汽車");    }}

        創(chuàng)建抽象工廠類和具體工廠類:

        // 抽象汽車工廠類public abstract class AbstractCarFactory {    // 生產(chǎn)商務(wù)汽車    abstract BusinessCar productionBusinessCar();    // 生產(chǎn)運(yùn)動(dòng)汽車    abstract SportCar productionSportCar();}// 比亞迪汽車工廠public class BydCarFactory extends AbstractCarFactory{    @Override    public BusinessCar productionBusiness() {        return new BydBusinessCar();    }        @Override    public SportCar productionSport() {        return new BydSportCar();    }}// 吉利汽車工廠public class GeelyCarFactory extends AbstractCarFactory{    @Override    public BusinessCar productionBusiness() {        return new GeelyBusinessCar();    }        @Override    public SportCar productionSport() {        return new GeelySportCar();    }}

        開始生產(chǎn)汽車:

        public class FactoryPatternDemo {    public static void main(String[] args) {        AbstractCarFactory factory = new BydCarFactory();        BusinessCar car = factory.BydBusinessCar();        car.printInfo();    }}// 輸出:這是比亞迪商務(wù)汽車

        抽象工廠模式除了具有工廠方法模式的優(yōu)點(diǎn)外,最主要的優(yōu)點(diǎn)就是可以在類的內(nèi)部對(duì)產(chǎn)品族進(jìn)行約束。但是產(chǎn)品族的擴(kuò)展將是一件十分費(fèi)力的事情,假如產(chǎn)品族中需要增加一個(gè)新的產(chǎn)品,則幾乎所有的工廠類都需要進(jìn)行修改,不能很好地支持開閉原則。所以使用抽象工廠模式時(shí),對(duì)產(chǎn)品等級(jí)結(jié)構(gòu)的劃分是非常重要的。


        總結(jié)


        三種工廠模式都各有優(yōu)缺點(diǎn),合適的才是最好的,希望大家能夠理解并靈活運(yùn)用,讓自己的代碼變得更優(yōu)雅!

      4.  
        (文/王恒)
        免責(zé)聲明
        本文僅代表作發(fā)布者:王恒個(gè)人觀點(diǎn),本站未對(duì)其內(nèi)容進(jìn)行核實(shí),請(qǐng)讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問題,請(qǐng)及時(shí)聯(lián)系我們刪除處理郵件:weilaitui@qq.com。
         

        Copyright ? 2016 - 2025 - 企資網(wǎng) 48903.COM All Rights Reserved 粵公網(wǎng)安備 44030702000589號(hào)

        粵ICP備16078936號(hào)

        微信

        關(guān)注
        微信

        微信二維碼

        WAP二維碼

        客服

        聯(lián)系
        客服

        聯(lián)系客服:

        在線QQ: 303377504

        客服電話: 020-82301567

        E_mail郵箱: weilaitui@qq.com

        微信公眾號(hào): weishitui

        客服001 客服002 客服003

        工作時(shí)間:

        周一至周五: 09:00 - 18:00

        反饋

        用戶
        反饋

        主站蜘蛛池模板: 精品一区二区三区免费观看| 伊人久久精品无码麻豆一区| 精品一区二区三区免费毛片爱 | 亚洲无线码一区二区三区| 亚洲爆乳精品无码一区二区三区| 日本精品高清一区二区2021| 久久高清一区二区三区| 精品视频在线观看你懂的一区| 亚洲码欧美码一区二区三区 | 亚洲一区中文字幕在线观看| 日本夜爽爽一区二区三区| 国产一区二区久久久| 文中字幕一区二区三区视频播放| 久久99久久无码毛片一区二区| 天美传媒一区二区三区| 国产对白精品刺激一区二区| 久久国产一区二区三区| 丰满少妇内射一区| 久久99国产一区二区三区| 亚洲国产精品成人一区| www.亚洲一区| 一区二区三区四区国产| 天码av无码一区二区三区四区 | 午夜视频久久久久一区| 日韩成人一区ftp在线播放| 精产国品一区二区三产区| 精品人妻少妇一区二区三区不卡 | 国产品无码一区二区三区在线蜜桃 | 国产精品自在拍一区二区不卡| 一区二区三区无码高清视频| 国产精品无码一区二区三级| 国产午夜精品免费一区二区三区 | 无码毛片一区二区三区视频免费播放 | 一区二区手机视频| 国产一区二区三区视频在线观看 | 国产成人久久精品一区二区三区| 国内精品无码一区二区三区| 亚洲国产精品一区二区成人片国内 | 一区在线免费观看| 精品少妇ay一区二区三区| 日韩a无吗一区二区三区|