一、簡單工廠模式
簡單工廠模式(Simple Factory Pattern)是指由一個工廠對象決定創建出哪一種產品類 的實例。屬於創建型模式,但它不屬於 GOF,23 種設計模式
(參考資料: http://en.wikipedia.org/wiki/Design_Patterns#Patterns_by_Type)。
簡單工廠模式適用於的場景:
1、適用 於工廠類負責創建的對象較少的場景,
2、且客戶端只需要傳入工廠類的參數,對於如何創 建對象的邏輯不需要關心。
簡單工廠模式缺點:
1、工廠類的職業相對過重,增加新的產品時需要修改工廠類的判斷邏輯,違背開閉原則
2、不易於擴展過於復雜的產品結構
下面手寫一個簡單的工廠模式
/**
* @Description 需要實現的接口
* @Author Bert
* @Date 2019\5\21
*/
public interface ICoure {
public void record();
}
/**
* @Description 實現ICoure
* @Author Bert
* @Date 2019\5\21 0021
*/
public class JavaCoure implements ICoure {
@Override
public void record() {
System.out.println("錄制Java課程!");
}
}
/**
* @Description 工廠類 將類的創建過程封裝到工廠里面
* @Author Bert
* @Date 2019\5\21 0021
*/
public class CourseFactory {
/**
* @Description 通過name判斷,創建對應的對象
* @Date 2019\5\21 0021 23:05
* @Param [name]
* @return com.bert.simple.factory.ICoure
*/
public ICoure create(String name){
if("Java".equals(name))
return new JavaCoure();
if("Python".equals(name))
return new PythonCoure();
else
return null;
}
/**
* @Description //通過類的全路徑
* @Date 2019\5\21 0021
* @Param [className]
* @return com.bert.simple.factory.ICoure
*/
public ICoure create1(String className){
try {
if( null != className && !"".equals(className)){
return (ICoure)Class.forName(className).newInstance();
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* @Description 傳入一個Class,可以避免輸入錯誤的內容
* @Date 2019\5\21 0021
* @Param [clazz]
* @return com.bert.simple.factory.ICoure
*/
public ICoure create2(Class clazz){
if (null != clazz) {
try {
return (ICoure) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
/**
* @Description 測試類
* @Author Bert
* @Date 2019\5\21 0021
*/
public class SimpleFactoryTest {
public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
/**
* 通過簡單的工廠創建
*/
ICoure iCoure = factory.create("Java");//方式1
iCoure.record();
ICoure factory1 = factory.create1("com.bert.simple.factory.JavaCoure");//方式2
factory1.record();
ICoure factory2 = factory.create2(JavaCoure.class);//方式3
factory2.record();
}
}
簡單工廠模式在 JDK 源碼也是無處不在 現在我們來舉個例子:
/* 里面通過createCalendar(TimeZone zone, Locale aLocale)傳入時區、語言 創建不同時區的時間 */
Calendar calendar = Calendar.getInstance();/* getInstance()是一個工廠模式,也是一個單例模式 */
//Calendar 源碼
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
/* getLogger(Class<?> clazz) 典型的工廠模式 */
Logger logger = LoggerFactory.getLogger(SimpleFactoryTest.class);/*也是一個單例*/
//LoggerFactory源碼
public static Logger getLogger(Class<?> clazz) {
Logger logger = getLogger(clazz.getName());
if (DETECT_LOGGER_NAME_MISMATCH) {
Class<?> autoComputedCallingClass = Util.getCallingClass();
if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
}
}
return logger;
}
二、工廠方法模式
工廠方法模式(Fatory Method Pattern)是指定義一個創建對象的接口,但讓實現這個 接口的類來決定實例化哪個類,工廠方法讓類的實例化推遲到子類中進行。屬於創建型模式,23中設計模式之一,在工廠方法 模式中用戶只需要關心所需產品對應的工廠,無須關心創建細節,而且加入新的產品符 合開閉原則。
/**
* @Description 需要實現的接口
* @Author Bert
* @Date 2019\5\21
*/
public interface ICoure {
public void record();
}
/**
* @Description 實現ICoure
* @Author Bert
* @Date 2019\5\21 0021
*/
public class JavaCoure implements ICoure {
@Override
public void record() {
System.out.println("錄制Java課程!");
}
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\21 0021
*/
public class PythonCoure implements ICoure {
@Override
public void record() {
System.out.println("錄制Python課程!");
}
}
/**
* @Description 工廠接口
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface ICoureFactory {
ICoure create();
}
/**
* @Description Java方法工廠
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaICoureFactory implements ICoureFactory{
@Override
public ICoure create() {
return new JavaCoure();
}
}
/**
* @Description Python方法工廠
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonICoureFactory implements ICoureFactory{
@Override
public ICoure create() {
return new PythonCoure();
}
}
/**
* @Description 工廠方法模式測試類
* @Author Bert
* @Date 2019\5\22 0022
*/
public class FactoryMethodTest {
public static void main(String[] args) {
ICoureFactory iCoureFactory = new JavaICoureFactory();
ICoure iCoure = iCoureFactory.create();
iCoure.record();
PythonICoureFactory iCoureFactory1 = new PythonICoureFactory();
ICoure iCoure1 = iCoureFactory1.create();
iCoure1.record();
}
}
類圖如下:

工廠方法模式的適用場景:
1、創建對象需要大量重復的代碼
2、客戶端(應用層)不依賴於產品類實例如何被創建、實現等細節,一個類通過其子類來指定創建哪個對象。
工廠方法模式的優點:
1、用戶只關系所需產品對應的工廠,無須關心創建細節。
2、加入新產品符合開閉原則,提高了系統的可擴展性。
工廠方法模式的缺點:
1、類的個數容易過多,增加了代碼結構的復雜度。
2、增加了系統的抽象性和理解難度。
三、抽象工廠模式
抽象工廠模式(Abstract Factory Pattern)是指提供一個創建一系列相關或者相互依賴對象的接口,無須指定他們具體的類。
屬於創建型設計模式。
/**
* @Description 需要實現的接口
* @Author Bert
* @Date 2019\5\21
*/
public interface ICoure {
public void record();
}
/**
* @Description 實現ICoure
* @Author Bert
* @Date 2019\5\21 0021
*/
public class JavaCoure implements ICoure {
@Override
public void record() {
System.out.println("錄制Java課程!");
}
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\21 0021
*/
public class PythonCoure implements ICoure {
@Override
public void record() {
System.out.println("錄制Python課程!");
}
}
/**
* @Description 要求所有的工廠都實現這個工廠
* 一個品牌的抽象
* 1、 抽象工廠不符合開閉原則 (在頂層接口中添加的抽象方法,在繼承他的類都需要繼承)
* 2、擴展性強
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface ICouseeFactory {
ICoure createCourse();
Inote createNote();
Ivideo createVideo();
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface Inote {
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public interface Ivideo {
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaNote implements Inote{
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaVideo implements Ivideo {
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonNote implements Inote {
}
/**
* @Description TODO
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonVideo implements Ivideo {
}
/**
* @Description JAVA 課程實現
* @Author Bert
* @Date 2019\5\22 0022
*/
public class JavaCourseFactory implements ICouseeFactory {
@Override
public ICoure createCourse() {
return new JavaCoure();
}
@Override
public Inote createNote() {
return new JavaNote();
}
@Override
public Ivideo createVideo() {
return new JavaVideo();
}
}
/**
* @Description Python課程實現
* @Author Bert
* @Date 2019\5\22 0022
*/
public class PythonCourseFactory implements ICouseeFactory {
@Override
public ICoure createCourse() {
return new PythonCoure();
}
@Override
public Inote createNote() {
return new PythonNote();
}
@Override
public Ivideo createVideo() {
return new PythonVideo();
}
}
/**
* @Description 抽象工廠 測試類
* @Author Bert
* @Date 2019\5\22 0022
*/
public class AbstactFactoryTest {
public static void main(String[] args) {
ICouseeFactory factory = new JavaCourseFactory();
factory.createCourse().record();
factory.createNote();
factory.createVideo();
}
}
抽象工廠模式使用場景:
1、客戶端(應用層)不依賴於產品類實例如何被創建,實現等細節。
2、強調一系列相關的產品對象(屬於同一產品族)一起使用創建對象需要大量重復的代碼。
3、提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體的實現。
抽象工廠模式優點:
1、具體產品在應用層代碼隔離,無須關系創建細節。
2、將一個系列的產品族統一到一起創建。
抽象工廠模式缺點:
1、規定了所有可能被創建的產品集合,產品族中擴展新的產品困難,需要修改抽象工廠的接口。
2、增加了系統的抽象性和理解難度。
Spring 中用到的抽象工廠模式例如:DefaultListableBeanFactory
