程序間的耦合-20.02.27

  • 編寫jdbc的工程代碼用于分析程序的耦合

    添加依賴
    <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql - connec tor- java</artifactId>
      <version>5.1.7</version>
    </dependency>
    </ dependencies>
    
    
    //copy下來(lái)的代碼,與下面項(xiàng)目不是同一個(gè)
    public class JdbcDemo1 {
    public static void main(String[] args) throws Exception{
    //1.注冊(cè)驅(qū)動(dòng)
    DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    //2.獲取連接
    Connection conn = DriverManager.getConnection( "jdbc :mysql://localhost:3307/mydb","root","980106WSK");
    //3.獲取操作數(shù)據(jù)庫(kù)的預(yù)處理對(duì)象
    PreparedStatement pstm = conn.prepareStatement("select * from account");
    //4.執(zhí)行SQL,得到結(jié)果集
    ResultSet rs = pstm.executeQuery();
    //5.遍歷結(jié)果集
    while(rs.next()){
    System.out.print1n(rs.getString("name"));
    }
    //6.釋放資源
    rs.close() ;
    pstm.close();
    conn.close();
    
    
  • 編譯期依賴
    將依賴注釋掉程序報(bào)錯(cuò)

    Error: (14, 56) java :程序包c(diǎn)om.mysql. jdbc不存在

    Compilatien conpleted with 1 ertor and 0 waringe in 2s 648ms(編譯時(shí)遇到錯(cuò)誤)

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

    • 耦合 : 程序間的依賴關(guān)系
      • 類之間的依賴
      • 方法間的依賴
    • 解耦 : 降低程序間的依賴關(guān)系
    • 實(shí)際開(kāi)發(fā)中 ,應(yīng)該做到:
      • 編譯期不依賴
      • 運(yùn)行時(shí)才依賴
    • 解耦思路 :
      • 使用反射來(lái)創(chuàng)建對(duì)象,而避免使用new關(guān)鍵字
      • 通過(guò)讀取配置文件來(lái)獲取要?jiǎng)?chuàng)建的對(duì)象全限定類名
  • 曾經(jīng)代碼中的問(wèn)題分拆

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

    業(yè)務(wù)層調(diào)用持久層,表現(xiàn)層調(diào)用業(yè)務(wù)層,使用new關(guān)鍵字的依賴關(guān)系有很強(qiáng)的耦合性,使我們代碼的獨(dú)立性很差

  • 編寫工廠類和配置文件

    • BeanFactory類
    /**
    * 一個(gè)創(chuàng)建Bean對(duì)象的工廠
    *
    * Bean:在計(jì)算機(jī)英語(yǔ)中,有可重用組件的含義。
    * JavaBean:用java語(yǔ)言編寫的可重用組件。
    *         javabean >實(shí)體類
    *     它就是創(chuàng)建我們的service和dao對(duì)象的。
    *
    *     第一個(gè):需要一個(gè)配置文件來(lái)配置我們的service和dao
    *             配置的內(nèi)容:唯一標(biāo)識(shí)=全限定類名 (key=value)
    *     第二個(gè):通過(guò)讀取配置文件中配置的內(nèi)容,反射創(chuàng)建對(duì)象
    *     我的配置文件可以是xml也可以是properties
    */
    public class BeanFactory{
        
    }
    
    • bean.properties配置文件
    itemsDao=com.qfetu.dao.impl.ItemsDaoImpl
    itemsService=com.qfetu.service.impl.ItemsServiceImpl
    
  • 工廠模式解耦

    • BeanFactory類
    /**
     * 一個(gè)創(chuàng)建Bean對(duì)象的工廠
     *
     * Bean:在計(jì)算機(jī)英語(yǔ)中,有可重用組件的含義。
     * JavaBean:用java語(yǔ)言編寫的可重用組件。
     *        javabean >實(shí)體類
     *    它就是創(chuàng)建我們的service和dao對(duì)象的。
     *
     *    第一個(gè):需要一個(gè)配置文件來(lái)配置我們的service和dao
     *            配置的內(nèi)容:唯一標(biāo)識(shí)=全限定類名 (key=value)
     *    第二個(gè):通過(guò)讀取配置文件中配置的內(nèi)容,反射創(chuàng)建對(duì)象
     *    我的配置文件可以是xml也可以是properties
     */
    public class BeanFactory {
        //定義一個(gè)Properties對(duì)象
        private static Properties properties;
    
        //使用靜態(tài)代碼塊為properties對(duì)象賦值
        static {
            try {
                //實(shí)例化對(duì)象
                properties = new Properties();//有些耦合是無(wú)法避免的,我們不能做到完全消除
    
                //獲取properties文件的流對(duì)象
                //InputStream is = new FileInputStream(); 這里不要用FileInputStream,而是使用類加載器的形式
                InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
    
                properties.load(is);
            } catch (Exception e) {
               throw new ExceptionInInitializerError("初始化properties失敗");//這里拋出一個(gè)初始化異常,Error
            }
        }
    
        /**
         * 根據(jù)Bean的名稱獲取bean對(duì)象
         * @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");
    
  • 分析工廠模式中的問(wèn)題并改造

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

此時(shí)的對(duì)象是多例的,對(duì)象被創(chuàng)建多次,執(zhí)行效率沒(méi)有單例對(duì)象高

  • 單例

    只被創(chuàng)建一次,從而類中的成員也就只會(huì)初始化一次,有線程問(wèn)題,但是在Service和Dao層是沒(méi)有類成員的,所以不存在線程問(wèn)題

bean = Class.forName(beanPath).newInstance();//每次都會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù)創(chuàng)建對(duì)象
  • 分析

    通過(guò)對(duì)單例的分析,顯然并不需要多例,只需要每一次都是同一個(gè)對(duì)象就夠了,所以對(duì)這個(gè)方法進(jìn)行調(diào)整,調(diào)整的前提是對(duì)象只能newInstance()一次.如果你創(chuàng)建之后不存起來(lái),根據(jù)java的垃圾回收機(jī)制,它會(huì)在長(zhǎng)時(shí)間不用時(shí)被回收,當(dāng)下一次再使用時(shí),就沒(méi)有了,所以需要在對(duì)象創(chuàng)建出來(lái)后馬上存起來(lái)

  • 工廠模式解耦的升級(jí)版

    • 修改后的BeanFactory類
    /**
     * 一個(gè)創(chuàng)建Bean對(duì)象的工廠
     *
     * Bean:在計(jì)算機(jī)英語(yǔ)中,有可重用組件的含義。
     * JavaBean:用java語(yǔ)言編寫的可重用組件。
     *        javabean >實(shí)體類
     *    它就是創(chuàng)建我們的service和dao對(duì)象的。
     *
     *    第一個(gè):需要一個(gè)配置文件來(lái)配置我們的service和dao
     *            配置的內(nèi)容:唯一標(biāo)識(shí)=全限定類名 (key=value)
     *    第二個(gè):通過(guò)讀取配置文件中配置的內(nèi)容,反射創(chuàng)建對(duì)象
     *    我的配置文件可以是xml也可以是properties
     */
    public class BeanFactory {
        //定義一個(gè)Properties對(duì)象
        private static Properties properties;
    
        //定義一個(gè)Map,用于存放我們要?jiǎng)?chuàng)建的對(duì)象,我們把它稱之為容器
        private static Map<String,Object> beans;
    
        //使用靜態(tài)代碼塊為properties對(duì)象賦值
        static {
            try {
                //實(shí)例化對(duì)象
                properties = new Properties();//有些耦合是無(wú)法避免的,我們不能做到完全消除
    
                //獲取properties文件的流對(duì)象
                //InputStream is = new FileInputStream(); 這里不要用FileInputStream,而是使用類加載器的形式
                InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
                properties.load(is);
    
                //實(shí)例化容器
                beans = new HashMap<String,Object>();
                // 取出配置文件中所有的Key
                Enumeration keys = properties.keys();
                // 遍歷枚舉
                while (keys.hasMoreElements()){
                    // 取出每個(gè)Key
                    String key = keys.nextElement().toString();
                    // 根據(jù)key獲取value
                    String beanPath = properties.getProperty(key);
                    //反射創(chuàng)建對(duì)象
                    Object value = Class.forName(beanPath).newInstance();
                    //把key和value存入容器中
                    beans.put(key,value);
                }
            } catch (Exception e) {
               throw new ExceptionInInitializerError("初始化properties失敗");//這里拋出一個(gè)初始化異常,Error
            }
        }
    
        /**
         * 根據(jù)bean的名稱獲取對(duì)象
         * @param beanName
         * @return
         */
        public static Object getBean(String beanName){
            return beans.get(beanName);
        }
    
      /*  *//**
         * 根據(jù)Bean的名稱獲取bean對(duì)象
         * @param beanName
         * @return
         *//*
        public static Object getBean(String beanName){
            Object bean = null;
            try {
                String beanPath = properties.getProperty(beanName);
                bean = Class.forName(beanPath).newInstance();   //每次都會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù)創(chuàng)建對(duì)象
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bean;
        }*/
    }
    
打印結(jié)果

在使用Map將對(duì)象存進(jìn)去之后會(huì)發(fā)現(xiàn),后續(xù)使用后就不需要再反復(fù)創(chuàng)建

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容