形象工厂
1.定义与类型
- 形象工厂模式提供了一个创立一系列相干或者相互依赖对象的接口,无需指定它们具体的类
- 创立型
2.实用场景
- 客户端(应用层)不依赖于产品类实例如何被创立、实现等细节
- 强调一系列相干的产品对象(属于同一产品族)一起应用创建对象须要大量的反复代码
- 提供一个产品类的库,所有的产品以同样的接口呈现,从而使得客户端不依赖于具体的实现
3.长处:
- 具体产品在应用层的代码隔离,无需关怀创立的细节
- 将一个系列的产品对立到一起创立
4.毛病:
- 规定了所有可能被创立的产品汇合,产品簇中扩大新的产品艰难;
- 减少了零碎的抽象性和了解难度
5.Coding
编码之前咱们先明确一个概念:比方一个车厂,他可能做汽车,电动车,自行车。对于上面一些列的从属产品,又别离设立了汽车厂,电动车厂,自行车厂...
在这个例子中整个车厂便是一个形象工厂,其上面从属的厂便是一个又一个具体工厂。如果把车场整体当做一个抽象类,那么具体的工厂就是这个抽象类的实现。
- 课程文章接口
public abstract class Article { public abstract void produce();}
- JAVA课程文章
public class JavaArticle extends Article{ @Override public void produce() { System.out.println("正在创立java文章"); }}
- Python课程文章
public class PythonArticle extends Article{ @Override public void produce() { System.out.println("正在筹备Python文章..."); }}
- 课程视频接口
public abstract class Video { public abstract void produce();}
- JAVA课程视频
public class JavaVideo extends Video{ @Override public void produce() { System.out.println("正在录制java视频...."); }}
- Python课程视频
public class PythonVideo extends Video{ @Override public void produce() { System.out.println("正在录制python视频..."); }}
上述是JAVA工厂和Python工厂每个工厂下的两种产品。
咱们能够定义形象工厂来指定工厂的实现
- 创立形象工厂
public interface AbstractCourseFactory { Video getCourse(); Article getArticle();}
- JAVA工厂
public class JavaCourseFactory implements CourseFactory{ @Override public Video getCourse() { //制作视频 return new JavaVideo(); } @Override public Article getArticle() { // 制作文章 return new JavaArticle(); }}
- Python工厂
public class PythonCourseFactory implements CourseFactory{ @Override public Video getCourse() { // 制作视频 return new PythonVideo(); } @Override public Article getArticle() { // 制作文章 return new PythonArticle(); }}
- UML类图
- 测试类
public class Test { public static void main(String[] args) { // 子类实例指向父类援用 CourseFactory abstractFactory = new JavaCourseFactory(); Article article = abstractFactory.getArticle(); Video course = abstractFactory.getCourse(); article.produce(); course.produce(); }}
6.比照学习
实现了形象工厂,咱们很天然想到之前学习过的工厂模式。那么这两者有什么区别呢?简略地来说,工厂模式是对一种产品进行工厂加工,对外提供获取这个产品的办法;形象工厂是对一个产品族下的一些列产品进行工厂加工。听起来还是很形象,看下例子吧:
- 工厂模式:鼠标工厂
形象工厂:电脑工厂(包含创立鼠标及键盘)
综上来说,形象工厂是对工厂模式的一种扩大,丰盛创立产品的品种。就如同一个餐厅,只卖午餐,那就是一个午餐的工厂模式;而这个餐厅早上买早餐,中午买午餐,早晨搞夜市,这是一个餐厅的形象工厂
7.源码
Mybatis中的形象工厂
MyBatis在创立SqlSession和Configuration对象时,应用的就是形象工厂,保障了调用者从一个工厂对象中取出的SqlSession和Configuration是配套的。比方MySQL工厂中取出的就是MySQL的SqlSession和Configuration,Oracle工厂中取出的就是Oracle的SqlSession和Configuration。
DefaultSqlSessionFactory实现了形象工厂SqlSessionFactory,能够间接返回配置信息及sqlsession
public class DefaultSqlSessionFactory implements SqlSessionFactory { private final Configuration configuration; public DefaultSqlSessionFactory(Configuration configuration) { this.configuration = configuration; } .... @Override public SqlSession openSession(ExecutorType execType, boolean autoCommit) { return openSessionFromDataSource(execType, null, autoCommit); } @Override public Configuration getConfiguration() { return configuration; } private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); final Executor executor = configuration.newExecutor(tx, execType); return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }}