zoukankan      html  css  js  c++  java
  • 设计模式-抽象工厂

    一、定义:

    抽象工厂提供了一个创建一系列相关或相互依赖的接口

    无效指定他们的类

    类型:创建型

    二:适用场景

    客户端(应用层)不依赖于产品类实例如何被创建、实现等细节

    强调一系列相关产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码

    提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现

    三、优点:

    具体产品在应用层代码隔离,无须关心创建细节

    将一系列的产品族统一到一起创建

    四、缺点

    规定了所有可能被创建的产品集合,产品族中扩建新的产品困难,需要修改抽象工厂的接口

    增加了系统的抽象性和理解难度

    五、产品等级结构与产品族

    工厂方法和抽象工厂最大的区别

    工厂方法针对的产品等级结构

    抽象工厂针对的是一个产品族

    图下图: 增加了一个具体工厂 

     

     六:Coding

     1. 创建CourseFactory方法,比如一个课程工厂,需要视频产品和文章产品,这两个产品构成一个产品族

    public interface CourseFactory {
        Video getVideo();
        Article getArticle();
    }
    

      

    2. 创建Article类

    public abstract class Article {
        public abstract void  produce();
    }
    

      

    3. 创建Video类

    public abstract class Video {
        public abstract void  produce();
    }
    

      

    4. 创建JavaVideo类

    public class JavaVideo extends Video {
        @Override
        public void produce() {
            System.out.println("录制Java视频");
        }
    }
    

      

    5. 创建JavaArticle 类

    public class JavaArticle extends Article{
        @Override
        public void produce() {
            System.out.println("编写Java课程文章");
        }
    }
    

      

    6. 创建工厂JavaCourseFactory 

    public class JavaCourseFactory implements  CourseFactory{
        @Override
        public Video getVideo() {
            return new JavaVideo();
        }
    
        @Override
        public Article getArticle() {
            return new JavaArticle();
        }
    }
    

      

    7. 同理创建AndroidVideo类

    public class AndroidVideo extends  Video {
        @Override
        public void produce() {
            System.out.println("录制Android视频");
    
        }
    }
    

      

    8 创建 AndroidArticle类

    public class AndroidArticle extends Article {
        @Override
        public void produce() {
            System.out.println("编写Android课程文章");
        }
    }
    

     

    9. 创建AndroidCourseFactory 类

    public class AndroidCourseFactory implements  CourseFactory{
        @Override
        public Video getVideo() {
            return new AndroidVideo();
        }
    
        @Override
        public Article getArticle() {
            return new AndroidArticle();
        }
    }
    

      

     

    10 创建测试类

    public class Test {
        public static void main(String[] args) {
            CourseFactory courseFactory = new JavaCourseFactory();
            Video video = courseFactory.getVideo();
            video.produce();
            Article article = courseFactory.getArticle();
            article.produce();
        }
    }
    

      

    11 uml图

    七、在JDK或者类库中的实例

    1. java.sql.Connection接口中有如下两个方法,分别返回Statement和PreparedStatement。相当于一个产品族,实现这个接口的方法,实现这两个方法。

    Statement createStatement(int resultSetType, int resultSetConcurrency)  throws SQLException;
    PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException;
    

      

    2. Mybatis中org.apache.ibatis.session下的SqlSessionFactory

    public interface SqlSessionFactory {
        SqlSession openSession();
    
        SqlSession openSession(boolean var1);
    
        SqlSession openSession(Connection var1);
    
        SqlSession openSession(TransactionIsolationLevel var1);
    
        SqlSession openSession(ExecutorType var1);
    
        SqlSession openSession(ExecutorType var1, boolean var2);
    
        SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2);
    
        SqlSession openSession(ExecutorType var1, Connection var2);
    
        Configuration getConfiguration();
    }
    

      这里不仅返回SqlSession,还要返回Configuration。

    看下SqlSessionFactory 的实现类:DefaultSqlSessionFactory的openSessionFromDataSource方法。

     private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
            Transaction tx = null;
    
            DefaultSqlSession var8;
            try {
                Environment environment = this.configuration.getEnvironment();
                TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
                tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
                Executor executor = this.configuration.newExecutor(tx, execType);
                var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
            } catch (Exception var12) {
                this.closeTransaction(tx);
                throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
            } finally {
                ErrorContext.instance().reset();
            }
    
            return var8;
        }
    

     返回DefaultSqlSession相当于一个产品,继承自SqlSession

     

  • 相关阅读:
    目录路径加反斜杠和不加的区别
    window端口号被占用解决
    个人博客设计记录
    2017/12/15
    添加code到github上
    跨域简介
    客户端存储
    window.name跨域
    BZOJ1305: [CQOI2009]dance跳舞
    BZOJ4872: [Shoi2017]分手是祝愿
  • 原文地址:https://www.cnblogs.com/linlf03/p/9746014.html
Copyright © 2011-2022 走看看