-
簡單工廠模式(Simple Factory Pattern)是指由一個工廠對象決定創建哪一種產品類的實例,但它不屬於GoF的23種設計模式,簡單工廠模式適用於工廠類負責創建對象較小的場景,且客戶端只需要傳入工廠類的參數,對於如何創建對象不需要關心
-
我們來看代碼:
pubic interface ILanguage{
//學習語言
public void study();
}
- 創建一個Java語言實現Language類
public class Java implements ILanguage{
public void study(){
System.out.println("學習Java語言");
}
}
- 客戶端調用代碼
pubic static void main (String[] args){
ILanguage language = new Java();
language.study();
}
- 在上面的代碼中,父類ILanguage 指向子類Java的引用,應用層代碼需要依賴Java,如果業務擴展,繼續增加Python甚至更多語言,那麼客戶端會變得非常臃腫,因此,我們要把這種依賴減弱,把創建的細節因此,現在我們用簡單工廠模式對代碼進行優化。
- 先增加課程類Python
public class Python implements ILanguage{
public void study(){
System.out.println("學習Python語言");
}
}
- 創建工廠類LanguageFactory
public class LanguageFactory{
public ILanguage create(String name){
if("java".equals(name)){
return new Java();
}else if("python".equals(name)){
return new Python();
}else{
return null;
}
}
}
- 客戶端修改代碼如下:
public static void main (String[] args){
LanguageFactory factory = new LanguageFactory();
factory.create("java");
}
-
下面我們看下類圖
-
客戶端調用變簡單了,但是如果我們業務繼續擴展,要增加前端語言,那麼工廠裏的create豈不是一直修改,不符合開閉原則,因此,我們還可以對簡單工廠模式繼續優化,採用反射技術
public class LanguageFactory{
public ILanguage create(String cassName){
try(){
if(StringUtils.isNotEmpty(name)){
return (ILanguage) Class.forName(className).newInstance();
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
- 修改客戶端代碼
public static void main (String[] args){
LanguageFactory factory = new LanguageFactory();
ILanguage language = factory.create("com.example.designPattern.simpleFactoryPattern.Java");
language.study();
}
-優化之後,產品不斷迭代,方法參數是字符串,可控性較差,還需要強制轉換類型,繼續整
public ILanguage create(Class<? extends ILanguage> clazz){
try{
if(null != clazz){
return clazz.newInstance();
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
- 優化客戶端代碼
public static void main (String[] args){
LanguageFactory factory = new LanguageFactory();
ILanguage language = factory.create(Java.class);
language.study();
}
-
類圖如下
-
簡單工廠模式在JDK源碼下的應用
-
Logger
-
簡單工廠模式的缺點,工廠類的職責相對過重,不易於擴展。
-
下期 工廠方法模式