关于java:设计模式抽象工厂模式

4次阅读

共计 3340 个字符,预计需要花费 9 分钟才能阅读完成。

形象工厂

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();}
  }
}
正文完
 0