本文實例講述了Java設計模式之工廠模式。分享給大家供大家參考,具體如下:
一、 簡單工廠
先來思考一個問題。我們平時寫程序時,會有這種情況,A對象裡面需要調用B對象的方法,這時我們使用的一般是new關鍵字來創建一個B實例,然後調用B實例的方法。這種做法的壞處在於:A類的方法實現直接調用了B類的類名(這種方式也被稱為硬編碼耦合),一旦系統需要重構:需要使用C類來代替B類時,程序就不得不修改A類代碼,如果應用中有100個或者10000個類以硬編碼方式耦合了B類,則需要修改100個、10000個地方,這顯然是一種非常可怕的事情。
換一個角度來看這個問題:對已A對象而言,它只需要調用B對象的方法,並不關心B對象的實現、創建過程,考慮讓B類實現一個IB接口,而A類只需要與IB接口耦合――A類並不直接使用new關鍵字來創建B實例,而是重新定義一個工廠類:IBFactory,由該工廠類負責創建IB實例,而A類用過調用IBFactory工廠的方法來得到IB的實例。通過以上設計:需要使用C類代替B類,則只需要讓C類也實現IB接口,並改寫IBFactory工廠中創建IB實例的實現代碼,讓該工廠產生C實例即可。這種將多個類對象交給工廠類來生成的設計方式叫做簡單工廠模式。
以下是簡單工廠模式的代碼:
/** * 簡單工廠模式* * 需要工廠生產的對象實例所實現的共同的接口* 髮型接口* @author Administrator * */public interface Hair { /** * 畫髮型*/ public void draw();}/** * 左偏分髮型* @author Administrator * */public class LeftHair implements Hair { @Override public void draw() { System.out.println("----------------畫左偏分髮型-----------------"); }}/** * 右偏分髮型* @author Administrator * */public class RightHair implements Hair { @Override public void draw() { System.out.println("-----------------畫右偏分髮型------------------"); }}/** * 生產髮型的工廠* 要生產什麼髮型只需在這裡改就行了* @author Administrator * */public class HairFactory { public Hair getHair() { return new LeftHair(); //return new RightHair(); }}/** * 客戶端測試類* @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方法的實現即可。
使用簡單工廠模式的優勢在於:讓對象的調用者和對象的創建過程分離,當對象調用者需要對象時,直接向工廠請求即可,從而避免了對象的調用者與對象實現類以硬編碼方式耦合,以提高系統的可維護性、可擴展性。當然,工廠模式也有一個小小的缺陷,當產品修改時,工廠類也要做相應的修改,此處可使用策略模式進行解決,下面是代碼。
public interface HairBuilder { /** * 製造髮型* @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(); }}這種做法的好處是無需再去修改工廠類,將工廠裡面的創建對量邏輯根據不同的策略抽像出來,程序需要創建什麼對象,只需網工廠中傳入相應的builder即可。
二、工廠方法
在簡單工廠模式中,系統使用工廠類生產所有產品實例,且該工廠類決定生產哪個類的實例,即工廠類負責所有的邏輯判斷、實例創建等工作。
如果不想再工廠類中進行邏輯判斷,程序可以為不同的產品類提供不同的工廠,不同的工廠類生產不同的產品,無需再工廠類中進行複雜的邏輯判斷。這就有點類似於上面的簡單工廠模式結合策略模式,不同的是前者只有一個工廠,後者需要有多個工廠。下面是工廠方法模式的代碼。
/** * 工廠方法模式* 需要工廠生產的對象實例所實現的共同的接口* @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---------------------"); }}/** * 生產人的工廠* @author Administrator * */public interface PersonFactory { //生產人public Person getPerson();}/** * 生產man的工廠* @author Administrator * */public class ManFactory implements PersonFactory { @Override public Person getPerson() { return new Man(); }}/** * 聲場women的工廠* @author Administrator * */public class WomenFactory implements PersonFactory { @Override public Person getPerson() { return new Women(); }}/** * 客戶端測試類* @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(); }}這種的典型的特點就是在客戶端代碼中根據不同的工廠生產其對應的產品,不必把複雜的邏輯都放在工廠類裡面判斷。這種實現有一個很明顯的缺陷,就是客戶端與工廠類進行了耦合。
三、抽象工廠
採用上面的工廠方法的設計架構,客戶端代碼成功與被調用對象的實現類分離,但帶來了另一種耦合:客戶端代碼與不同的工廠類耦合。為了解決這種耦合的問題,考慮在增加一個工廠類,用來生成工廠實例,實現生產產品的工廠與客戶端分離,這種設計方式被稱為抽象工廠模式。下面是抽象工廠模式的代碼
/** * 抽象工廠模式* 生產PersonFactory的工廠* @author Administrator * */public class PersonFactoryFactory { public static PersonFactory getPersonFactory(String type) { if(type.equalsIgnoreCase("man")) { return new ManFactory(); } else { return new WomenFactory(); } }}/** * 客戶端測試類* @author Administrator * */public class PersonTest { public static void main(String[] args) { PersonFactory factory = PersonFactoryFactory.getPersonFactory("man"); Person person = factory.getPerson(); person.drawPerson(); }}更多java相關內容感興趣的讀者可查看本站專題:《Java數據結構與算法教程》、《Java操作DOM節點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。