字數總計:0 個 | 閱讀時長:0 分鐘 |閱讀次數:

元件 (Component) 是部屬 (deployment) 的單位,也是系統在部屬中最小的部分實體。

  • 在 Java 裡,它是 jar 檔
  • 在 Ruby 中,它是 gem 檔
  • 在 .Net 中,它是 DLL 檔

在 Compiled Language,它們是二進制檔的集合,在 Interpreted Language 中,它是原始檔的集合。

Component 經由 Link 合併到單一執行檔當中。也可以彙總到一個獨立的歸檔 (archive) 例如 .war 檔。或者他們可以部屬為動態載入 plugin,無論最終如何部屬,一個良好的設計始終保持著可獨立性。

元件簡史

早期軟體開發,程式設計師控制程式的記憶體位置和布局。程式的第一行當中會出現一個 origin 語句,是用來宣告程式要載入到哪個記憶體位置。

程式碼 到 執行

當computer要執行時高階語言,無法直接執行需要轉譯成機器語言。

  1. 高階語言會先compiler成組合語言。
  2. 接著被assembler組譯成機器語言。
  3. 再將object file由linker整理成執行檔(executable file)。
  4. 最後將執行檔裡的資料copy至適當的記憶體位址。(loader)

連結器(linker)

linker 是一種特殊程序,它將編譯器/彙編器產生的目標檔案和其他程式碼片段組合起來,產生副檔名為 .exe 的可執行檔。在目標檔案中,連結器會搜尋並附加執行檔所需的所有函式庫。它調節保存每個模組程式碼的記憶體空間。它還合併兩個或多個單獨的目標程式並在它們之間建立連結。

linker 執行多項任務,包括: 符號解析:連結器解析程式中在一個模組中定義並在另一個模組中引用的符號。 程式碼最佳化:連結器最佳化編譯器產生的程式碼,以減少程式碼大小並提高程式效能。 記憶體管理:連結器將記憶體位址分配給程式的程式碼和資料部分,並解決出現的任何衝突。 庫管理:連結器可以將外部庫連結到可執行檔中以提供附加功能。

載入器(loader)

  1. 讀取執行檔的header來決定程式碼與資料區的大小。
  2. 並以此來產生足夠容納資料與程式碼的記憶體空間。
  3. 將資料copy至記憶體。
  4. 接著複製主程式的parameter至stack(argument放到local variable)。
  5. 初始化暫存器並將stack指標設定在第一個可用空間。
  6. (這裡由os掌控)跳至start-up routine(啟動常式)呼叫要被執行的主程式,當主程式結束返回時,使用exit來結束執行並釋放硬體資源。

Conclusion

這些動態鏈結檔可以在 runtime 時,被插入在一起,這是我們的架構的軟體元件。它花了 50 年走到這裡,但我們已經處於一個新的位置,元件 plugin 架構現在很簡單就能當作是預設架構,而不是以往那種依靠艱鉅努力才能得到的架構。