1. 程式人生 > >Spring 之 factory工廠模式的解耦

Spring 之 factory工廠模式的解耦

在實際開發中我們可以把三層的物件都使用配置檔案配置起來,當啟動伺服器應用載入的時候,讓一個類中的
方法通過讀取配置檔案,把這些物件創建出來並存起來。在接下來的使用的時候,直接拿過來用就好了。
那麼,這個讀取配置檔案,建立和獲取三層物件的類就是工廠。

上一小節解耦的思路有 2 個問題:
1、存哪去?
分析:由於我們是很多物件,肯定要找個集合來存。這時候有 Map 和 List 供選擇。
到底選 Map 還是 List 就看我們有沒有查詢需求。有查詢需求,選 Map。
所以我們的答案就是
在應用載入時,建立一個 Map,用於存放三層物件。
我們把這個 map 稱之為容器。
2、還是沒解釋什麼是工廠?
工廠就是負責給我們從容器中獲取指定物件的類。這時候我們獲取物件的方式發生了改變。
原來:
我們在獲取物件時,都是採用 new 的方式。是主動的。
現在:
我們獲取物件時,同時跟工廠要,有工廠為我們查詢或者建立物件。是被動的
這就是
控制反轉-Inversion Of Contr

![在這裡插入圖片描述
程式碼的演示:
曾經程式碼中的問題分析-----------------------------》
模擬一下:
建立新的module:-----》 介面
這些都是 之前做過的 實現類 多型new的現象 就是要避免 和 解耦的 可以用的 優化
業務層 在呼叫 持久層 也在 表現層 到 持久層 都會共有的 問題s
我們maven的座標啊 地方就是 jar 的方式 (沒有座標的)沒有瀏覽器與web

在模擬一個表現層 (實際裡這裡就是一個 servlet)

我們呈現 了好多的依賴 這就是我們要解決的
maven的pom 檔案還是 有個 mysql 就行


mysql
mysql-connector-java
5.1.6

----dao裡

package com.fhw.dao;

/* 賬戶持久層介面*/
public interface IAccountDao {
/* 模擬儲存賬戶的操作*/
void saveAccount();
}


package com.fhw.dao.impl;

import com.fhw.dao.IAccountDao;
/* 賬戶持久層實現類*/
public class IAccountDaoImpl implements IAccountDao {

public void saveAccount() {
  //  System.out.println("儲存了賬戶");
}

}


-seervice 裡

package com.fhw.service;
/*賬戶 :業務層的介面

  • /
    public interface IAcconutService {
    /
    *
    • 模擬儲存賬戶
      */
      void saveAccount();
      }
      ----package com.fhw.service.impl;

import com.fhw.dao.IAccountDao;
import com.fhw.factory.BeanFactory;
import com.fhw.service.IAcconutService;

public class IAccountServiceImpl implements IAcconutService{
/private IAccountDao accountDao=new IAccountDaoImpl();/

 IAccountDao accountDao= (IAccountDao) BeanFactory.getBean("accountDao");
public void saveAccount() {
    accountDao.saveAccount();
    System.out.println();
}

}

properties配置檔案

accountService =com.fhw.service.impl.IAccountServiceImpl
accountDao=com.fhw.dao.impl.IAccountDaoImpl

-----核心的 ``factory工廠類------------

``package com.fhw.factory;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/*

  • c建立一個 Bean物件

  • Bean 在計算機英語裡是 可重用元件

  • javaBean: 不同於java實體類 大於實體類 java編寫的可重用元件

  • javabean 來 建立 我們的 Service 與到的物件

  • 1: 需要 配置檔案 來 配置Service與 dao
    *配置內容 :唯一標示= 全限定類名 就是 key =value 的配置檔案

  • xml 或 propertise 都行

  • 2:通過配置檔案的內容來 反射建立物件

  • 現在 選用簡單 propertise 應用

  • */
    public class BeanFactory {
    //定義一個 properties 物件
    private static Properties props;
    //優化 改造 定義map容器 用於存放我們要建立的 物件
    private static Map<String ,Object> beans;
    // static 為物件 賦值
    static{
    try {
    // 例項化物件
    props = new Properties();
    //還是類載入器 :反射解耦 方便多了
    InputStream in=BeanFactory.class.getClassLoader().getResourceAsStream(“bean.properties”);
    props.load(in);
    //例項化容器
    beans=new HashMap<String,Object>();
    //取出配置檔案裡所有的 key
    Enumeration keys = props.keys();
    //遍歷列舉
    while (keys.hasMoreElements()){
    String key = keys.nextElement().toString();
    //根據key 來獲取value
    String beanpath = props.getProperty(key);
    //反射建立物件
    Object value=Class.forName(beanpath).newInstance();
    beans.put(key,value);
    }

       } catch (Exception e) {// 這裡若 讀取失敗
           //直接throw 指定異常 給資訊即可
           throw new ExceptionInInitializerError("初始化properties 失敗!");
       }
    

    }

    /**

    • 根據bean 的名稱獲取 物件 是單例模式
    • @param beanName
    • @return
      /
      public static Object getBean(String beanName){
      return beans.get(beanName);
      }
      /
      public static Object getBean(String beanName){//寫活 : Object 或 T泛型 get那個 引數指定
      Object bean=null;
      try {
      String beanPath = props.getProperty(beanName);
      //反射獲取 到
      bean = Class.forName(beanPath).newInstance();
      }catch (Exception e){
      e.printStackTrace();
      }
      return bean;
      }*/
      }
      /*當單例放到方法裡
      定義方法的時候 呼叫方法 就重新載入 也是初始化 所以也能保證每次初始化-----》 單例也可以----》但是BeanFactory的就是反射的建構函式NewInstance
      -----BeanFactory 建立物件是的反射 裡的newInstance()=》這句 話的出場–每次都會呼叫 預設 建構函式 建立物件
      所以每次都是 新的 -------》Spring也 不能識別 只能的java GC 機制 來回收
      現在就 只能用一次 newInstance()要保留
      =》存到那
      =》容器

於是我們就要一個Map 裡的key value ----------*/