控制反轉 IOC 理論推導

控制反轉 IOC 理論推導

按照我們傳統的開發,我們會先去 dao 層創建一個介面,在介面中定義方法。

public interface UserDao {
    void getUser();
}

然後再去實現類中實現這個方法的作用。

public class UserDaoImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("默認獲取用戶的數據");
    }
}

然後再去 service 層寫一個介面,在介面中定義方法。

public interface UserService {
    void getUser();
}

再然後寫實現類,實現裡面的方法。

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

然後我們使用這業務類

public class MyTest {

    public static void main(String[] args) {
        // 用戶實際調用的是業務層,dao 層他們不需要接觸
        UserService userService = new UserServiceImpl();
        userService.getUser();
    }

}

最後會輸出

默認獲取用戶的數據

但是現在在 dao 層新增加了一個實現,例如 UserDaomySql

public class UserDaoMysql implements UserDao {
    @Override
    public void getUser() {
        System.out.println("從 MySQL 中獲取數據");
    }
}

如果我們想要從 UserDaoMysql 這個類中調用 getUser() 這個方法,就需要在 UserServiceImpl 這個類中修改程式碼,將創建的 UserDaoImpl 改為 UserMysqlImpl 這個對象。然後才能得到我們想要的效果。

從 MySQL 中獲取數據

如果用戶就像產品經理一樣,今天要你想要在 UserDaoImpl 這個對象中獲取數據,明天就想要從 UserDaoMysql 這個對象中獲取數據呢?

我們面對這樣的問題,是不是還要每次去修改程式碼,如果我們在很多地方創建了這個對象,豈不是要到處修改,或者有更多的實現類,產品經理又突然叫我們用另一個對象,這樣我們就會被折磨死。是吧!

我們都知道猴子的臉說變就變,產品經理何嘗不是?

那麼我們可以不可以這樣做,我們就吧選擇權交給產品經理,我們不按照我們的意願去創建這個對象,我們將這個問題拋給產品經理,誒,我不建,我讓他去選,他喜歡用哪個,那就創建哪個。

我們來看看我們在 UserServiceImpl 中創建對象的那條語句

private UserDao userDao = new UserDaoImpl();

我想聰明的你,看到這條語句你就很快能明白,這個不就是定義一個對象變數,然後創建一個對象,將其賦值給它。

那麼我們可不可以想個辦法,讓他動態的將這個對象注入到這個變數裡面呢?

聰明的你仔細想想,想想我們創建實體類的時候。

嘿嘿!!!

是不是想到了什麼。

我們創建實體類的時候,是不是一開始我們沒有為那個變數賦值,是後面才用 Set 賦值的吧。

所以是不是想到該怎麼做了,嘿嘿嘿

沒錯,我們就是寫個 Setter

private UserDao userDao;

/**
  * 利用 Set 進行動態實現值的注入
  * @param userDao dao 層的對象
  */
public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}

我寫的和你想的一樣嗎?我想是的吧。

然後我們使用它

public class MyTest {

    public static void main(String[] args) {
        // 用戶實際調用的是業務層,dao 層他們不需要接觸
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoMysql());
        userService.getUser();
    }

}

這樣我們是不是就可以隨便產品經理怎麼想了,他愛用啥用啥,讓他自己選一個創建就好了。

這樣我們是不是就實現了反轉,誒,我不創建對象,讓你來選,你喜歡哪一個,就用哪一個。