日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

抽象工厂讲解

發布時間:2024/4/13 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 抽象工厂讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們來學一下抽象工廠,抽象工廠模式提供一個創建一系列相關或者相互依賴的對象的接口,關鍵字一系列相關,或相互依賴相關的接口,那根據這個一系列呢,我們會引出產品等級,產品族這兩個概念,無須指定他們具體的類,類型是創建型,同一個主題單獨的工廠封裝起來,在正常使用中,客戶端需要創建抽象工廠的具體實現,然后使用抽象工廠,作為接口,來創建這一主題的具體對象,那我們在使用的時候呢,是不需要知道或關心,他從這些內部的工廠中,獲得對象的具體類型,因為我們的客戶端程序呢,僅使用這些接口的通用接口,那抽象工廠模式呢,一組對象的實現細節,和他們的使用呢,分離開來

我們接著來看一下適用場景,首先客戶端不依賴于產品類實例如何被創建,實現的細節,這個呢很好理解,第二個強調一系列相關產品對象,屬于同一產品族,一起使用創建對象時,需要大量的重復代碼,這里面我們就可以使用抽象工廠,同時呢提供了一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴于具體的實現,那使用抽象工廠模式,能夠在工廠具體變化的時候,不要修改使用工廠的

接著我們來看一下抽象工廠的優點,首先具體產品在應用層代碼隔離,無須關心創建細節,那工廠相關的這幾個呢,都有這個優點,第二個優點是抽象工廠比較重要的,講一個系列的產品族統一到一起創建,那后面我們會講產品族,我們繼續來看

缺點也比較明顯,規定了所有可能被創建的產品集合,產品族中擴展新的產品比較困難,需要修改抽象工廠的接口,增加了系統的抽象性和理解難度 我們說一下產品等級結構和產品族,我們首先看一下這個圖

這個圖詮釋的非常好,而且非常的恰當,首先呢我們理解一個概念,可以看到圖中有橢圓形,圓形和正方形,這三個圖形相同顏色的,就代表一個產品族,這兒呢是一個產品族

打個比方,產品族都是由同一個工廠生產的,位于不同產品等級結構,對于豎著的我們看一下,相同形狀,但是呢,顏色深淺不一樣的,他們是同一個產品等級結構

比如圓形,橢圓形,和正方形,這里面我們打個比方,產品族比如美的電器,美的還生產洗衣機,圓形就是洗衣機,美的這個工廠還生產空調,橢圓形就是空調,他們都是美的品牌,他們都是屬于美的這個產品族,豎著來看,橢圓形都是空調,第一排是美的空調,第二排那個橢圓形可以理解成海爾的空調,第三排的橢圓形呢,可以理解成海信的空調,他們都是空調,他們屬于同一個產品等級結構,打個比方,在產品等級結構中,假設有一個抽象類,空調,美的空調,海爾空調,格力空調,海信空調,都是空調,而橫著來看,美的電冰箱,美的洗衣機,美的空調,都是美的,這樣的話就比較好理解了,我們學習了工廠方法,那工廠方法模式呢,針對的就是產品等級結構,而抽象工廠模式呢,針對的就是產品族,我們只要在美的工廠里面取空調,取出來的肯定是美的的空調,我們只要在美的工廠里面去電冰箱,取出來的肯定也是美的的電冰箱,所以我們只要指出一個產品所處的產品族,以及他所處的等級結構,就可以唯一確定這個產品,這里面一定要注意,抽象工廠和工廠方法,最大的一個區別,然后我們繼續來看

左側呢具體的小房子,我們就認為他是一個具體的工廠,剛剛又說美的生產出來的電冰箱空調洗衣機,全部是美的品牌,只要從左側具體工廠取出來的,肯定是屬于同一個產品族

