Java設計模式:工廠模式
Java設計模式:工廠模式
【尊重原創,轉載請註明出處】http://blog.csdn.net/guyuealian/article/details/52015589
工廠模式的意圖:定義一個介面來建立物件,但是讓子類來決定哪些類需要被例項化。工廠方法把例項化的工作推遲到子類中去是實現。 工廠模式可以根據客戶的需要,定義一個工廠類專門負責建立類的例項。
一、先來看一下普通的設計模式:
public interface FruitInterface{
public void Colour();
}
public class Apple implements FruitInterface{
@Override
public void Colour() {
System.out.println("---蘋果的顏色是紅色的---");
}
}
public class Orange implements FruitInterface{
@Override
public void Colour() {
System.out.println("---橘子的顏色是黃色的---");
}
}
public class FruitTest { //客戶端程式
public static void main(String[] args) {
FruitInterface f = new Apple();
f.Colour();
}
}
上面的客戶端程式Fruit f = new Apple();可以獲得蘋果的顏色,但若要獲得橘子的顏色,就需要在客戶端增加橘子的例項化程式碼,並顯式的呼叫;這樣並不利於後期的維護和管理;決解的方法是新建一個工廠,通過IF判斷語句,根據客戶端需要,例項化對應的物件,實現對顏色的統一管理。二、新增加一個Factory作為過渡端,並通過過渡端取得介面的例項化物件,這個過渡端就是工廠類:
//工廠類,用於生產物件
public class Factory {
public FruitInterface getColour(String key) {
FruitInterface f = null;// 定義介面物件,通過過子類例項化
if ("Apple".equals(key)) {
f = new Apple();// 通過Apple類例項化介面
} else if ("Orange".equals(key)) {
f = new Orange();// 通過Orange類例項化介面
}
return f;
}
}
//客戶端程式
public class FruitTest {
public static void main(String[] args) {
//(1)普通設計模式,客戶端需要顯式的實現化物件
// FruitInterface f = new Apple();
// f.Colour();
//(2)工廠設計模式,客戶端僅需要改變輸入引數,增加新類時需要修改工廠類
Factory factory = new Factory();
FruitInterface colour = factory.getColour("Apple");
colour.Colour();
}
}
與普通的設計模式相比,工廠模式例項過程是在工廠類完成的,而不是在客戶端的程式碼中實現的,客戶端只需改變輸入引數(改變引數Apple),即可獲得對用的例項物件。通過工廠類,可以避免客戶端顯式的呼叫顏色這個方法,從而降低了客戶端程式與產品物件的耦合。三、繼續改進:工廠類中通過IF判斷語句,可以選擇性地建立需要的例項化物件;但這時,如果需要增加新的水果,如葡萄時;需要改動兩個地方:不僅需要新建一個葡萄的類,還需要在工廠類中新增判斷和例項化語句。為了降低程式的耦合,這時需要用到反射的機制來動態的建立物件。
繼續改進Factory類:
繼續改進Factory類:
//工廠類,用生產物件
public class Factory {
// 根據型別來建立物件
public FruitInterface getColour(String key) {
FruitInterface f = null;// 定義介面物件,同過子類例項化
if ("Apple".equals(key)) {
f = new Apple();// 通過Apple類例項化介面
} else if ("Orange".equals(key)) {
f = new Orange();// 通過Orange類例項化介面
}
return f;
}
// 通過反射,根據類的名稱來生產物件
public FruitInterface getColourByClass(String className) throws Exception {
FruitInterface fruit = (FruitInterface) Class.forName(className)
.newInstance();
return fruit;
}
}
//客戶端程式
public class FruitTest {
public static void main(String[] args) throws Exception {
//(1)普通設計模式,客戶端需要顯式的實現化物件
// FruitInterface f = new Apple();
// f.Colour();
//(2)工廠設計模式,客戶端僅需要改變輸入引數
//Factory factory = new Factory();
// FruitInterface colour = factory.getColour("Apple");
// colour.Colour();
//(3)通過反射的工廠設計模式,客戶端僅需要改變輸入引數
Factory factory = new Factory();
FruitInterface colour = factory.getColourByClass("com.fruit.Apple");
colour.Colour();
}
}
通過反射的工廠設計模式,當有新增加的類時,如增加葡萄這種水果,這時只需要新建一個子類Grape,並實現介面FruitInterface的方法Colour(),客戶端僅需要改變輸入引數(更改引數com.fruit.Apple即可),而Factory類不需要修改任何程式碼。PS:通過反射的方式建立物件,效能會要稍微低些,通常情況下,沒有必要使用反射來建立物件,只有當程式需要動態建立某個類的物件時才考慮使用反射。
四、升級改進:
通過反射的工廠設計模式已經可以大大的降低程式的耦合,但這時客戶端輸入引數時,需要輸入整個完整的全限定類名(即完整的包名+類名),如果需要多個例項物件,這時客戶端需要進行多次的更改引數;解決的方法是,把需要配置的引數以鍵值物件(Key-Value)的形式儲存在屬性檔案中。而客戶端只需要知道Key值就可以呼叫。
新建屬性檔案type.properties,其以key-value的形式儲存輸入引數和包名的對應關係
新建屬性檔案type.properties,其以key-value的形式儲存輸入引數和包名的對應關係
Apple=com.fruit.Apple
Orange=com.fruit.Orange
Grape=com.fruit.Grape
有了屬性檔案,就需要獲取和解釋該屬性檔案的類PropertiesReader //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().getResourceAsStream("type.properties");
props.load(in);
Enumeration 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;
}
}
在工廠類Factory中,新增加一個方法getColourByClassKey,獲取屬性檔案,並根據value值來生產物件://通過獲取屬性檔案,根據value值來生產物件
public FruitInterface getColourByClassKey(String key) throws Exception {
Map<String, String> map = new PropertiesReader().getProperties();
FruitInterface fruit = (FruitInterface) Class.forName(map.get(key))
.newInstance();
return fruit;
}
這時客戶端只需要傳入一個key值即可:// (4)傳入Key值,獲取屬性檔案
FruitInterface colour = factory.getColourByClassKey("Apple");
colour.Colour();
這種升級後的工廠設計模式,把需要的對映的關係都儲存到屬性檔案中,客戶端只需要知道屬性檔案中key值,就可以實現功能;維護時,只需要修改屬性檔案,把key值告訴客戶端使用者即可。相關文章
- Java設計模式(工廠模式)Java設計模式
- Java設計模式--工廠模式Java設計模式
- Java 設計模式(工廠模式)Java設計模式
- java設計模式-工廠模式Java設計模式
- java設計模式 – 工廠模式Java設計模式
- Java設計模式之工廠模式Java設計模式
- java設計模式–抽象工廠模式Java設計模式抽象
- java設計模式-工廠方法模式Java設計模式
- Java設計模式-抽象工廠模式Java設計模式抽象
- Java設計模式(工廠方法設計模式)Java設計模式
- Java 設計模式之工廠方法模式與抽象工廠模式Java設計模式抽象
- Java設計模式之工廠方法模式Java設計模式
- Java設計模式之(二)——工廠模式Java設計模式
- java設計模式-簡單工廠模式Java設計模式
- Java設計模式(二):工廠方法模式Java設計模式
- java設計模式之一 工廠模式Java設計模式
- Java設計模式之工廠模式(Factory)Java設計模式
- Java設計模式3:工廠方法模式Java設計模式
- 設計模式-工廠模式二(工廠方法模式)設計模式
- Java設計模式模式 (包括工廠模式xml解析)Java設計模式XML
- JAVA設計模式 3【建立型】理解工廠模式與抽象工廠模式Java設計模式抽象
- Java設計模式學習筆記——工廠模式與抽象工廠模式Java設計模式筆記抽象
- 【設計模式】工廠模式設計模式
- 設計模式 —— 工廠模式設計模式
- 設計模式-工廠模式設計模式
- 設計模式(工廠模式)設計模式
- 設計模式——工廠模式設計模式
- 設計模式----工廠模式設計模式
- 設計模式-簡單工廠、工廠方法模式、抽象工廠模式設計模式抽象
- 設計模式----工廠設計模式設計模式
- 設計模式-工廠設計模式設計模式
- 設計模式之工廠方法模式|抽象工廠模式設計模式抽象
- 3.java設計模式之工廠模式Java設計模式
- Java常用設計模式之工廠方法模式Java設計模式
- Java常用設計模式之抽象工廠模式Java設計模式抽象
- 我的Java設計模式-工廠方法模式Java設計模式
- 淺識JAVA設計模式——工廠模式(一)Java設計模式
- Java設計模式學習三-----工廠模式Java設計模式