工廠模式相當于創(chuàng)建實例對象的new,我們經(jīng)常要根據(jù)類Class生成實例對象,如A a=new A() 。工廠模式也是用來創(chuàng)建實例對象的,所以new時就要多個心眼,是否可以考慮實用工廠模式,雖然這樣做,可能多做一些工作,但會給你系統(tǒng)帶來更大的可擴展性和盡量少的修改量。設想一個場景:一個肉鋪老板賣肉,因為剛開張生意冷清,也就先賣下豬肉吧。
類圖如下:

原先我們可能會在客戶端直接調(diào)用比如Pig asiaPig = new AsiaPig()之類的代碼,但現(xiàn)在我們只需調(diào)用PigFactory.createPig(***)來達到對Pig實現(xiàn)類的創(chuàng)建,這樣客戶端程序中超類的代碼和子類對象的創(chuàng)建代碼解藕了。
public class PigFactory {
@SuppressWarnings("unchecked")
public static Pig createPig(String pigName) {
if ("AsiaPig".equals(pigName)) {
return new AsiaPig();
} else if ("AfricanPig".equals(pigName)) {
return new AfricanPig();
} else {
return null;
}
}
}
public class PorkStore {
private static void sendPork(String pigName) {
Pig africanPig = PigFactory.createPig(pigName);
africanPig.send();
}
public static void main(String[] args) {
sendPork("AsiaPig");
sendPork("AfricanPig");
}
}
這樣做的另一個問題又出來了,隨著if else的增多代碼塊變的越趨龐大,這時就可利用java的發(fā)射來進行改善了,調(diào)整如下:
package factoryMethod;
public class PigFactory {
@SuppressWarnings("unchecked")
public static Pig createPig(String pigNme) {
try {
Class animalClass = Class.forName(pigNme);
return (Pig)animalClass.newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException("caught exception while found the class", e);
} catch (InstantiationException e) {
throw new RuntimeException("caught exception while instantiation", e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
public class PorkStore {
private static void sendPork(String pigName) {
Pig africanPig = PigFactory.createPig(pigName);
africanPig.send();
}
public static void main(String[] args) {
sendPork("factoryMethod.AsiaPig");
sendPork("factoryMethod.AfricanPig");
}
}
共廠方法模式定義了一個創(chuàng)建對象的接口,但由子類決定要實例化的類是哪一個,讓類把實例化推遲到子類。