那抽象工廠解決的正式這個問題,所以具體使用工廠方法還是抽象工廠呢,還要看我們實際的應用場景,而這兩個模式呢,怎么選擇呢,剛剛也說了,看業務場景,那從理論上來說,當一個工廠生產不同等級結構的,一個產品族中的,那這個時候抽象工廠模式,比工廠方法模式呢,更為簡單,更有效率,那在后面的coding當中,也會體會他們之間的區別,還有類的個數一個比較,我們會引入一個新的應用場景,然后在擴展的時候呢,用工廠方法思考一下,用抽象工廠也思考一下,很明顯的就能夠對比出來,他們的區別,這樣也會加深我們對抽象工廠的使用,那整體工廠方面呢,是簡單工廠,工廠方法,還有抽象工廠,我們通過一系列的業務引入,場景改變,需求變更,就是希望能夠理解透,牢牢的掌握住這個知識點,那接著回到這個圖中,這個工廠創建美的洗衣機,這個工廠又創建美的電冰箱,這個工廠又創建了美的的空調

現在提出了一個要求,每個課程不僅僅要有視頻,還要有相應的手記,那如果按照工廠方法的一個方式,來擴展的話,想想一下,Java手記,不同的手記,他們之間也是各具特色,那如果按照工廠方法擴展要求來說,我們要創建一個前端的手記類,Java的手記類,Pathon的手記類,前端手記的工廠,Java手記的工廠,還有Pathon手記的工廠,同時呢我們還要創建手記的抽象類,還有手記的一個工廠,那在工廠方法中,如果我們的業務場景發生了比較大擴展,很容易產生類爆炸這么一種情況,也就是說我們要建很多很多的類,而原來一個視頻就是一個課程,而現在一個視頻加一個手記是一個課程,那我們來分析一下,Java視頻,Pathon視頻,前端視頻,他們處于同一個視頻等級,都是視頻,前端手記,Java手記,Pathon手記,他們處于同一個產品等級,都是手記,Java視頻和Java手記他們屬于同一產品族,都是Java相關的,同一產品族,我們就看Java,同一產品等級我們就看他是視頻還是手記即可,那我們現在就來實現他,那我們先創建一個包,那我們先來寫一個課程,在寫課程之前呢,我們先創建課程工廠,這里我們使用interface來聲明

首先從上往下看,上面就是產品族的工廠,課程的工廠,里面有article,里面有video,在IDEA這個插件里面,它會自動認為它是一個屬性,我們可以試一下,假如我們現在不以get開頭,這個時候他就變成一個方法,因為我們這個是get開頭的,他認為他是一個property

在jackson序列號和反序列化的時候,對于get開頭和set開頭的方法,也可以通過一些配置,是set和get開頭的方法變成一個屬性,那這個不是我們的重點,現在他認為是一個屬性或者方法不重要

我們先把他去掉,從上往下看,產品族的工廠,下面有兩個具體的產品族工廠

分別是Java課程和Python課程的工廠,然后往下看,Java課程工廠生產JavaVideo

生產PathonVideo,生產PathonArticle,而Video和Article呢,分別作為整個產品族的一個返回值,他們三是依賴于具體的產品,也就是他們三依賴抽象產品Video,依賴抽象產品Article,而Article兩個具體的子類,就是JavaArticle和PathonArticle,他們兩個就是具體的產品了,那我們往上看一下,那每個設計模式呢,都是結合實際的業務場景,那在某些業務場景呢,可能這種設計模式需要改進或者優化,甚至可能帶來更多的麻煩,例如我們現在增加了算法課程工廠,那對于現在抽象工廠這種模式,非常容易擴展,對原來的類還不需要變化,也就是我們在這里創建一個算法的工廠,他來實現課程工廠,然后下面我再創建算法的Video,算法手記,兩個實際的產品,就可以了,其他這個類呢,是不需要動的,因為遵循工廠,實際產品,他們之間定義的一個契約,包含抽象方法和接口,那這個呢就是抽象工廠的一個好處,那當然還有一個好處

就那現在的類圖來說,我們應用層比如Test客戶端,調用這些類的一個客戶端代碼,一會我會領著大家來寫Test,他在使用的時候,他并不關心產品族創建的一個過程,我們應用層代碼只需要關心值哪個產品族工廠就可以了,因為我們應用層代碼不會直接創建Java手記和Pathon手記,Java視頻和Pathon視頻,因為整個創建過程是由創建工廠來創建的,這里創建的是一個產品族產品,這里面創建的是Java肯定不會錯,如果我們把代碼放在應用層,進行耦合的話,如果應用層的代碼對Java視頻,Java手記依賴過大的話,那么我們在應用層代碼可能會寫錯,就是這個課程是有Java的視頻和Python的手記組成,這樣的話就鬧笑話了,而現在我們是從Java課程的工廠里面取出來的,一定是Java視頻和Java手記,都是屬于Java產品族的,那這個也是抽象工廠的一大優點,那我們現在來寫一下應用層Test類

