工廠方法模式定義:定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法讓類把實例化推遲到子類。
UML類圖:
所有工廠模式都用來封裝對象的創建。工廠方法模式通過讓子類決定改創建的對象是什麼,來達到將對象創建的過程封裝的目的。
1. Creator所有子類都必須實現這個抽象的factoryMethod()方法。
2. ConcreteCreator實現了factoryMethod(),以實際製造出產品。由它負責創建一個或多個集體產品,只有此類知道如何創建這些產品。
3. 所有產品ConcreteProduct必須實現Product,這樣就可以使用這個接口,而不是具體的類。
注意:這裏說的實現不一定是實現接口,而是泛指超類。
所有工廠模式都用來封裝對象的創建。工廠方法模式通過讓子類決定改創建的對象是什麼,來達到將對象創建的過程封裝的目的。這樣做的好處是在實例化對象時,只會依賴於接口,而不是具體的類。(設計原則:針對接口編程)
例如:有一個蛋糕工廠,由蛋糕工廠負責生產各種蛋糕(奶油蛋糕、巧克力蛋糕、水果蛋糕、冰欺凌蛋糕等等)
//蛋糕類
public abstract class Cake {
protected String name;//名字
public void make() {
System.out.println("做蛋糕---");
}
public String makeDone() {
return name;
}
}
//巧克力蛋糕
public class ChocolateCake extends Cake {
public ChocolateCake() {
name = "巧克力蛋糕";
}
}
//奶油蛋糕
public class MilkCake extends Cake{
public MilkCake() {
name = "巧奶油蛋糕";
}
}
//工廠
public abstract class Factory {
//1.工廠方法是抽象的。
//2.工廠方法必須返回一個產品。
//3.工廠方法將客戶(超類中的代碼,例如:toMake())和具體創建產品的代碼分隔開來。
abstract Cake createCake(String item);
public Cake toMake(String type){
Cake cake = createCake(type);
return cake;
}
}
//蛋糕工廠 利用java反射機制
public class CakeFactory extends Factory{
@Override
Cake createCake(String ClassName) {
Cake c = null;
try {
c=(Cake)Class.forName(ClassName).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return c;
}
}
//客戶端
public class ClientTest {
public static void main(String[] args) {
//首先先創建一個蛋糕工廠
Factory factory = new CakeFactory();
//由蛋糕店工廠負責生產客戶所需要的蛋糕。
Cake cake = factory.toMake("com.csdn.reflectfactory.MilkCake");
Cake cake_ = factory.toMake("com.csdn.reflectfactory.ChocolateCake");
//取出工廠創建的蛋糕
System.out.println(cake.makeDone());
System.out.println(cake_.makeDone());
}
}
輸出:奶油蛋糕
巧克力蛋糕
反射的好處是如果創建新種類的蛋糕不用修改工廠的代碼。
可以看看 沒用反射的工廠模式 http://blog.csdn.net/allen_gang/article/details/9033453