l

2011年1月10日 星期一

無笑軟工:跨平台軟體開發的幾種技巧

Jan. 10 22:11~22:47

幾個月前因故要整理跨平台軟體開發方法,這裡所謂的跨平台其實也只是讓軟體能夠在 Windows 與 Linux-based 作業系統上面執行,今天 Teddy 就把腦袋中所知道的作法整理一下。

不同種類的作業系統(例如 Windows 與 Linux)存在本質上的差異性。例如,Windows 與Linux 使用完全不同的圖型應用程式介面(GUI API),要開發同時可執行於這兩個平台的桌面應用程式,便要處理此差異性。甚至相同的作業系統,也會因為版本、位元(32 或 64 位元)、或是安裝更新套件(service pack)而提供不同的功能。例如,GetSystemFirmwareTable 這個 Windows API(讀取 System Management BIOS 相關資訊)只在 Windows Server 2003 SP1 之後的版本以及 Windows XP 64 位元才提供,同樣屬於 Windows XP 作業系統的 32 位元版本就不提供此 API。類似的形況在 Linux 作業系統上也十分常見。由於 Linux 屬於開放原始碼軟體,不同的廠商可自行發佈其專屬的 Linux 版本,例如紅帽公司的 Red Hat Enterprise Linux 以及 Novell 公司的 SUSE Linux Enterprise Server。這些由不同廠商所發布的 Linux 套件,彼此間也存在許多差異性。例如,許多系統設定檔存放的位置並不一致、預設的安裝軟體、函式庫也不盡相同。

除了作業系統的差異性,跨平台軟體可能還需要與不同的外部系統相互合作。例如,假設一個跨平台進銷存系統,需要同時支援商業資料庫系統,例如 Oracle、DB2、SQL Server,以及免費的自由軟體資料庫,例如 MySQL 或 Postgress。最後,軟體的執行環境也是一個需要考量的問題。例如,使用 Java 所開發的應用程式,便須考慮 Java 虛擬機器版本;使用微軟 C++ 通常會使用到 MFC 函式庫,或是需要符合 POSIX 執行環境;若是網頁應用程式,則需考量瀏覽器軟體與版本(IE6、IE7、IE8、Firefox 3.0 等)。

