1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        工廠方法模式:在 Spring Boot 中的典型應(yīng)用

        共 5318字,需瀏覽 11分鐘

         ·

        2022-02-20 19:56

        大家好,我是CodingLong!

        在上一篇《簡單工廠模式》中我們了解到,簡單工廠模式每次增加新的產(chǎn)品時,都要修改其“工廠類”,這違背了開閉原則。而本篇介紹的工廠方法模式,對“工廠類”進一步抽象,即使新增產(chǎn)品也不用修改原來的代碼,這滿足了開閉原則。

        1 定義

        工廠方法模式(Factory Method Pattern)定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。

        Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

        也就是說,我們需要提供一個抽象的工廠接口,聲明一個創(chuàng)建對象的工廠方法,由其子類具體實現(xiàn)工廠方法,并決定創(chuàng)建哪一個產(chǎn)品對象。

        2 角色

        下面是工廠方法模式中的幾個角色:

        • 抽象產(chǎn)品(Product):所有具體產(chǎn)品的公共接口。
        • 具體產(chǎn)品(ConcreteProduct):實現(xiàn)了Product接口,是工廠方法中創(chuàng)建的對象。
        • 抽象工廠(Factory):所有具體工廠的公共接口。聲明一個工廠方法,該方法返回一個Product類型的對象。
        • 具體工廠(ConcreteFactory):實現(xiàn)了Factory接口,工廠方法返回一個ConcreteProduct實例。
        • 客戶端(Client):客戶端通過具體工廠來創(chuàng)建對應(yīng)的產(chǎn)品實例。

        下面是該模式的UML類圖:

        3 實現(xiàn)

        還是以《簡單工廠模式》中的手機案例,來講解該模式的實現(xiàn)。

        3.1 抽象產(chǎn)品接口:Phone

        創(chuàng)建一個手機接口,它可以打電話和發(fā)短信。

        /**
        ?*?手機接口
        ?*/

        public?interface?Phone?{

        ????/**
        ?????*?打電話
        ?????*/

        ????void?call();

        ????/**
        ?????*?發(fā)短信
        ?????*/

        ????void?sendSMS();
        }

        3.2 兩個具體產(chǎn)品類:XiaomiPhone和RedmiPhone

        為手機接口創(chuàng)建兩個實現(xiàn)類,一個是小米手機,一個是紅米手機,當(dāng)然也可以有更多的實現(xiàn)類。

        /**
        ?*?小米手機實現(xiàn)類
        ?*/

        public?class?XiaomiPhone?implements?Phone?{
        ????@Override
        ????public?void?call()?{
        ????????System.out.println("使用小米手機打電話");
        ????}

        ????@Override
        ????public?void?sendSMS()?{
        ????????System.out.println("使用小米手機發(fā)短信");
        ????}
        }

        /**
        ?*?紅米手機實現(xiàn)類
        ?*/

        public?class?RedmiPhone?implements?Phone?{
        ????@Override
        ????public?void?call()?{
        ????????System.out.println("使用紅米手機打電話");
        ????}

        ????@Override
        ????public?void?sendSMS()?{
        ????????System.out.println("使用紅米手機發(fā)短信");
        ????}
        }

        3.3 一個工廠接口:PhoneFactory

        創(chuàng)建一個手機工廠的接口,包含一個創(chuàng)建Phone的方法。

        /**
        ?*?手機工廠接口
        ?*/

        public?interface?PhoneFactory?{
        ????/**
        ?????*?獲取手機實例
        ?????*
        ?????*?@return
        ?????*/

        ????Phone?createPhone();
        }

        3.4 兩個具體工廠類:XiaomiPhoneFactory和RedmiPhoneFactory

        創(chuàng)建兩個具體手機工廠實現(xiàn)類,每個工廠創(chuàng)建各自的產(chǎn)品實例。

        /**
        ?*?小米手機工廠類
        ?*/

        public?class?XiaomiPhoneFactory?implements?PhoneFactory?{
        ????@Override
        ????public?Phone?createPhone()?{
        ????????return?new?XiaomiPhone();
        ????}
        }

        /**
        ?*?紅米手機工廠類
        ?*/

        public?class?RedmiPhoneFactory?implements?PhoneFactory?{
        ????@Override
        ????public?Phone?createPhone()?{
        ????????return?new?RedmiPhone();
        ????}
        }

        3.5 客戶端:Client

        創(chuàng)建一個客戶端,通過XiaomiPhoneFactory工廠創(chuàng)建小米手機;通過RedmiPhoneFactory工廠創(chuàng)建紅米手機。

        /**
        ?*?客戶端類
        ?*/

        public?class?Client?{

        ??public?static?void?main(String[]?args)?{
        ????????System.out.println("================小米手機================");
        ????????Phone?xiaomiPhone?=?new?XiaomiPhoneFactory().createPhone();
        ????????xiaomiPhone.call();
        ????????xiaomiPhone.sendSMS();

        ????????System.out.println("================紅米手機================");
        ????????Phone?redmiPhone?=?new?RedmiPhoneFactory().createPhone();
        ????????redmiPhone.call();
        ????????redmiPhone.sendSMS();
        ????}
        }

        3.6 運行結(jié)果

        運行客戶端main方法,會打印如下內(nèi)容:

        ================小米手機================
        使用小米手機打電話
        使用小米手機發(fā)短信
        ================紅米手機================
        使用紅米手機打電話
        使用紅米手機發(fā)短信

        4 優(yōu)缺點

        優(yōu)點:

        • 使對象的創(chuàng)建和使用分離,對象的創(chuàng)建交給具體的工廠類負(fù)責(zé),客戶端不需要關(guān)心是怎么創(chuàng)建的,只關(guān)心如何使用就行了。
        • 一個具體工廠只負(fù)責(zé)創(chuàng)建一個產(chǎn)品實例,遵循了單一職責(zé)。
        • 新增產(chǎn)品時,只需創(chuàng)建一個對應(yīng)的工廠類即可,遵循了開閉原則。

        缺點:

        • 每增加一個產(chǎn)品,都要增加一個對應(yīng)的工廠類,類的數(shù)量激增。

        5 典型應(yīng)用

        我們以Redis連接為例,來看下工廠方法模式在Spring Boot中的應(yīng)用。

        在Java中,連接Redis的兩個比較常用的客戶端是JedisLettuce,它們都被Spring官方加入到了spring-data-redis項目中,使用戶可以自由的選擇使用哪種連接方式。

        來看下它的整體結(jié)構(gòu):

        RedisConnection是Redis連接接口,在工廠方法模式中屬于抽象產(chǎn)品角色。它有兩個主要實現(xiàn)類:JedisConnectionLettuceConnection,是工廠方法中創(chuàng)建的具體產(chǎn)品。

        RedisConnectionFactory是Redis連接工廠接口,在工廠方法模式中屬于抽象工廠角色。它有兩個實現(xiàn)類:JedisConnectionFactoryLettuceConnectionFactory。

        JedisConnectionFactory工廠中創(chuàng)建的是JedisConnection對象:

        public?class?JedisConnectionFactory?implements?InitializingBean,?DisposableBean,?RedisConnectionFactory?{
        ??????//...
        ??????
        ??????/*
        ???????*?獲取Redis連接
        ???????*/

        ??????public?RedisConnection?getConnection()?{
        ????
        ????????assertInitialized();
        ????
        ????????if?(isRedisClusterAware())?{
        ??????????return?getClusterConnection();
        ????????}
        ????
        ????????Jedis?jedis?=?fetchJedisConnector();
        ????????JedisClientConfig?sentinelConfig?=?this.clientConfig;
        ????
        ????????SentinelConfiguration?sentinelConfiguration?=?getSentinelConfiguration();
        ????????if?(sentinelConfiguration?!=?null)?{
        ??????????sentinelConfig?=?createSentinelClientConfig(sentinelConfiguration);
        ????????}
        ????
        ????????JedisConnection?connection?=?(getUsePool()???new?JedisConnection(jedis,?pool,?this.clientConfig,?sentinelConfig)
        ????????????:?new?JedisConnection(jedis,?null,?this.clientConfig,?sentinelConfig));
        ????????connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
        ????????return?postProcessConnection(connection);
        ??????}
        ??????
        ??????//...
        }

        而在LettuceConnectionFactory工廠中創(chuàng)建的是LettuceConnection對象:

        public?class?LettuceConnectionFactory
        ????implements?InitializingBean,?DisposableBean,?RedisConnectionFactory,?ReactiveRedisConnectionFactory?
        {
        ??????//?...

        ??????/*
        ???????*?獲取Redis連接
        ???????*/

        ??????public?RedisConnection?getConnection()?{
        ????
        ????????assertInitialized();
        ????
        ????????if?(isClusterAware())?{
        ??????????return?getClusterConnection();
        ????????}
        ????
        ????????LettuceConnection?connection;
        ????????connection?=?doCreateLettuceConnection(getSharedConnection(),?connectionProvider,?getTimeout(),?getDatabase());
        ????????connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
        ????????return?connection;
        ??????}
        ??????
        ??????//?...
        ?
        }

        6 完整代碼

        完整代碼請訪問我的Github,若對你有幫助,歡迎給個?,感謝~~??????

        https://github.com/gozhuyinglong/blog-demos/blob/main/design-patterns/src/main/java/io/github/gozhuyinglong/designpatterns/factory/FactoryMethod.java

        7 推薦閱讀

        微信搜索:碼農(nóng)StayUp

        主頁地址:https://gozhuyinglong.github.io

        源碼分享:https://github.com/gozhuyinglong/blog-demos


        瀏覽 198
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            做爱视频网站免费观看 | 成人黄色网 | 女人18片毛片90分钟免费 | 粉嫩av在线播放 亚洲国产另类精品专区 | 天天搞夜夜爽 | 四虎免费视频 | 中国大乳女人的hdmove | 性爱五月天网站 | 欧美日韩不卡合集视频 | 丁香五月社区 |