抽象工厂源码解析
public interface Connection extends Wrapper, AutoCloseable 數據庫連接的一個接口,本身它是一個接口,這里面有很多方法,很多方法很自然也都是抽象方法,實現這個接口的類要進行實現,Statement createStatement() throws SQLException;這里面返回了Statement,下面接著看,他又返回了PreparedStatement prepareStatement(String sql) throws SQLException;他又返回PreparedStatement,很容易理解,在這個Connection接口里面,返回的都屬于同一個產品族,例如我們創建一個MYSQL的Connection,或者SQLSERVER,從這個連接獲取的無論是PreparedStatement還是Statement,都是連接,也就是說mysql去獲取的時候,肯定是獲取MYSQL連接的Statement,如果調用prepareStatement這個方法肯定是獲取MYSQL連接的PreparedStatement,所以這里面定義的各種獲取方法,他們都屬于同一個產品族,同理我們再看一個類,還是java.sql這個包下的,有一個Statement這個類,也就是剛才那個方法的返回值,首先我們看一下這個也是一個接口,public interface Statement extends Wrapper, AutoCloseable這里面executeQuery返回一個ResultSet,executeUpdate返回一個int,下面返回也是同一個Statement,很明顯這里也是一個抽象工廠,這里面的所有方法都需要子類來實現,并且只要是從這個Statement獲取的時候,獲取的肯定是同一個產品族,我們看到他有很多實現類,同理Connection也有很多實現類,例如我們這里導入了MYSQL的驅動,我們看一下,只要我們從MYSQL實現里面獲取
一定要是屬于MYSQL產品族的,MYSQL這里就可以理解什么是抽象工廠,所以在Connection和Statement這里面呢,我們很清楚的理解到什么是抽象工廠,以及在JDK中怎么使用,我們看一下Mybatis的,這里也是一個接口
但是我們注意到,這里面不僅僅返回SqlSession,還要返回Configuration,那很明顯,只要通過SqlSessionFactory,去獲取的兩種類型,肯定是屬于同一個產品族,無論是mysql的sqlSessionFactory,還是SQLSERVER的sqlSessionFactory,獲取的產品也都是屬于同一個產品族,我們看一下他的實現類,實現類有兩個,一個是默認的SqlSessionFactory,還有SqlSessionManager這兩個類,那這兩個類肯定實現了他們這兩個方法,其實SqlSession是Mybatis工作的一個核心,SqlSessionFactory創建的是SqlSession,我們進來看一下,我們看一下方法,只能非常多
包括執行SQL,獲取mapper,管理事務,包括這里面的rollback,他比較類似于Mysql的connection對象,那之前我們也看了,SqlSession里面有很多重載方法,包括支持AutoCommit,使用ExecutorType,關于事務的一些處理,通過這些來構建核心的SqlSession對象
那我們看一下,在默認的SqlSessionFactory里面,是怎么使用的,我們打開這個實現類,我們打開openSession,這里面有很多重載的方法
我們找一個帶事務的吧,我們看一下,通過這個方法我們來研究一下
這工廠怎么產生一個產品,我先從configration里面去獲取環境變量,然后初始化這個事務工廠,對他進行賦值,再獲取Transaction,然后再通過transaction作為他的入參,獲取一個Executor,然后再通過配置,executor,和autoCommit,這三個參數來構建默認的DefaultSqlSession,那也就是說在這個方法里面,返回值是SqlSession,實際返回的是DefaultSqlSession,那明顯這兩個類之間就是抽象工廠,這么一個模式,比較典型,希望通過這一段源碼解析,能帶來更好的吸收和理解
package com.learn.design.pattern.creational.abstractfactory;/*** 再創建一個手記的class* 那這兩個類呢也都是抽象類* * * @author Leon.Sun**/
public abstract class Article {public abstract void produce();
}
package com.learn.design.pattern.creational.abstractfactory;/*** 創建這個Video class* * * @author Leon.Sun**/
public abstract class Video {public abstract void produce();}
package com.learn.design.pattern.creational.abstractfactory;/*** 創建抽象類和接口的一個業務場景的選擇* 那在我們這里面呢* 我們會聲明兩個方法* 一個是獲取視頻* 一個是獲取手記* 而這兩個都是抽象方法* 使用抽象類也是OK的* 只不過這兩種我們都來體會一下* 我們寫兩個方法* * 課程是視頻加手記* 才可以稱之為內容* 那么我們就聲明一個產品族的一個工廠* 我們聲明Java課程的一個工廠* * * @author Leon.Sun**/
public interface CourseFactory {Video getVideo();Article getArticle();}
package com.learn.design.pattern.creational.abstractfactory;/*** 他呢繼承Video* * * @author Leon.Sun**/
public class JavaVideo extends Video {@Overridepublic void produce() {System.out.println("錄制Java課程視頻");}
}
package com.learn.design.pattern.creational.abstractfactory;/*** 他呢繼承Article這個類* * * @author Leon.Sun**/
public class JavaArticle extends Article {/*** 然后實現produce方法* */@Overridepublic void produce() {System.out.println("編寫Java課程手記");}
}
package com.learn.design.pattern.creational.abstractfactory;/*** 他來實現CourseFactory* 那現在我們要找到具體的Java視頻和Java手記* 那我們繼續聲明類* * 我們使用抽象工廠的時候* 并沒有聲明視頻的工廠和手記的工廠* 而是聲明一個組合到一起的課程的工廠* 但是具體的產品是有的* Java手記和Java視頻* Java課程作為產品族* 他包含視頻和手記* 那我們接著寫一套Python的* * @author Leon.Sun**/
public class JavaCourseFactory implements CourseFactory {@Overridepublic Video getVideo() {/*** 這里直接返回JavaVideo* */return new JavaVideo();}@Overridepublic Article getArticle() {/*** 這里就直接返回JavaArticle* */return new JavaArticle();}
}
package com.learn.design.pattern.creational.abstractfactory;/*** PythonVideo繼承Video* 然后再寫一個Pathon的手記* * @author Leon.Sun**/
public class PythonVideo extends Video {@Overridepublic void produce() {System.out.println("錄制Python課程視頻");}
}
package com.learn.design.pattern.creational.abstractfactory;/*** 繼承Article* * * @author Leon.Sun**/
public class PythonArticle extends Article {@Overridepublic void produce() {System.out.println("編寫Python課程手記");}
}
package com.learn.design.pattern.creational.abstractfactory;/*** 我們再創建一個Pathon的課程工廠* 他呢實現課程工廠CourseFactory* 然后把里面的具體實現* 寫一下* 當我們要擴展課程的時候* 只需要創建產品族的一個工廠* 還有具體的產品就可以* 現在我們對整體的抽象工廠我們看一下* 我們看一下類圖* * * @author Leon.Sun**/
public class PythonCourseFactory implements CourseFactory {@Overridepublic Video getVideo() {/*** 這里直接new一個PythonVideo*/return new PythonVideo();}@Overridepublic Article getArticle() {/*** 這里直接new一個PythonArticle* */return new PythonArticle();}
}
package com.learn.design.pattern.creational.abstractfactory;import java.sql.Connection;/*** 都是一個產品族* 注意一定要強調產品族的概念* 在抽象工廠這個設計模式當中* 那我們來看一下UML* * @author Leon.Sun**/
public class Test {public static void main(String[] args) {/*** 我們創建一個CourseFactory* 我們new一個JavaCourseFactory* * */CourseFactory courseFactory = new JavaCourseFactory();/*** 這個Video我們直接從courseFactory里面去取* * */Video video = courseFactory.getVideo();/*** 這個手記我也是直接從courseFactory去取* 只要從這個工廠里面取的* 肯定都是Java產品族的* * */Article article = courseFactory.getArticle();video.produce();article.produce();Connection c = null;}
}
?
總結