和整個抽象工廠是怎么協作的,通過這個圖我們就能夠看出來,我們應用層Test代碼根本就不關心什么具體的視頻或者手記之類的,我只關心從哪個工廠拿哪個產品就是了,我從Java課程工廠里面拿Java的產品,我從Pathon課程工廠里面拿Pathon的手記,肯定不會拿錯,也有可能應用層的代碼非常復雜,我從Java課程里面取了一個手記,從Pathon工廠里面取了一個視頻,然后展示給頁面,這個時候設計模式會跳出來說,怪我了,這個時候不能怪設計模式,應用層的代碼和具體的視頻,是解耦的,和具體的手記也是解耦的,例如說我們現在看到的這個類,他們現在都屬于同一個包,如果不在同一個包,我這里面也不需要導入Java視頻的一個類,Java手記的一個類,Pathon視頻的類,Pathon手記的類,這就達到了一定程度的解耦,我們接著看類圖,那我們在使用抽象工廠的時候,盡量找固定程度比較高的,比如課程里面肯定是有視頻的,手記,這兩個幾乎是不會刪除,他們固定程度是比較高的,那剛剛總結的就是抽象工廠的優點,那抽象工廠也是有缺點的,我得快速總結一下,首先應用代碼不和具體的產品發生依賴,他只和具體的產品族工廠發生以來關系,第二點從具體的產品族工廠取出來的,肯定屬于同一產品族,第三點擴展性好,例如新增前端算法的產品族,只需要增加前端的課程工廠,還有具體的產品,就可以了,很方便,無須修改原有系統,符合開閉原則,那整個就是根據實際的應用場景,進行取舍,所以接下來我就說一下缺點,缺點最主要的是什么呢,新增產品等級,會比較麻煩,要對原有的系統進行比較大的修改,那在這種業務場景下,他就違背了開閉原則,所以某些原則在某些場景符合的,比如說,我們擴展新的產品族,這個是符合開閉原則的,但是在抽象工廠里邊,如果為現有的產品族增加新的產品等級,那就不符合開閉原則了,那這個時候我們引入一個新的業務場景,這個課程除了視頻和手記之外呢,還要把源碼放到里面,也就是說視頻手記和源碼,才能構成這個課程,那么我們對原有的修改就比較大了,首先我們要把這個課程工廠,新增一個源碼,然后實現這個課程工廠的具體工廠,也都要增加源碼,下面我們再創建一個源碼的抽象類,然后再寫具體的JAVA源碼,Pathon源碼的,實際產品,那在這種情況下,是不符合開閉原則的,因為我們要修改原來里面具體的實現了,所以對于產品族里面擴展,新的產品等級,還是比較麻煩的,所以平時在我們工廠的應用場景,例如產品等級結構,產品固定的,并且還需要多個產品來組合到一起,形成產品族的,每個業務場景,但是呢如果碰到頻繁改動,那也不適用于抽象工廠,比如今天課程里面再加一個工廠,明天工廠里面還要加一個東西,后天我還要加個東西,那這個就真的太頻繁了,這個類要經常經常改,這些抽象相關的類,所以我們平時找相對固定的,即使你們過了好久才改一次呢,也沒有關系的,比如我們新增了一個源碼,可能這種工廠的設計模式呢可以固定一年兩年三年的,這個呢時間就很長了,這種即使我們去改,也是OK的,只不過我們測試的時候,仔細一些,就可以了,比如說隨著網站的業務不斷擴大,一年或者兩年呢,添加一個新的產品等級,這都是沒有問題的,半年也是OK的,對比工廠方法,一起來看一下,我們把property去掉就OK了,這樣就變成一個正常的方法演示

