Java設(shè)計(jì)模式之工廠模式分析【簡(jiǎn)單工廠、工廠方法、抽象工廠】
本文實(shí)例講述了Java設(shè)計(jì)模式之工廠模式。分享給大家供大家參考,具體如下:
一、 簡(jiǎn)單工廠
先來(lái)思考一個(gè)問(wèn)題。我們平時(shí)寫(xiě)程序時(shí),會(huì)有這種情況,A對(duì)象里面需要調(diào)用B對(duì)象的方法,這時(shí)我們使用的一般是new關(guān)鍵字來(lái)創(chuàng)建一個(gè)B實(shí)例,然后調(diào)用B實(shí)例的方法。這種做法的壞處在于:A類的方法實(shí)現(xiàn)直接調(diào)用了B類的類名(這種方式也被稱為硬編碼耦合),一旦系統(tǒng)需要重構(gòu):需要使用C類來(lái)代替B類時(shí),程序就不得不修改A類代碼,如果應(yīng)用中有100個(gè)或者10000個(gè)類以硬編碼方式耦合了B類,則需要修改100個(gè)、10000個(gè)地方,這顯然是一種非??膳碌氖虑?。
換一個(gè)角度來(lái)看這個(gè)問(wèn)題:對(duì)已A對(duì)象而言,它只需要調(diào)用B對(duì)象的方法,并不關(guān)心B對(duì)象的實(shí)現(xiàn)、創(chuàng)建過(guò)程,考慮讓B類實(shí)現(xiàn)一個(gè)IB接口,而A類只需要與IB接口耦合——A類并不直接使用new關(guān)鍵字來(lái)創(chuàng)建B實(shí)例,而是重新定義一個(gè)工廠類:IBFactory,由該工廠類負(fù)責(zé)創(chuàng)建IB實(shí)例,而A類用過(guò)調(diào)用IBFactory工廠的方法來(lái)得到IB的實(shí)例。通過(guò)以上設(shè)計(jì):需要使用C類代替B類,則只需要讓C類也實(shí)現(xiàn)IB接口,并改寫(xiě)IBFactory工廠中創(chuàng)建IB實(shí)例的實(shí)現(xiàn)代碼,讓該工廠產(chǎn)生C實(shí)例即可。這種將多個(gè)類對(duì)象交給工廠類來(lái)生成的設(shè)計(jì)方式叫做簡(jiǎn)單工廠模式。
以下是簡(jiǎn)單工廠模式的代碼:
/** * 簡(jiǎn)單工廠模式 * * 需要工廠生產(chǎn)的對(duì)象實(shí)例所實(shí)現(xiàn)的共同的接口 * 發(fā)型接口 * @author Administrator * */ public interface Hair { /** * 畫(huà)發(fā)型 */ public void draw(); } /** * 左偏分發(fā)型 * @author Administrator * */ public class LeftHair implements Hair { @Override public void draw() { System.out.println("----------------畫(huà)左偏分發(fā)型-----------------"); } } /** * 右偏分發(fā)型 * @author Administrator * */ public class RightHair implements Hair { @Override public void draw() { System.out.println("-----------------畫(huà)右偏分發(fā)型------------------"); } } /** * 生產(chǎn)發(fā)型的工廠 * 要生產(chǎn)什么發(fā)型 只需在這里改就行了 * @author Administrator * */ public class HairFactory { public Hair getHair() { return new LeftHair(); //return new RightHair(); } } /** * 客戶端測(cè)試類 * @author Administrator * */ public class HairTest { public static void main(String[] args) { HairFactory factory = new HairFactory(); Hair hair = factory.getHair(); hair.draw(); } }
可以看到,如果想把HairTest里面生成的LeftHair改成RightHair,只需修改HairFactory里面getHair方法的實(shí)現(xiàn)即可。
使用簡(jiǎn)單工廠模式的優(yōu)勢(shì)在于:讓對(duì)象的調(diào)用者和對(duì)象的創(chuàng)建過(guò)程分離,當(dāng)對(duì)象調(diào)用者需要對(duì)象時(shí),直接向工廠請(qǐng)求即可,從而避免了對(duì)象的調(diào)用者與對(duì)象實(shí)現(xiàn)類以硬編碼方式耦合,以提高系統(tǒng)的可維護(hù)性、可擴(kuò)展性。當(dāng)然,工廠模式也有一個(gè)小小的缺陷,當(dāng)產(chǎn)品修改時(shí),工廠類也要做相應(yīng)的修改,此處可使用策略模式進(jìn)行解決,下面是代碼。
public interface HairBuilder { /** * 制造發(fā)型 * @return */ public Hair getHair(); } public class LeftHairBuilder implements HairBuilder { @Override public Hair getHair() { return new LeftHair(); } } public class RightHairBuilder implements HairBuilder { @Override public Hair getHair() { return new RightHair(); } } public class HairFactory { private HairBuilder hairBuilder; public HairFactory(HairBuilder hairBuilder) { this.hairBuilder = hairBuilder; } public void setHairBuilder(HairBuilder hairBuilder) { this.hairBuilder = hairBuilder; } public Hair getHair() { return hairBuilder.getHair(); } } public class HairTest { public static void main(String[] args) { // HairBuilder builder = new LeftHairBuilder(); HairBuilder builder = new RightHairBuilder(); HairFactory factory = new HairFactory(builder); Hair hair = factory.getHair(); hair.draw(); } }
這種做法的好處是無(wú)需再去修改工廠類,將工廠里面的創(chuàng)建對(duì)量邏輯根據(jù)不同的策略抽象出來(lái),程序需要?jiǎng)?chuàng)建什么對(duì)象,只需網(wǎng)工廠中傳入相應(yīng)的builder即可。
二、工廠方法
在簡(jiǎn)單工廠模式中,系統(tǒng)使用工廠類生產(chǎn)所有產(chǎn)品實(shí)例,且該工廠類決定生產(chǎn)哪個(gè)類的實(shí)例,即工廠類負(fù)責(zé)所有的邏輯判斷、實(shí)例創(chuàng)建等工作。
如果不想再工廠類中進(jìn)行邏輯判斷,程序可以為不同的產(chǎn)品類提供不同的工廠,不同的工廠類生產(chǎn)不同的產(chǎn)品,無(wú)需再工廠類中進(jìn)行復(fù)雜的邏輯判斷。這就有點(diǎn)類似于上面的簡(jiǎn)單工廠模式結(jié)合策略模式,不同的是前者只有一個(gè)工廠,后者需要有多個(gè)工廠。下面是工廠方法模式的代碼。
/** * 工廠方法模式 * 需要工廠生產(chǎn)的對(duì)象實(shí)例所實(shí)現(xiàn)的共同的接口 * @author Administrator * */ public interface Person { public void drawPerson(); } public class Man implements Person { @Override public void drawPerson() { System.out.println("---------------------draw a man--------------------"); } } public class Women implements Person { @Override public void drawPerson() { System.out.println("--------------------draw a women---------------------"); } } /** * 生產(chǎn)人的工廠 * @author Administrator * */ public interface PersonFactory { //生產(chǎn)人 public Person getPerson(); } /** * 生產(chǎn)man的工廠 * @author Administrator * */ public class ManFactory implements PersonFactory { @Override public Person getPerson() { return new Man(); } } /** * 聲場(chǎng)women的工廠 * @author Administrator * */ public class WomenFactory implements PersonFactory { @Override public Person getPerson() { return new Women(); } } /** * 客戶端測(cè)試類 * @author Administrator * */ public class PersonTest { public static void main(String[] args) { // PersonFactory factory = new ManFactory(); PersonFactory factory = new WomenFactory(); Person person = factory.getPerson(); person.drawPerson(); } }
這種的典型的特點(diǎn)就是在客戶端代碼中根據(jù)不同的工廠生產(chǎn)其對(duì)應(yīng)的產(chǎn)品,不必把復(fù)雜的邏輯都放在工廠類里面判斷。這種實(shí)現(xiàn)有一個(gè)很明顯的缺陷,就是客戶端與工廠類進(jìn)行了耦合。
三、抽象工廠
采用上面的工廠方法的設(shè)計(jì)架構(gòu),客戶端代碼成功與被調(diào)用對(duì)象的實(shí)現(xiàn)類分離,但帶來(lái)了另一種耦合:客戶端代碼與不同的工廠類耦合。為了解決這種耦合的問(wèn)題,考慮在增加一個(gè)工廠類,用來(lái)生成工廠實(shí)例,實(shí)現(xiàn)生產(chǎn)產(chǎn)品的工廠與客戶端分離,這種設(shè)計(jì)方式被稱為抽象工廠模式。下面是抽象工廠模式的代碼
/** * 抽象工廠模式 * 生產(chǎn)PersonFactory的工廠 * @author Administrator * */ public class PersonFactoryFactory { public static PersonFactory getPersonFactory(String type) { if(type.equalsIgnoreCase("man")) { return new ManFactory(); } else { return new WomenFactory(); } } } /** * 客戶端測(cè)試類 * @author Administrator * */ public class PersonTest { public static void main(String[] args) { PersonFactory factory = PersonFactoryFactory.getPersonFactory("man"); Person person = factory.getPerson(); person.drawPerson(); } }
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
- Java創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory)
- Java設(shè)計(jì)模式之抽象工廠模式淺析講解
- Java設(shè)計(jì)模式之抽象工廠模式(Abstract?Factory)
- Java?深入理解創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式
- 深入理解Java設(shè)計(jì)模式之抽象工廠模式
- Java設(shè)計(jì)模式之簡(jiǎn)單工廠 工廠方法 抽象工廠深度總結(jié)
- Java設(shè)計(jì)模式之抽象工廠模式詳解
- Java設(shè)計(jì)模式之抽象工廠模式
- Java設(shè)計(jì)模式筆記之抽象工廠代碼示例
- Java設(shè)計(jì)模式之抽象工廠模式實(shí)例詳解
- Java設(shè)計(jì)模式編程中簡(jiǎn)單工廠與抽象工廠模式的使用實(shí)例
- Java設(shè)計(jì)模式編程中的工廠方法模式和抽象工廠模式
- Java設(shè)計(jì)模式之工廠方法和抽象工廠
相關(guān)文章
eclipse連接不到genymotion問(wèn)題的解決方案
今天小編就為大家分享一篇關(guān)于eclipse連接不到genymotion問(wèn)題的解決方案,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03Java利用過(guò)濾器實(shí)現(xiàn)完善登錄功能
這篇文章主要為大家詳細(xì)介紹了Java如何利用過(guò)濾器實(shí)現(xiàn)完善登錄功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下2022-09-09淺析Java迭代器Iterator和Iterable的區(qū)別
Java語(yǔ)言中,Iterator和Iterable都是用來(lái)遍歷集合類數(shù)據(jù)結(jié)構(gòu)的接口,雖然它們有很多相似的地方,但在具體實(shí)現(xiàn)中卻有著一些不同之處,本文將詳細(xì)分析它們的區(qū)別,并提供相應(yīng)的代碼示例,需要的朋友可以參考下2023-07-07