-
設(shè)計模式——工廠模式
一、概念
? ? 1、實例化對象,用工廠方法替代new操作;
? ? 2、工廠模式包括工廠方法模式和抽象工廠模式;
? ? 3、抽象工廠模式是工廠方法模式的擴(kuò)展。
二、意圖
????1、定義一個接口來創(chuàng)建對象,但是子類來決定哪些類需要被實例化;
????2、工廠方法把實例化的工作推遲到子類中去實現(xiàn)。
三、應(yīng)用場景
????1、有一組類似的對象需要創(chuàng)建;
????2、在編碼時不能預(yù)見需要創(chuàng)建哪種類的實例;
????3、系統(tǒng)需要考慮擴(kuò)展性,不應(yīng)依賴于產(chǎn)品類實例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié)。
工廠適用于哪些場景:
????1、一個系統(tǒng)應(yīng)當(dāng)不依賴于產(chǎn)品類實例被創(chuàng)建、組成和表示的細(xì)節(jié),這對于所有形態(tài)的工廠模式都是重要的;
????2、這個系統(tǒng)的產(chǎn)品有至少一個的產(chǎn)品族;
????3、同屬于同一個產(chǎn)品族(例如圣誕系列、元旦系列)的產(chǎn)品是設(shè)計成在一起使用的,這一約束必須得在系統(tǒng)的設(shè)計中體現(xiàn)出來;
????4、不同的產(chǎn)品以一系列的接口的面貌出現(xiàn),從而使系統(tǒng)不依賴于接口實現(xiàn)的細(xì)節(jié)。
常見應(yīng)用:
? ?1、 JDBC——一種用于執(zhí)行SQL語句的Java API,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問,它由一組用Java語言編寫的類和接口組成。
? ?2、 SpringBeanFactory
????????BeanFactory 作為Spring基礎(chǔ)的IOC容器,是Spring的一個Bean工廠;如果單從工廠模式的角度考慮,它就是用來“生產(chǎn)Bean”,然后提供給客戶端。
????????Bean實例化的過程如下:
? ? ? ? ? ? (1)、調(diào)用Bean的默認(rèn)構(gòu)造方法,或者指定的構(gòu)造方法,生成bean實例(贊成為instance1);
????????????(2)、如果Bean的配置文件中注入了Bean屬性,則在instance1基礎(chǔ)上進(jìn)行屬性注入形成instance2,這?種注入是覆蓋性的;
? ? ? ? ? ? (3)、如果Bean實現(xiàn)了InitializingBean接口,則調(diào)用afterPropertiesSet()方法,來改變或操作instance2,得到instance3;
????????????(4)、如果Bean的配置文件中制定了init-method="init"屬性,則會調(diào)用指定的初始化方法,則在instance3的基礎(chǔ)上調(diào)用初始化方法init(),講對象最終初始化為instance4;當(dāng)然,這個初始化的名字是任意的
四、動機
????項目現(xiàn)狀:在軟件系統(tǒng)中經(jīng)常面臨著“對象”的創(chuàng)建工作,由于需求的變化,這個“對象”也可能隨之發(fā)生變化,但它卻擁有比較穩(wěn)定的接口。
????提供封裝機制去隔離易變“對象”的變化,從而保持系統(tǒng)中依賴該“對象”的“其他對象”不隨著需求的變化而變化。
????代碼設(shè)計:
????????1、盡量松耦合,一個對象的依賴對象的變化與對象本身無關(guān);
????????2、具體產(chǎn)品與客戶端剝離,責(zé)任分割。
工廠模式代碼示例:
public?interface?HairInterface{ ????//實現(xiàn)發(fā)型 ????public?void?draw(); } //左偏分發(fā)型 public?class?LeftHair?implements?HairInterface{ ????//畫一個左偏分發(fā)型 ????@Override ????public?void?draw(){ ????????System.out.println("實現(xiàn)了一個左偏分發(fā)型......"); ????} } //右偏分發(fā)型 public?class?RightHair?implements?HairInterface{ ????//畫一個右偏分發(fā)型 ????@Override ????public?void?draw(){ ????????System.out.println("實現(xiàn)了一個右偏分發(fā)型......"); ????} } //中分發(fā)型 public?class?InHair?implements?HairInterface{ ????//畫一個中分發(fā)型 ????@Override ????public?void?draw(){ ????????System.out.println("實現(xiàn)了一個中分發(fā)型......"); ????} }
public?class?SunnyTest{ ????public?static?void?main(String[]?args){ ??????????//此類調(diào)用不利于代碼維護(hù),也不利于管理,每次都要自己new一個對象 ???????HairInterface?left?=?new?LeftHair(); ???????left.draw(); ???????HairInterface?right?=?new?RightHair(); ??????????????right.draw(); ?????????????? ???????//工廠創(chuàng)建對象,將類交給工廠管理,要做什么樣的事情讓工廠幫我們創(chuàng)建對象 ???????HairFactory?factory?=?new?HairFactory(); ???????HairInterface?left?=?factory.getHair("left"); ???????left.draw(); ???????HairInterface?right?=?factory.getHair("right"); ???????right.draw(); ?????????????? ???????//工廠根據(jù)類的名稱獲取對象,這樣只需增加類,在創(chuàng)建的時候傳入類限定名就可以 ???????HairInterface?left?=?factory.getHairByClass("LeftHair的全類限定名"); ???????left.draw(); ???????HairInterface?right?=?factory.getHair("RightHair的全類限定名"); ???????right.draw(); ?????????????? ???????//向上面?zhèn)魅肴愊薅苈闊?,在Java中有properties文件可以對類做映射關(guān)系,傳參的時候傳入類對應(yīng)的別名就OK ???????HairInterface?left?=?factory.getHairByClassKey("right"); ???????right.draw(); ???????HairInterface?in?=?factory.getHairByClassKey("in"); ??????????????in.draw(); ????} }
//對發(fā)型進(jìn)行統(tǒng)一的管理 public?class?HairFactory{ ????//根據(jù)類型來創(chuàng)建對象,但是每多創(chuàng)建一種就要加if判斷 ????public?HairInterface?getHair(String?key){ ????????if("left".equals(key)){ ????????????return?new?LeftHair(); ????????}else?if("right".equals(key)){ ????????????return?new?RightHair(); ????????} ????????return?null; ????} ????//Java反射機制創(chuàng)建對象,根據(jù)類的名稱創(chuàng)建對象 ????public?HairInterface?getHairByClass(String?className){ ????????try{ ????????????HairInterface?hair?=?Class.forName(className).newInstance(); ????????????return?hair; ????????}catch(Exception?e){//有具體的異常抓捕,這里用Exception代替 ????????????e.printStackTrace(); ????????} ????????return?null; ????} ????//讀取properties文件獲取全類限定名 ????????public?HairInterface?getHairByClassKey(String?key){ ????????????try{ ????????????????Map<String,String>?map?=?new?PropertiesReader().getProperties(); ????????????????HairInterface?hair?=?Class.forName(map.get(key)).newInstance(); ????????????????return?hair; ????????????}catch(Exception?e){//有具體的異常抓捕,這里用Exception代替 ????????????????e.printStackTrace(); ????????????} ????????????return?null; ????} ???? }
--type.properties left=LeftHair的全類限定名 right=RightHair的全類限定名 in=InHair的全類限定名
//讀取properties文件類 public?class?PropertiesReader{ ????public?Map<String,String>?getProperties(){ ????????Properties?props?=?new?Properties(); ????????Map<String,String>?map?=?new?HashMap<String,String>(); ????????try{ ????????????InputStream?in?=?getClass.getReaourceAsStream("type.properties"); ????????????props.load(in); ????????????Enumration?en?=?props.propertyNames(); ????????????While(en.hasMoreElements()){ ????????????????String?key?=?(String)en.nextElement(); ????????????????String?property?=?props.getProperty(key); ????????????????map.put(key,property); ????????????????//System.out.println(key?+?"??"+?property); ????????????} ????????}catch(Exception?e){ ????????????e.printStackTrace(); ????????} ????????return?map; ????} ????public?static?void?main(String[]?args){ ????????PropertiesReader?reader?=?new?PropertiesReader(); ????????Map<String,String>?map?=?reader.getProperties(); ????????Syatem.out.println(map.get("in")); ????} }
抽象工廠模式類圖:
抽象工廠模式代碼示例:
//男孩 public?interface?Boy{ ????public?void?drawMan(); } //女孩 public?interface?Girl{ ????public?void?drawWomen(); }
//圣誕系列女孩 public?class?MCGirl?implements?Girl{?? ????@override ????public?void?drawWomen(){ ????????System.out.println("圣誕系列的女孩子......"); ????} } //元旦系列女孩 public?class?HNGirl?implements?Girl{???? ????@override ????public?void?drawWomen(){ ????????System.out.println("新年系列的女孩子......"); ????} } //圣誕系列男孩 public?class?MCBoy?implements?Boy{?? ????@override ????public?void?drawMan(){ ????????System.out.println("圣誕系列的男孩子......"); ????}?? } //元旦系列男孩 public?class?HNBoy?implements?Boy{ ???@override ???public?void?drawMan(){ ???????System.out.println("新年系列的男孩子......"); ???}???? }
//人物的實現(xiàn)接口 public?interface?PersonFactory{ ????public?Boy?getBoy(); ???? ????public?Girl?getGirl(); } //圣誕系列工廠 public?class?MCFactory?implements?PersonFactory{ ???@override ???public?Boy?getBoy(){ ???????return?new?MCBoy(); ???} ???@override ???public?Girl?getGirl(){ ???????return?new?MCGirl(); ???} ??? } //元旦系列工廠 public?class?HNFactory?implements?PersonFactory{ ???@override ???public?Boy?getBoy(){ ???????return?new?HNBoy(); ???} ???@override ???public?Girl?getGirl(){ ???????return?new?HNGirl(); ???} }
public?class?SunnyTest{ ???public?static?void?main(String[]?args){ ???????//生產(chǎn)圣誕系列女孩 ???????PersonFactory?factory?=?new?MCFactory(); ???????Girl?girl?=?factory.getGirl(); ???????girl.drawWomen(); ???????//生產(chǎn)元旦系列男孩 ???????PersonFactory?factory?=?new?HNFactory(); ???????Boy?boy?=?factory.getBoy(); ???????boy.drawMan(); ???} }
五、總結(jié)
工廠方法模式和抽象工廠模式對比:
????1、工廠模式是一種極端情況的抽象工廠模式,而抽象工廠模式可以看成是工廠模式的推廣;
????2、工廠模式用來創(chuàng)建一個產(chǎn)品的等級結(jié)構(gòu),而抽象工廠模式是用來創(chuàng)建多個產(chǎn)品的等級結(jié)構(gòu);
????3、工廠模式只有一個抽象產(chǎn)品類,而抽象工廠模式有多個抽象產(chǎn)品類
工廠模式的是想幫助我們:
????1、系統(tǒng)可以在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品;
????2、客戶端不必關(guān)心對象如何創(chuàng)建,交給工廠創(chuàng)建,明確了創(chuàng)建;
????3、更好的理解面向?qū)ο蟮脑瓌t,面向接口編程,而不要面向?qū)崿F(xiàn)編程。
查看全部 -
工廠模式.
查看全部 -
Enumeration在這里我并不推薦使用,而是推薦使用Iterator接口。此接口的功能與 Iterator 接口的功能是重復(fù)的。此外,Iterator 接口添加了一個可選的移除操作,并使用較短的方法名。新的實現(xiàn)應(yīng)該優(yōu)先考慮使用 Iterator 接口而不是 Enumeration 接口。
查看全部 -
工廠模式:1、有一組類似的對象需要創(chuàng)建。
2、在編碼時不能預(yù)見需要創(chuàng)建哪種類的實例。
3、系統(tǒng)需要考慮拓展性,不依賴于產(chǎn)品類實例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié)
查看全部 -
理解查看全部
-
工廠模式的優(yōu)點
查看全部 -
工廠方法模式與抽象工廠模式總結(jié)查看全部
-
抽象工廠模式類圖
查看全部 -
一,工廠方法和抽象工廠方法的對比: 1)工廠模式是一種極端情況下的抽象工廠模式,通過前面的類圖和代碼實現(xiàn)我們可以看到這樣一個對比,而抽象工廠模式可以看成是工廠模式的推廣, 2)工廠模式用來創(chuàng)建一個產(chǎn)品的等級結(jié)構(gòu),而抽象工廠模式是用來創(chuàng)建多個產(chǎn)品的等級結(jié)構(gòu), 3)工廠模式只有一個抽象產(chǎn)品類,而抽象工廠模式有多個抽象產(chǎn)品類,總之就是單一對多個產(chǎn)品的這種對比。 二,工廠模式幫助我們實現(xiàn)了什么呢? 1)系統(tǒng)可以在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品, 2)客戶端不必關(guān)系對象如何去創(chuàng)建,明確了職責(zé),對象具體的創(chuàng)建交給了具體的產(chǎn)品,product1,product2,客戶端只要告訴工廠我需要哪一,product1還是product2,它們具體是怎么創(chuàng)建的,怎么組合的,都交給了具體的產(chǎn)品product1,product2 3)更好的理解面向?qū)ο蟮脑瓌t,面向接口編程,而不是面向?qū)崿F(xiàn)編程。 那我們整體的工廠模式就是這樣一個原則。 三,工廠模式適用于哪些場景呢? 1)一個系統(tǒng)應(yīng)當(dāng)不依賴于產(chǎn)品類實例被創(chuàng)立,組成和表示的細(xì)節(jié),就是說這個產(chǎn)品如何被創(chuàng)建,組成和表現(xiàn),我們都?xì)w結(jié)到具體的產(chǎn)品是如何實現(xiàn)上去了,與前端的client,和中端的factory都是沒有關(guān)系的, 2)這個系統(tǒng)的產(chǎn)品至少有一個產(chǎn)品族,工廠方法模式就是一個產(chǎn)品族,它是最簡單的一個等級, 3)同屬于同一個產(chǎn)品族的產(chǎn)品是設(shè)計成在一起使用的,這是毋庸置疑的,同屬于一個系列的產(chǎn)品,就是在一起的, 4)不同的產(chǎn)品以一系列的接口的面貌出現(xiàn),從未使系統(tǒng)不依賴于接口實現(xiàn)的細(xì)節(jié),我們都是面向接口編程的,不是面向?qū)崿F(xiàn)編程的,查看全部
-
設(shè)計模式---工廠模式——總結(jié)? 1、接下來看spring beanfactory,這是非常有名的工具,我們知道spring容器是一個控制反轉(zhuǎn),主要作用是生成bean,管理bean,從工廠模式來看,spring beanfactory就是生產(chǎn)bean,然后提供給客戶端。 2、來看一下bean實例化的過程:調(diào)用bena的默認(rèn)構(gòu)造方式生成bean的實例,暫稱為instance1,如果在bean配置文件中注入了bean的屬性,則在instance1基礎(chǔ)上進(jìn)行屬性注入形成instance2,這種注入是覆蓋性的,如果bean實現(xiàn)了InitializingBean接口,則調(diào)用afterPropertiesSet()方法,來改變或者操作instance2,得到instance3。其中:InitializingBean是spring提供的一個初始化bean的類,如果實現(xiàn)了這個類,則必須實現(xiàn)afterPropertiesSet()方法,接下來,如果bean的配置文件中指定了inti-method="init"屬性,又會調(diào)用一個初始化方法,則在instance3的基礎(chǔ)上又會進(jìn)行一些改變,編程instance4.
查看全部 -
抽象工廠類就是有一個工廠類接口,有多個具體的工廠類繼承這個工廠類接口,獲取工廠類需要制定具體調(diào)用哪一個工廠類實例,然后調(diào)用這個工廠類中的方法獲取指定的對象。
查看全部 -
property工具類的實現(xiàn)
public?class?propertiesReader?{ public?Map<String,String>?getProperties()?{ Properties?props=new?Properties(); Map<String,String>?map=new?HashMap<String,String>(); try?{ InputStream?in=getClass().getResourceAsStream("type.properties"); props.load(in); Enumeration?en?=?props.propertyNames(); while(en.hasMoreElements()) { String?key?=?(String)?en.nextElement(); String?propery?=?props.getProperty(key); map.put(key,?propery); } }?catch?(IOException?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } return?map; } }
查看全部 -
@設(shè)計模式——工廠模式——工廠模式概述
設(shè)計模式:是一套被反復(fù)使用,多數(shù)人知曉的,經(jīng)過分類編目的,代碼設(shè)計經(jīng)驗的總結(jié) 好處:可以提高代碼的重用性,讓代碼更容易被他人理解,保證代碼的可靠性 工廠模式: 實例化對象,用工廠方法代替new操作 工廠模式包括工廠方法模式和抽象工廠模式 抽象工廠模式是工廠方法模式的擴(kuò)展。 工廠模式的意圖:定義一個接口來創(chuàng)建對象,但是讓子類來決定哪些類需要被實例化。 工廠方法把實例化的工作推遲到子類中去實現(xiàn)。 適合工廠模式的情況: (1)有一組類似的對象需要創(chuàng)建。 (2)在編碼的時候不能預(yù)見需要創(chuàng)建哪種類的實例。 (3)系統(tǒng)需要考慮擴(kuò)展性,不應(yīng)依賴于產(chǎn)品類實例化如何被創(chuàng)建,組合和表達(dá)的細(xì)節(jié)。 設(shè)計: (1)盡量松耦合,(2)具體產(chǎn)品與客戶端剝離
查看全部 -
在java開發(fā)中,應(yīng)該活用配置文件去進(jìn)行開發(fā),將配置文件,加入到我們的擼代碼的思路中,這樣,擼代碼的思維,就比較的開闊
查看全部 -
我們現(xiàn)在有動物,植物,兩個對象,這兩個對象可以抽象出一個對象,生物;其中,動物,植物,都分別具有自己的獨有屬性,此時如果采用工廠模式,是否可以對動物,植物,進(jìn)行增刪改查(自我感覺不適用);其次,如果是生物中的方法,是否可以通過工廠模式實現(xiàn),比如呼吸(自我感覺適用)。
因此,針對于工廠模式來說,適用于,在一個方法中,使用了相同屬性的不同對象,如果在一個方法中,使用的不同的屬性,個人感覺,不適用工廠模式
查看全部 -
實例? instance
查看全部 -
工廠模式的應(yīng)用:jdbc
查看全部 -
根據(jù)類的名稱來創(chuàng)建對象? ? 反射機制
查看全部 -
工廠模式總結(jié) 適用于哪些場景
查看全部 -
工廠方法 vs 抽象工廠
查看全部 -
抽象工廠模式 常見應(yīng)用
查看全部
舉報