1. 程式人生 > 程式設計 >淺析springboot通過面向介面程式設計對控制反轉IOC的理解

淺析springboot通過面向介面程式設計對控制反轉IOC的理解

IoC是什麼

  Ioc—Inversion of Control,即“控制反轉”,不是什麼技術,而是一種設計思想。在Java開發中,Ioc意味著將你設計好的物件交給容器控制,而不是傳統的在你的物件內部直接控制。如何理解好Ioc呢?理解好Ioc的關鍵是要明確“誰控制誰,控制什麼,為何是反轉(有反轉就應該有正轉了),哪些方面反轉了”,那我們來深入分析一下:

  ●誰控制誰,控制什麼:傳統Java SE程式設計,我們直接在物件內部通過new進行建立物件,是程式主動去建立依賴物件;而IoC是有專門一個容器來建立這些物件,即由Ioc容器來控制對 象的建立;誰控制誰?當然是IoC 容器控制了物件;控制什麼?那就是主要控制了外部資源獲取(不只是物件包括比如檔案等)。

  ●為何是反轉,哪些方面反轉了:有反轉就有正轉,傳統應用程式是由我們自己在物件中主動控制去直接獲取依賴物件,也就是正轉;而反轉則是由容器來幫忙建立及注入依賴物件;為何是反轉?因為由容器幫我們查詢及注入依賴物件,物件只是被動的接受依賴物件,所以是反轉;哪些方面反轉了?依賴物件的獲取被反轉了。

IoC能做什麼

  IoC 不是一種技術,只是一種思想,一個重要的面向物件程式設計的法則,它能指導我們如何設計出鬆耦合、更優良的程式。傳統應用程式都是由我們在類內部主動建立依賴物件,從而導致類與類之間高耦合,難於測試;有了IoC容器後,把建立和查詢依賴物件的控制權交給了容器,由容器進行注入組合物件,所以物件與物件之間是 鬆散耦合,這樣也方便測試,利於功能複用,更重要的是使得程式的整個體系結構變得非常靈活。

  其實IoC對程式設計帶來的最大改變不是從程式碼上,而是從思想上,發生了“主從換位”的變化。應用程式原本是老大,要獲取什麼資源都是主動出擊,但是在IoC/DI思想中,應用程式就變成被動的了,被動的等待IoC容器來建立並注入它所需要的資源了。

  IoC很好的體現了面向物件設計法則之一—— 好萊塢法則:“別找我們,我們找你”;即由IoC容器幫物件找相應的依賴物件並注入,而不是由物件主動去找。

好了,正文開始!

IOC,把控制反轉到業務端,這句話沒什麼問題,在springboot框架裡,物件的管理是通過spring ioc來實現的,而開發人員的開發原則裡總是說“面向介面程式設計”,而為什麼要面向介面卻沒幾個人能說出來,今天在寫一個基於redis的手動分佈鎖時,對這個面向介面和控制反轉又有了一個體會。

底層程式碼更需要面向介面

當你為開發人員提供一個封閉的包時,他們是直接用的,他們不會修改你的程式碼,當然他們可以去繼承並擴充套件;當然如果你不希望被繼承可以宣告為final,這都是面向物件程式設計裡提供好的功能,我們主要看控制反轉這句話,它把控制權交給了上層去實現,底層通過 面向介面 的原則只設計一個規範,而又使用者去實現;但框架功能裡的細節是要有的,這類似於“模版方法”模式,底層框架實現了流程,而個性化的部分由上層去實現。

看jpa裡的審計介面

public interface AuditorAware<T> {

	/**
	 * Returns the current auditor of the application.
	 *
	 * @return the current auditor
	 */
	Optional<T> getCurrentAuditor();
}

上面這個泛型介面只有一個方法,需要讓上層開發人員根據自己的業務去實現它,比較返回一個當前登陸的使用者實體,或者返回使用者名稱稱,然後底層框架裡直接使用這個AuditorAware介面的物件;當然如果你的底層只接收一個String型別的值,你也可以去派生一個個性化介面,讓上層開發人員去實現你的介面即可。

/**
 * 返回使用者ID的標識介面,由程式使用者去實現.
 */
public interface UserIdAuditorAware extends AuditorAware<String> {

}

上面程式碼更加準確的規定了AuditorAware是一個字串的介面,只返回使用者ID即可。

@Component
public class CurrentUserAware implements UserIdAuditorAware {
 @Autowired
 ApplicationContext applicationContext;

 @Override
 public Optional<String> getCurrentAuditor() {
  ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  HttpServletRequest request = requestAttributes.getRequest();
  return Optional.of(request.getSession().getAttribute("id").toString());
 }
}

我們的底層程式碼會使用它的getCurrentAuditor()返回值 ,它是一個字串。

public Object execute(String sourceId,Integer timeout,TimeUnit unit) {
  Assert.notNull(sourceId,"sourceId不能為空");
  String key = getKey(sourceId);
  String user = auditorAware.getCurrentAuditor().orElse(null);
  Assert.notNull(user,"AuditorAware例項返回的值為空");
  // 程式碼略
}

對於一個小小的功能,我們在經過思考之後,對於之前學過的東西進行總結,你可能會想法某種設計模式、某個演算法、某個原則、在使用它們之後,讓你的程式碼擴充套件性更好,這種程式碼也彷彿有了生命!

總結

到此這篇關於淺析springboot通過面向介面程式設計對控制反轉IOC的理解的文章就介紹到這了,更多相關springboot面向介面程式設計控制反轉IOC內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!