我們可以發現抽象工廠里面的方法啊,工廠方法關注等級結構,抽象工廠關注產品族,這個是兩個設計模式最大的區別,那抽象工廠還是非常有威力的,他能幫助我們針對抽象編程,而不是針對具體的類來編程,抽象工廠我們就講完了,希望通過對比的方式,能融會貫通,使用這兩種工廠相關的模式 package com.learn.design.pattern.creational.abstractfactory;/*** 再創建一個手記的class* 那這兩個類呢也都是抽象類* * * @author Leon.Sun**/ public abstract class Article {public abstract void produce(); } package com.learn.design.pattern.creational.abstractfactory;/*** 創建這個Video class* * * @author Leon.Sun**/ public abstract class Video {public abstract void produce();} package com.learn.design.pattern.creational.abstractfactory;/*** 創建抽象類和接口的一個業務場景的選擇* 那在我們這里面呢* 我們會聲明兩個方法* 一個是獲取視頻* 一個是獲取手記* 而這兩個都是抽象方法* 使用抽象類也是OK的* 只不過這兩種我們都來體會一下* 我們寫兩個方法* * 課程是視頻加手記* 才可以稱之為內容* 那么我們就聲明一個產品族的一個工廠* 我們聲明Java課程的一個工廠* * * @author Leon.Sun**/ public interface CourseFactory {Video getVideo();Article getArticle();} package com.learn.design.pattern.creational.abstractfactory;/*** 他呢繼承Video* * * @author Leon.Sun**/ public class JavaVideo extends Video {@Overridepublic void produce() {System.out.println("錄制Java課程視頻");} } package com.learn.design.pattern.creational.abstractfactory;/*** 他呢繼承Article這個類* * * @author Leon.Sun**/ public class JavaArticle extends Article {/*** 然后實現produce方法* */@Overridepublic void produce() {System.out.println("編寫Java課程手記");} } package com.learn.design.pattern.creational.abstractfactory;/*** 他來實現CourseFactory* 那現在我們要找到具體的Java視頻和Java手記* 那我們繼續聲明類* * 我們使用抽象工廠的時候* 并沒有聲明視頻的工廠和手記的工廠* 而是聲明一個組合到一起的課程的工廠* 但是具體的產品是有的* Java手記和Java視頻* Java課程作為產品族* 他包含視頻和手記* 那我們接著寫一套Python的* * @author Leon.Sun**/ public class JavaCourseFactory implements CourseFactory {@Overridepublic Video getVideo() {/*** 這里直接返回JavaVideo* */return new JavaVideo();}@Overridepublic Article getArticle() {/*** 這里就直接返回JavaArticle* */return new JavaArticle();} } package com.learn.design.pattern.creational.abstractfactory;/*** PythonVideo繼承Video* 然后再寫一個Pathon的手記* * @author Leon.Sun**/ public class PythonVideo extends Video {@Overridepublic void produce() {System.out.println("錄制Python課程視頻");} } package com.learn.design.pattern.creational.abstractfactory;/*** 繼承Article* * * @author Leon.Sun**/ public class PythonArticle extends Article {@Overridepublic void produce() {System.out.println("編寫Python課程手記");} } package com.learn.design.pattern.creational.abstractfactory;/*** 我們再創建一個Pathon的課程工廠* 他呢實現課程工廠CourseFactory* 然后把里面的具體實現* 寫一下* 當我們要擴展課程的時候* 只需要創建產品族的一個工廠* 還有具體的產品就可以* 現在我們對整體的抽象工廠我們看一下* 我們看一下類圖* * * @author Leon.Sun**/ public class PythonCourseFactory implements CourseFactory {@Overridepublic Video getVideo() {/*** 這里直接new一個PythonVideo*/return new PythonVideo();}@Overridepublic Article getArticle() {/*** 這里直接new一個PythonArticle* */return new PythonArticle();} } package com.learn.design.pattern.creational.abstractfactory;/*** 都是一個產品族* 注意一定要強調產品族的概念* 在抽象工廠這個設計模式當中* 那我們來看一下UML* * @author Leon.Sun**/ public class Test {public static void main(String[] args) {/*** 我們創建一個CourseFactory* 我們new一個JavaCourseFactory* * */CourseFactory courseFactory = new JavaCourseFactory();/*** 這個Video我們直接從courseFactory里面去取* * */Video video = courseFactory.getVideo();/*** 這個手記我也是直接從courseFactory去取* 只要從這個工廠里面取的* 肯定都是Java產品族的* * */Article article = courseFactory.getArticle();video.produce();article.produce();} }

?

總結

以上是生活随笔為你收集整理的抽象工厂讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。