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 {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
package com.learn.design.pattern.creational.abstractfactory;
/**
* 他呢继承Article这个类
*
*
* @author Leon.Sun
*
*/
public class JavaArticle extends Article {
/**
* 然后实现produce方法
*
*/
@Override
public 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 {
@Override
public Video getVideo() {
/**
* 这里直接返回JavaVideo
*
*/
return new JavaVideo();
}
@Override
public Article getArticle() {
/**
* 这里就直接返回JavaArticle
*
*/
return new JavaArticle();
}
}
package com.learn.design.pattern.creational.abstractfactory;
/**
* PythonVideo继承Video
* 然后再写一个Pathon的手记
*
* @author Leon.Sun
*
*/
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python课程视频");
}
}
package com.learn.design.pattern.creational.abstractfactory;
/**
* 继承Article
*
*
* @author Leon.Sun
*
*/
public class PythonArticle extends Article {
@Override
public void produce() {
System.out.println("编写Python课程手记");
}
}
package com.learn.design.pattern.creational.abstractfactory;
/**
* 我们再创建一个Pathon的课程工厂
* 他呢实现课程工厂CourseFactory
* 然后把里面的具体实现
* 写一下
* 当我们要扩展课程的时候
* 只需要创建产品族的一个工厂
* 还有具体的产品就可以
* 现在我们对整体的抽象工厂我们看一下
* 我们看一下类图
*
*
* @author Leon.Sun
*
*/
public class PythonCourseFactory implements CourseFactory {
@Override
public Video getVideo() {
/**
* 这里直接new一个PythonVideo
*/
return new PythonVideo();
}
@Override
public 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;
}
}