1、工廠模式的介紹 java
工廠模式專門負責將大量有共同接口的類實例化。工廠模式能夠動態決定將哪個類實例化,沒必要事先知道每次要實例化哪個類。 數據庫
工廠模式的幾種形態: 工具
(1)簡單工廠(Simple Factory)模式,又稱靜態工廠方法模式(Static Factory Method Pattern)。 this
(2)工廠方法(Factory Method)模式,又稱多態性工廠(Polymorphic Factory)模式,或虛擬構造子(Virtual Constructor)模式; spa
(3)抽象工廠(Abstract Factory)模式,又稱工具箱(Kit 或Toolkit)模式。設計
2、簡單工廠模式 code
2.1簡單工廠模式介紹 對象
簡單工廠模式(Simple Factory Pattern):又稱爲靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。在簡單工廠模式中,能夠根據自變量的不一樣返回不一樣類的實例。簡單工廠模式專門定義一個類來負責建立其餘類的實例,被建立的實例一般都具備共同的父類。繼承
2.2簡單工廠模式角色 接口
(1)工廠類(Creator)角色:擔任這個角色的是工廠方法模式的核心,含有與應用緊密相關的商業邏輯。工廠類在客戶端的直接調用下建立產品對象,它每每由一個具體Java 類實現。
(2)抽象產品(Product)角色:擔任這個角色的類是工廠方法模式所建立的對象的父類,或它們共同擁有的接口。抽象產品角色能夠用一個Java 接口或者Java 抽象類實現。
(3)具體產品(Concrete Product)角色:工廠方法模式所建立的任何對象都是這個角色的實例,具體產品角色由一個具體Java 類實現。
2.3簡單工廠模式的優缺點
簡單工廠模式的優勢以下:
(1)工廠類含有必要的判斷邏輯,能夠決定在何時建立哪個產品類的實例,客戶端能夠免除直接建立產品對象的責任,而僅僅「消費」產品;簡單工廠模式經過這種作法實現了對責任的分割,它提供了專門的工廠類用於建立對象。 (2)客戶端無需知道所建立的具體產品類的類名,只須要知道具體產品類所對應的參數便可,對於一些複雜的類名,經過簡單工廠模式能夠減小使用者的記憶量。
(3)經過引入配置文件,能夠在不修改任何客戶端代碼的狀況下更換和增長新的具體產品類,在必定程度上提升了系統的靈活性。
簡單工廠模式的缺點以下:
(1)因爲工廠類集中了全部產品建立邏輯,一旦不能正常工做,整個系統都要受到影響。
(2)使用簡單工廠模式將會增長系統中類的個數,在必定程序上增長了系統的複雜度和理解難度。
(3)系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能形成工廠邏輯過於複雜,不利於系統的擴展和維護。
(3)簡單工廠模式因爲使用了靜態工廠方法,形成工廠角色沒法造成基於繼承的等級結構。
2.4簡單工廠模式的適用環境
(1)工廠類負責建立的對象比較少:因爲建立的對象較少,不會形成工廠方法中的業務邏輯太過複雜;
(2)客戶端只知道傳入工廠類的參數,對於如何建立對象不關心:客戶端既不須要關心建立細節,甚至連類名都不須要記住,只須要知道類型所對應的參數。
2.5簡單工廠模式的舉例
例:
//抽象產品角色 public interface Car{ public void drive(); } //具體產品角色 public class Benz implements Car{ public void drive() { System.out.println("Driving Benz "); } } public class Bmw implements Car{ public void drive() { System.out.println("Driving Bmw "); } } //工廠類角色 public class Driver{ //工廠方法.注意 返回類型爲抽象產品角色 public static Car driverCar(String s)throws Exception{ //判斷邏輯,返回具體的產品角色給Client if(s.equalsIgnoreCase("Benz")) return new Benz(); else if(s.equalsIgnoreCase("Bmw")) return new Bmw(); else throw new Exception(); } }
3、工廠方法模式
3.1工廠方法模式的介紹
工廠方法模式定義一個用於建立對象的接口,讓子類決定實例化哪個類。Factory Method是一個類的實例化延遲到其子類。
在工廠方法模式中,核心的工廠類再也不負責全部的產品的建立,而是將具體建立的工做交給子類去作。這個核心類則搖身一變,成爲了一個抽象工廠角色,僅負責給出具體工廠子類必須實現的接口,而不接觸哪個產品類應當被實例化這種細節。
3.2工廠方法模式角色
(1)抽象工廠(Creator)角色:擔任這個角色的是工廠方法模式的核心,它是與應用程序無關的。任何在模式中建立對象的工廠類必須實現這個接口。在上面的系統中這個角色由Java 接口Creator 扮演;在實際的系統中,這個角色也經常使用抽象Java 類實現。
(2)具體工廠(Concrete Creator)角色:擔任這個角色的是實現了抽象工廠接口的具體Java 類。具體工廠角色含有與應用密切相關的邏輯,而且受到應用程序的調用以建立產品對象。在本系統中給出了兩個這樣的角色,也就是具體Java
類ConcreteCreator1 和ConcreteCreator2。
(3)抽象產品(Product)角色:工廠方法模式所建立的對象的超類型,也就是產品對象的共同父類或共同擁有的接口。在本系統中,這個角色由Java 接口Product 扮演;在實際的系統中,這個角色也經常使用抽象Java 類實現。 (4)具體產品(Concrete Product)角色:這個角色實現了抽象產品角色所聲明的接口。工廠方法模式所建立的每個對象都是某個具體產品角色的實例。
3.3工廠方法模式的優缺點
工廠方法模式的優勢以下:
(1)在工廠方法模式中,工廠方法用來建立客戶所須要的產品,同時還向客戶隱藏了哪一種具體產品類將被實例化這一細節,用戶只須要關心所需產品對應的工廠,無需關心建立細節,甚至無需知道具體產品類的類名。
(2)基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它可以使工廠能夠自主肯定建立何種產品對象,而如何建立這個對象的細節則徹底封裝在具體工廠內部。工廠方法模式之因此又被稱爲多態工廠模式,正是由於全部的具體工廠類都具備同一抽象父類。
(3)使用工廠方法模式的另外一個優勢是在系統中加入新產品時,無需修改抽象工廠和抽象產品提供的接口,無需修改客戶端,也無需修改其餘的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就能夠了,這樣,系統的可擴展性也就變得很是好,徹底符合「開閉原則」。
工廠方法模式的缺點以下:
(1)在添加新產品時,須要編寫新的具體產品類,並且還要提供與之對應的具體工廠類,系統中類的個數將成對增長,在必定程度上增長了系統的複雜度,有更多的類須要編譯和運行,會給系統帶來一些額外的開銷。
(2)因爲考慮到系統的可擴展性,須要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增長了系統的抽象性和理解難度,且在實現時可能須要用到DOM、反射等技術,增長了系統的實現難度。
3.4工廠方法模式的適用環境
在如下狀況下可使用工廠方法模式:
(1)一個類不知道它所須要的對象的類:在工廠方法模式中,客戶端不須要知道具體產品類的類名,只須要知道所對應的工廠便可,具體的產品對象由具體工廠類建立;客戶端須要知道建立具體產品的工廠類。
(2)一個類經過其子類來指定建立哪一個對象:在工廠方法模式中,對於抽象工廠類只須要提供一個建立產品的接口,而由其子類來肯定具體要建立的對象,利用面向對象的多態性和里氏代換原則,在程序運行時,子類對象將覆蓋父類對象,從而使得系統更容易擴展。
(3)將建立對象的任務委託給多個工廠子類中的某一個,客戶端在使用時能夠無需關心是哪個工廠子類建立產品子類,須要時再動態指定,可將具體工廠類的類名存儲在配置文件或數據庫中。
3.5工廠方法模式的舉例
例:
//抽象產品 PenCore.java public abstract class PenCore{ String color; public abstract void writeWord(String s); } //具體產品 RedPenCore.java public class RedPenCore extends PenCore { RedPenCore() { color = "紅色"; } public void writeWord(String s) { System.out.println("寫出" + color + "的字" + s); } } BluePenCore.java public class BluePenCore extends PenCore { BluePenCore() { color = "藍色"; } public void writeWord(String s) { System.out.println("寫出" + color + "的字" + s); } } BlackPenCore.java public class BlackPenCore extends PenCore { BlackPenCore() { color = "黑色"; } public void writeWord(String s) { System.out.println("寫出" + color + "的字" + s); } } //構造者 BallPen.java public abstract class BallPen { BallPen(){ System.out.println("生產一隻裝有"+getPenCore().color+"筆芯的圓珠筆"); } public abstract PenCore getPenCore(); } //具體構造者 RedBallPen.java public class RedBallPen extends BallPen { public PenCore getPenCore() { return new RedPenCore(); } } BlueBallPen.java public class BlueBallPen extends BallPen { public PenCore getPenCore() { return new BluePenCore(); } } BlackBallPen.java public class BlackBallPen extends BallPen { public PenCore getPenCore() { return new BlackPenCore(); } }
4、抽象工廠模式
4.1抽象工廠模式的介紹
抽象工廠模式提供一個建立一系列或相互依賴的對象的接口,而無需指定它們具體的類。
4.2抽象工廠模式角色
抽象工廠模式涉及到的系統角色
(1)抽象工廠(AbstractFactory)角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統的商業邏輯無關的。一般使用Java 接口或者抽象Java 類實現,而全部的具體工廠類必須實現這個Java 接口或繼承這個抽象Java 類。 (2)具體工廠類(Conrete Factory)角色:這個角色直接在客戶端的調用下建立產品的實例。這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。一般使用具體Java 類實現這個角色。
(3)抽象產品(Abstract Product)角色:擔任這個角色的類是工廠方法模式所建立的對象的父類,或它們共同擁有的接口。一般使用Java 接口或者抽象Java 類實現這一角色。
(4)具體產品(Concrete Product)角色:抽象工廠模式所建立的任何產品對象都是某一個具體產品類的實例。這是客戶端最終須要的東西,其內部必定充滿了應用系統的商業邏輯。一般使用具體Java 類實現這個角色。
4.3抽象工廠模式的優缺點
優勢:
(1) 隔離了具體類的生成,使得用戶不須要知道什麼被建立了。
(2) 當一個產品族中的多個對象被設計成一塊兒工做時,它可以保證客戶端始終
只使用同一個產品族中的對象。 缺點:
(1)添加新的產品對像時,難以擴展抽象工廠以便生產新種類的產品。
4.4抽象工廠模式的適用環境
(1)一個系統不該當依賴於產品類實例如何被建立、組合和表達的細節。這對於全部形態的工廠模式都是重要的;
(2)一個系統的產品有多於一個的產品族,而系統只消費其中某一族的產品; (3)同屬於同一個產品族的產品是在一塊兒使用的,這一約束必需要在系統的設計中體現出來;
(4)系統提供一個產品類的庫,全部的產品以一樣的接口出現,從而使客戶端不依賴於實現。
4.5抽象工廠模式的舉例
例:
//抽象產品 UpperClothes.java public abstract class UpperClothes { public abstract int getChestSize(); public abstract int getHeight(); public abstract String getName(); } Trousers.java public abstract class Trousers { public abstract int getWaistSize(); public abstract int getHeight(); public abstract String getName(); } //具體產品 WesternUpperClothes.java public class WesternUpperClothes extends UpperClothes { private int chestSize; private int height; private String name; WesternUpperClothes(String name,int chestSize,int height){ this.name=name; this.chestSize=chestSize; this.height=height; } public int getChestSize() { return chestSize; } public int getHeight() { return height; } public String getName() { return name; } } CowboyUpperClothes.java public class CowboyUpperClothes extends UpperClothes { private int chestSize; private int height; private String name; CowboyUpperClothes(String name,int chestSize,int height){ this.name=name; this.chestSize=chestSize; this.height=height; } public int getChestSize() { return chestSize; } public int getHeight() { return height; } public String getName () { return name; } } WesternTrousers.java public class WesternTrousers extends Trousers { private int waistSize; private int height; private String name; WesternTrousers(String name,int waistSize,int height){ this.name=name; this.waistSize=waistSize; this.height=height; } public int getHeight() { return height; } public String getName() { return name; } public int getWaistSize() { return waistSize; } } CowboyTrousers.java public class CowboyTrousers extends Trousers { private int waistSize; private int height; private String name; CowboyTrousers(String name,int waistSize,int height){ this.name=name; this.waistSize=waistSize; this.height=height; } public int getHeight() { return height; } public String getName() { return name; } public int getWaistSize() { return waistSize; } } //抽象工廠 ClothesFactory.java public abstract class ClothesFactory { public abstract UpperClothes createUpperClothes(int chestSize,int height); public abstract Trousers createTrousers(int waistSize,int height); } //具體工廠 BeijingClothesFactory.java public class BeijingClothesFactory extends ClothesFactory { public Trousers createTrousers(int waistSize, int height) { return new WesternTrousers("北京牌褲子",waistSize,height); } public UpperClothes createUpperClothes(int chestSize, int height) { return new WesternUpperClothes("北京牌上衣",chestSize,height); } } ShanghaiClothesFactory.java public class ShanghaiClothesFactory extends ClothesFactory { public Trousers createTrousers(int waistSize, int height) { return new WesternTrousers("上海牌褲子",waistSize,height); } public UpperClothes createUpperClothes(int chestSize, int height) { return new WesternUpperClothes("上海牌上衣",chestSize,height); } }