程序间的耦合-20.02.27

  • 编写jdbc的工程代码用于分析程序的耦合

    添加依赖
    <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql - connec tor- java</artifactId>
      <version>5.1.7</version>
    </dependency>
    </ dependencies>
    
    
    //copy下来的代码,与下面项目不是同一个
    public class JdbcDemo1 {
    public static void main(String[] args) throws Exception{
    //1.注册驱动
    DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    //2.获取连接
    Connection conn = DriverManager.getConnection( "jdbc :mysql://localhost:3307/mydb","root","980106WSK");
    //3.获取操作数据库的预处理对象
    PreparedStatement pstm = conn.prepareStatement("select * from account");
    //4.执行SQL,得到结果集
    ResultSet rs = pstm.executeQuery();
    //5.遍历结果集
    while(rs.next()){
    System.out.print1n(rs.getString("name"));
    }
    //6.释放资源
    rs.close() ;
    pstm.close();
    conn.close();
    
    
  • 编译期依赖
    将依赖注释掉程序报错

    Error: (14, 56) java :程序包com.mysql. jdbc不存在

    Compilatien conpleted with 1 ertor and 0 waringe in 2s 648ms(编译时遇到错误)

  • 程序的耦合和解耦的思路分析

    • 耦合 : 程序间的依赖关系
      • 类之间的依赖
      • 方法间的依赖
    • 解耦 : 降低程序间的依赖关系
    • 实际开发中 ,应该做到:
      • 编译期不依赖
      • 运行时才依赖
    • 解耦思路 :
      • 使用反射来创建对象,而避免使用new关键字
      • 通过读取配置文件来获取要创建的对象全限定类名
  • 曾经代码中的问题分拆

    private IitemsDao iitemsDao = new ItemsDaoImpl();
    
    IitemsService iitemsService = new ItemsServiceImpl();
    

    业务层调用持久层,表现层调用业务层,使用new关键字的依赖关系有很强的耦合性,使我们代码的独立性很差

  • 编写工厂类和配置文件

    • BeanFactory类
    /**
    * 一个创建Bean对象的工厂
    *
    * Bean:在计算机英语中,有可重用组件的含义。
    * JavaBean:用java语言编写的可重用组件。
    *         javabean >实体类
    *     它就是创建我们的service和dao对象的。
    *
    *     第一个:需要一个配置文件来配置我们的service和dao
    *             配置的内容:唯一标识=全限定类名 (key=value)
    *     第二个:通过读取配置文件中配置的内容,反射创建对象
    *     我的配置文件可以是xml也可以是properties
    */
    public class BeanFactory{
        
    }
    
    • bean.properties配置文件
    itemsDao=com.qfetu.dao.impl.ItemsDaoImpl
    itemsService=com.qfetu.service.impl.ItemsServiceImpl
    
  • 工厂模式解耦

    • BeanFactory类
    /**
     * 一个创建Bean对象的工厂
     *
     * Bean:在计算机英语中,有可重用组件的含义。
     * JavaBean:用java语言编写的可重用组件。
     *        javabean >实体类
     *    它就是创建我们的service和dao对象的。
     *
     *    第一个:需要一个配置文件来配置我们的service和dao
     *            配置的内容:唯一标识=全限定类名 (key=value)
     *    第二个:通过读取配置文件中配置的内容,反射创建对象
     *    我的配置文件可以是xml也可以是properties
     */
    public class BeanFactory {
        //定义一个Properties对象
        private static Properties properties;
    
        //使用静态代码块为properties对象赋值
        static {
            try {
                //实例化对象
                properties = new Properties();//有些耦合是无法避免的,我们不能做到完全消除
    
                //获取properties文件的流对象
                //InputStream is = new FileInputStream(); 这里不要用FileInputStream,而是使用类加载器的形式
                InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
    
                properties.load(is);
            } catch (Exception e) {
               throw new ExceptionInInitializerError("初始化properties失败");//这里抛出一个初始化异常,Error
            }
        }
    
        /**
         * 根据Bean的名称获取bean对象
         * @param beanName
         * @return
         */
        public static Object getBean(String beanName){
            Object bean = null;
            try {
                String beanPath = properties.getProperty(beanName);
                bean = Class.forName(beanPath).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bean;
        }
    }
    
    //IitemsService iitemsService = new ItemsServiceImpl();
            IitemsService iitemsService = (IitemsService)BeanFactory.getBean("itemsService");
    
     //private IitemsDao iitemsDao = new ItemsDaoImpl();
        private IitemsDao iitemsDao = (IitemsDao)BeanFactory.getBean("itemsDao");
    
  • 分析工厂模式中的问题并改造

    • 多例
       for (int i = 0; i < 5; i++) {
                IitemsService iitemsService = (IitemsService)BeanFactory.getBean("itemsService");
                System.out.println(iitemsService);
            }
    
打印结果

此时的对象是多例的,对象被创建多次,执行效率没有单例对象高

  • 单例

    只被创建一次,从而类中的成员也就只会初始化一次,有线程问题,但是在Service和Dao层是没有类成员的,所以不存在线程问题

bean = Class.forName(beanPath).newInstance();//每次都会调用默认构造函数创建对象
  • 分析

    通过对单例的分析,显然并不需要多例,只需要每一次都是同一个对象就够了,所以对这个方法进行调整,调整的前提是对象只能newInstance()一次.如果你创建之后不存起来,根据java的垃圾回收机制,它会在长时间不用时被回收,当下一次再使用时,就没有了,所以需要在对象创建出来后马上存起来

  • 工厂模式解耦的升级版

    • 修改后的BeanFactory类
    /**
     * 一个创建Bean对象的工厂
     *
     * Bean:在计算机英语中,有可重用组件的含义。
     * JavaBean:用java语言编写的可重用组件。
     *        javabean >实体类
     *    它就是创建我们的service和dao对象的。
     *
     *    第一个:需要一个配置文件来配置我们的service和dao
     *            配置的内容:唯一标识=全限定类名 (key=value)
     *    第二个:通过读取配置文件中配置的内容,反射创建对象
     *    我的配置文件可以是xml也可以是properties
     */
    public class BeanFactory {
        //定义一个Properties对象
        private static Properties properties;
    
        //定义一个Map,用于存放我们要创建的对象,我们把它称之为容器
        private static Map<String,Object> beans;
    
        //使用静态代码块为properties对象赋值
        static {
            try {
                //实例化对象
                properties = new Properties();//有些耦合是无法避免的,我们不能做到完全消除
    
                //获取properties文件的流对象
                //InputStream is = new FileInputStream(); 这里不要用FileInputStream,而是使用类加载器的形式
                InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
                properties.load(is);
    
                //实例化容器
                beans = new HashMap<String,Object>();
                // 取出配置文件中所有的Key
                Enumeration keys = properties.keys();
                // 遍历枚举
                while (keys.hasMoreElements()){
                    // 取出每个Key
                    String key = keys.nextElement().toString();
                    // 根据key获取value
                    String beanPath = properties.getProperty(key);
                    //反射创建对象
                    Object value = Class.forName(beanPath).newInstance();
                    //把key和value存入容器中
                    beans.put(key,value);
                }
            } catch (Exception e) {
               throw new ExceptionInInitializerError("初始化properties失败");//这里抛出一个初始化异常,Error
            }
        }
    
        /**
         * 根据bean的名称获取对象
         * @param beanName
         * @return
         */
        public static Object getBean(String beanName){
            return beans.get(beanName);
        }
    
      /*  *//**
         * 根据Bean的名称获取bean对象
         * @param beanName
         * @return
         *//*
        public static Object getBean(String beanName){
            Object bean = null;
            try {
                String beanPath = properties.getProperty(beanName);
                bean = Class.forName(beanPath).newInstance();   //每次都会调用默认构造函数创建对象
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bean;
        }*/
    }
    
打印结果

在使用Map将对象存进去之后会发现,后续使用后就不需要再反复创建

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容