抽象工厂源码解析

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;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值