以下介紹幾種常見用以解決平台差異性的設計方法(可同時選用多種方法):

  • 取平台功能的交集:針對所要支援平台的功能,取其交集。此優點為可避免平台之間功能的差異性,但卻限制了應用程式可以使用的平台功能。例如,假設平台A圖形使用者介面具有進階的 3D 半透明效果,但平台B並不支援。則採用平台功能交集設計法的應用程式便無法使用平台A上面的 3D 半透明效果。如此會導致該程式在平台A上只能用基本的圖形介面。
  • 取平台功能的聯集:針對所要支援平台的功能,取其聯集。此優點為可避免平台之間功能的差異性,並且不會限制了應用程式可以使用的平台功能。但針對特定平台所不提供的功能,則需要以自行開發軟體加以模擬。以前述例子為例,則採用平台功能聯集設計法的專案必須要在平台B上自行模擬 3D 半透明效果。
  • 使用 Platform Factory:套用設計樣式所介紹的 Abstract Factory 樣式,針對特定平台提供特定實作,但對於客戶端程式而言並不需要知道這些屬於特定平台的程式碼,可達到程式的可維護性和擴充性。
  • 使用編譯器巨集:在 C C++ 專案中,普遍使用編譯器巨集來達到產生不同平台程式碼的目的。Linux 作業系統本身即是一個最好的範例。
  • 使用跨平台語言:使用 Java Python 這類的跨平台程式語言來開發專案。這類的語言通常提供虛擬機器或執行環境來執與平台無關的二進制程式碼(例如Java Bytecode)。跨平台語言通常也伴隨著跨平台函式庫,例如 Java Swing 圖行使用者介面或是Java內建的其他類別庫。跨平台語言所承諾「寫一次,處處可執行」(write once, run anywhere)的優點,理論上可大幅簡化開發跨平台專案的工作。然而實務上,我們經常可發現跨平台語言在不同的平台還是會有不同的行為,因此曾經有人將write once, run anywhere 戲稱為 write once, debug everywhere。由此更可見跨平台專案在其支援的平台中,必須被完整地整合與測試之重要性。
  • 使用跨平台函式庫:像 C C++ 這種核心很小的語言,並沒有規範標準的 GUI API。因此,若要使用 C C++ 開發跨平台的 GUI 應用程式,則通常會搭配使用類似 Qt 這種跨平台 GUI 函式庫。即使是 Java 這種跨平台語言,也會因為效率的因素,也有由 IBM 公司所提供的 SWTStandard Wegit Toolkit)跨平台 GUI 函式庫可使用。其他常見的跨平台函式庫包含 TCP/IP 函式庫、資料庫存取函式庫、XML 檔案操作函式庫等。
  • 使用程式產生技術:開發跨平台軟體除了可使用通用程式語言(例如C/C++/Java)之外,另一種方式則是透過定義領域專屬語言(domain specific languages),然後藉由程式產生技術(code generation)來產生可執行於不同平台的程式碼。近年來很流行的 MDAmodel driven architecture)即可視為支援跨平台軟體開發的一種方法。採用此技術需定義領域專屬語言,且需要為不同平台撰寫專屬的程式產生器,通常在較特殊的應用領域中才會採用。例如,國內便有軟體廠商使用自行定義的 XML 檔案來撰寫網頁應用程式內容,然後視客戶需要,使用程式產生器技術產生微軟 ASP.NET應用程式或是 Java JSP/Servlet 應用程式,達到跨平台的目的。
  • 使用模擬器Windows 作業系統專屬的應用程式之所以無法執行在 Linux 上,主要是因為 Linux 上沒有提供 Windows API。因此,如果可以在 Linux 上提供Windows API,則專屬於 Windows 的應用程式完全不需修改便可直接在 Linux 上執行(反之亦然)。開放原始碼軟體Winehttp://www.winehq.org/)與Cygwinhttp://www.cygwin.com/)便是在 Linux 上實作 Windows API 與在Windows 上提供 Linux API 的兩個例子。
  • 使用虛擬機器:採用模擬器雖然可以在不需要原始平台的作業系統中執行應用程式,但是開發一個完整且高效率的模擬器並不容易,而且需要隨著所模擬的作業系統更新而異動。若採用虛擬機器(例如 VMWareXenVirtualBoxVirtual PC)則省去了撰寫模擬器的工作,而且由於虛擬機器可視為介於硬體與作業系統之間的平台,因此可以支援不同作業系統的安裝。例如,我們可以在 Windows XP 上使用 VMWare 安裝Red Hat Enterprise Linux 或是 Windows Server 2008,也可以在 Linux 平台上安裝Winodws XP FreeBSD 等。使用虛擬機器可以讓不具備跨平台功能的軟體在不須修改的前提下執行於異質平台上。然而,透過虛擬機器(或是模擬器)執行應用程式其效率較差,且若應用程式需要存取特殊硬體支援,則可能便無法採用此方法。
  • 使用硬體抽象層:微軟的 Windows NT 作業系統在開發之初便考慮到需要執行於不同硬體平台的問題,例如 Intel X86 Alpha。為了使作業系統可順利的在不同的硬體執行,微軟在硬體與作業系統之間定義了硬體抽象層(HALhardware abstraction layer)。作業系統透過不同硬體平台的硬體抽象層,便可在極小幅度的修改之下,執行於不同的硬體平台。

以上報告完畢,若有疏漏尚請告知。

***

友藏內心獨白:怎麼才 2011 年初就開始『作帳』啦。

2 則留言:

  1. 對啊,Qt 也是滿多人用的。因為 Teddy 這幾年都在用 Java 開發 Web AP,也就沒機會用。只有當年在學校看學弟用過... XD

    回覆刪除