作者簡介
高煥堂,Android專家顧問。台灣Android論壇主席,現任亞太地區Android技術大會主席,台灣Android領域框架開發聯盟總架構師。發表100多篇Android核心技術文章,出版了6本Android專業技術書籍。
學歷:
美國 U. ofColorado 資管研究所(1991)
淡江大學管理科學研究所(1983)
曾任:
銘傳大學專職講師
台灣《面向對象 Object-Oriented 雜誌》主編
英國 Access Capital公司嵌入式軟體架構師
內容簡介
android從程式設計師到架構師之路,在躍入架構設計新天地時,你很快會發現,架構設計的主要流派有二:
•抽象思維派:致力於抽象出穩定、可靠、不變的共同性架構;亦即,追求<萬變不離其宗>的宗。
•組合創新派:致力於組合出具體獨特性的創新架構;亦即,追求<與眾不同>的特質。
在本課程里,將以後者(組合創新)為主軸,希望能陪伴你在移動網際網路、智慧型終端的創新潮流中,能如魚得水、展現無比的創造力。此外,也會幫你建立紮實的抽象思維能力。
為了讓你能順利從(代碼)開發躍升到(架構)設計,本課程會堅持一個美好的信念: ”各項架構設計決策都必須能迅速落實為代碼”。
一方面符合敏捷的原則;另一方面,你可以從熟悉的代碼中,領悟到其幕後的設計思想和技術。例如,本課程也以Android開源的代碼來闡述其幕後的 UI、IPC、HAL等架構的設計思維和技巧。為了特彆強調架構與代碼兩者之間的無隙縫銜接,高煥堂老師特別設計了EIT代碼造形,讓組合創新派的設計核心:接口(即EIT的<I>)能直接落實到代碼。因之,EIT造形成為架構與代碼的核心交匯點。
此外,在本課程里,將由高老師指導大家親自進行架構設計,直接取得實務經驗;例如,以移動網際網路+智慧型家庭的情境,設計出手機與TV整合、多螢互動的新型系統架構,並迅速落實為可執行的框架代碼。並藉由成功案例分享來提供大量的實務設計模式,融合到框架的開發與API設計上,讓學員在最短的時間內獲得紮實的設計經驗和技巧;往上套用於各行各業上。
作品目錄
Part-1: 從架構到代碼的過程
1.1 敏捷與架構的完美組合
•敏捷開發的原則和價值觀
•開發、架構、測試之關係
•架構在敏捷過程里的角色
•架構師在敏捷過程的職責
•過程觀點:(需求)測試做<反饋>,敏捷(過程)做<疊代>;
•分合觀點:(架構)設計做<分>,(代碼)開發做<合>
•測試觸發反饋,反饋帶動疊代,疊代驅動<架構à代碼>重構
•疊代促進了<架構師&開發者>的心靈溝通與攜手協作
•舉例:架構師如何設計敏捷的起始架構(Simple Solution)
加法設計:圍繞問題( Problem)和願景(Vision),產生創意構想(Creative Idea)
減法設計:創意愛上限制(Creativity loves constraint)
1.2 代碼是架構的外貌,永遠青春
•架構師與開發者的合作成果:架構+代碼=軟體(系統)
•架構是軟體的骨架、代碼是軟體的外貌
•架構是軟體的核心
•架構的用意:創新組<合>
•架構設計的焦點:接口(Interface)
•設計決策具有<未來性>,系統才能適應未來
1.3 設計與開發的分工合作
•架構設計的目的是:組合
•架構師做<分>,支持開發者做<合>,合作實踐(系統)組合
•分得妙,就能合得快(即:分之以為用,合之以為利)
•分得妙,就能得好接口(Interface)
•架構師的核心工作:接口設計(Interface Design)
•開發者的核心工作:依據接口,開發(系統)模組並整合
•有許多種開發者:如App開發者、底層系統開發者等
1.4 敏捷思維:儘快呈現架構的外貌
•接口設計是<物>的組合設計
•接口設計是<事>的分工設計
•架構師設計多種接口來支撐分工與組合
•架構師心中的4種接口:SI、PI、API和UI
SI:本架構與外部系統之間的整合接口
PI:本架構與內部挿件(Plug-in)之間的接口
API:本架構與應用程式(App)之間的接口
UI:App與用戶的互動接口
l 依循敏捷原則,接口迅速落實為代碼,儘快呈現外貌
1.5 EIT造形:接口美麗的外貌
•認識EIT軟體造形
•EIT造形:呈現核心設計的外貌
•EIT造形的可涵蓋三種:SI、PI、API
•EIT造形的代表本架構
•EIT造形的代表本架構的配件(即外掛程式:Plug-in)
1.6 一群<E&I>美妙的組合是:框架(Framework)
•認識GoF的設計模式(Design Pattern)
•隨著敏捷的疊代過程,EIT造形會逐漸增加
•如何巧妙組合漸增的EIT造形:擅用設計模式
•組合起來,就成為軟體框架了
•如何迭成多層級(Layer)的框架體系:以Android為例
Part-2: 從Android框架代碼中學習設計
2.1 基礎設計模式(Pattern)的代碼:以Android為例
•Template Method模式:IoC(控制反轉)機制
•Observer模式:接口設計
•Abstract Factory模式:兩個EIT造形的組合
•Adapter模式:封裝接口
•Composite模式:實踐組合
•Façade模式:組合體的接口設計
•EIT造形是原子,設計模式是分子
•更多EIT造形的組合模式:以Android代碼為例
2.2 從 UI框架入手
•View體系的架構設計(使用Template Method模式)
•Activity-View的架構設計(使用Factory模式)
•Layout-View的架構設計(使用Composite模式)
•WMS(WindowManagerService)-View的架構設計
•WMS-SurfaceFlinger的架構設計
•Surface-Canvas(畫布)的架構設計
•SurfaceView與OpenGL的3D繪圖架構設計
•ListView框架的設計
2.3 跨進程(IPC)架構設計
•Android 的IPC幕後設計:BD(Binder Driver)驅動架構
•以IBinder接口包裝BD驅動的服務
•包裝IBinder接口的Proxy-Stub設計模式
•Proxy和Stub類別的代碼
•設計Proxy和Stub類別的API
•如何自動生成Proxy和Stub類別代碼
•IBinder & AIDL方法
方法(一):Implementing a Binder
方法(二):Using a Messenger
方法(三):Bound Services
2.4 Java與C/C++兩層框架的設計
•JNI(Java Native Interface)代碼開發要點
•JNI的數據型態(Data Type)轉換規則
•JNI的執行緒(Thread)模式:JNIENV類的設計
•正向通信:Java函式調用本地C函式
•反向通信:本地C函式調用Java函式
•Android HAL架構設計
HAL(Hardware Abstraction Layer)的意義
理解runtime與HAL Stub
撰寫HAL Stub代碼
Stub調用Linux Kernel的方法
2.5 核心服務的框架設計
•認識核心服務(Core Service)
核心服務都是在開機過程中,由Android的INIT進程啟動的
包括Android Service和 Native Service兩種
以Java語言撰寫的,就稱為Android Service
以C++撰寫的,就稱為Native Service
•親自撰寫一個核心服務
撰寫一個C++類別
繼承BBinder基類,繼承得來IBinder界面
提供接口給Java層(透過JNI)調用
2.6 JUnit測試框架的設計
•Android的測試工具,都是基於JUnit測試框架的
•JUnit框架也是由許多EIT造形所組成;其TestCase基類是
•從基類衍生出各子類,如ServiceTestCase就是擴充的;其內涵的setUP()和tearDown()函式就是
•可撰寫(即Test case)代碼,來啟動TDD機制
•可使用TestSuite基類來管理一群相關的(即Test case)
Part-3: 梳理你的架構設計思想、方法和模式
3.1 複習設計概念與技藝
概念複習
•說明框架的起源、分層與其「無用之用」效果
•闡述套用框架魅力的泉源:控制反轉(IoC, Inversion of Control)機制
•深入認識控制反轉機制
•主控者是框架,而不是應用程式
•現代套用框架:採取廣義IoC觀念
•框架的重要功能:提供默認行為(Default Behavior)
技藝複習
•抽象(無之)與衍生(有之)
•打造框架:細膩的抽象步驟
•基本步驟:
細膩的手藝(一):數據抽象
細膩的手藝(二):函式抽象
細膩的手藝(三):將抽象類別轉為接口
•善用類的繼承(Inheritance)機制
•設計基類的抽象函式
•抽象是手段,組合是目的
UML複習
•UML的3種基本圖表:類圖、順序圖和用例圖
•以UML表達設計模式和框架
•EIT造形的兩種表達:UML圖和代碼
3.2 架構設計的需求分析方法
•基本設計技能:把輪胎拔掉
•偉大的雕刻師羅丹( Musée Rodin)說:”把不必要的部分去掉”
•買主需求:想想為什麼(why)汽車架構師會決定把輪胎拔掉呢? 其背後的理由是:買主來了,才知道買主對輪胎的偏好或特殊需求。只有等到買主決定和挑選了輪胎之後,才能將輪胎裝配上去。
•探索買主需求
為什麼把輪胎拔掉呢?
為什麼火鍋店的桌子要挖洞呢?
為什麼餐廳要分開<食譜>與<點選單>呢?
3.3 接口設計模式
•什麼是接口(Interface)
•在OOP里,將接口定義為一種特殊的類別(Class)
•在Java里,將”純粹抽象類別”稱為接口(Interface)
•EIT造形的接口表示為
•可以合併到里
誰控制<I>?
•成為控制點
•引擎àà驅動輪胎
如何控制API ?
•UI與API
•被動型API與主動型API
API與商業模式
•API決定控制權&金流
•沒錢就改版,改版就有錢
•以HAL為例,說明API = 話語權
•誰擁用接口的制定權,誰就掌握控制點,就能獲得較大的話語權
•從API看控制力量的強弱等級
•把控制力傳播出去
Part-4: 親自<敏捷+架構>、并迭代出代碼
4.1 情境範例:”手機訪問TV/STB”
•願景:多屏互動、幸福家庭的實踐
•亮點:許多智慧型設備大量進入家庭,在家裡的Android TV建立一朵私密雲,來整合窗外多個雲平台和手機移動終端,變得流行起來。
•情境:手機遠距訪問TV,透過TV打開家中的壁燈開關
•架構:基於<手機+TV>的大小機相聯、大小螢幕互動的新架構
•設計:設計TV里的框架、撰寫外掛程式
•技術:
在外的家庭成員透過手機瀏覽器(Browser)上網訪問家庭雲,您可以在家庭雲里,安裝一個i-Jetty網頁容器(Web Container)
此時,I-Jetty里的HttpServlet就是另一個,而它的doGet()等函式就是
您寫的servlet代碼就是I-Jetty的,它接受手機的訪問
4.2 實際開發:依循敏捷、落實為代碼
<架構設計>階段的敏捷疊代
•Step-0. 準備測試計畫
訂定此階段的測試方案(Test Case)
以Android手機Browser為測試方案的執行軟體
•Step-1. 設計敏捷過程的起點架構:Simple Solution
通信協定:手機與TV采HTTP通信
軟體接口:TV端的EIT造形與手機端Browser對接
設計:以UML表達EIT造形
代碼:賺寫I-Jetty的Servlet來實踐EIT造形
•Step-2. 啟動TDD機制、進行疊代
從手機來實機檢測TV里的EIT造形的接口代碼
依循TDD的反饋,疊代Step-1和Step-2的活動
<代碼開發>階段的敏捷疊代
•Step-3. 準備測試計畫
訂定此階段的測試方案:基於用戶需求(Requirements)
以Android手機Browser為測試方案的執行軟體
•Step-4. 以上階段Step-2產出的EIT造形為起點架構
•Step-5. 依循測試方案,展開細節設計和代碼開發
撰寫Android App代碼:基於Android套用框架
I-Jetty的調用Android的App
App透過JNI調用Android的Zigbee驅動代碼
Zigbee驅動透過Dongle發信號給壁燈開關
•Step-6. 啟動TDD機制、進行疊代
從手機來實機檢測TV里的有關代碼
依循TDD的反饋,疊代Step-5和Step-6的活動,直到完成
4.3 繼續敏捷疊代、開發新功能
新功能1:手機控制TV里的Camera拍照片
•TV/STB內的i-Jetty含有servlet代碼,讓手機可以遠距來訪問它
•TV/STB則內含Camera驅動,能控制攝像頭硬體
•運用EIT造形和敏捷疊代,開發軟體來整合家外的手機與TV/STB上的攝像頭硬體,讓家庭成員隨時從手機來打開TV/STB的攝像頭,拍了照片送回到手機上呈現出來
•展開敏捷過程,直到完成
新功能2:手機控制TV將照片送上雲端(Cloud)
•TV/STB將Camera拍攝的照片送上雲端:例如Google的GAE等
•基於WiFi通信協定
•展開敏捷過程,直到完成
Part-5: 架構設計套用:支持跨平台
5.1 三個架構設計策略
•三個實施策略:
策略-1:把它”EIT(設計)”了
策略-2:挾天子以令諸侯
策略-3:建立中間件(middleware)
5.2 跨晶片(小)平台:採取<策略-1>
情境A:先有別人的(小)平台,然後才建立我的平台
•小平台是指別人的平台,該平台的變化決定於別人
•為了跨平台,就不宜直接使用別人的平台
•您設計,而且設計來包容別人平台的變化,這就稱為:把它”EIT(設計)”了。
情境B:先建立我的平台,然後才讓別人來擴充(Extend)
•這反過來,讓別人設計外掛程式來擴充(extend)您的
•別人為了保護他自己,也會將外掛程式分成兩部分:<壁虎尾巴>與<壁虎身體>
•萬一您的有變化時,這隻壁虎(外掛程式)便能棄尾求生,讓<壁虎身體>跨您的
5.3 Android版本(大)平台:採取<策略-2>
•Android升級和版本變更頻繁,終端必須隨之而更新
•Android是一個多層級結構,各層都是由Google所開發,Google是強龍,位居天子角色,其設計來控制您的外掛程式
•您可以拿EIT造形搭配Proxy-Stub設計模式,規劃Stub類別(曹操類),制定自己的,讓脫離Android的所牽制;實現”挾天子以令諸侯”的效果
5.4 跨自己的平台(建立中間件):採取<策略-3>
•隨著您的公司業務成長,您的平台版本變更頻繁;如何包容自己平台的變化呢?
•您可以規劃一個上層平台來吸納自己平台的變化
•此平台又稱為中間件,其提供穩定的(又稱API),也保護自己平台的變動自由度,實現”沒錢就改版,改版就有錢”的效果
•中間件還能提供您的專有API,來凸顯自己平台的獨特性
Part-6: 架構設計的成功案例分享
6.1 案例:重構PhoneGap的架構和代碼
•議題:PhoneGap目前只搭配HTML5的Web App
如何重構PhoneGap的架構和代碼
讓PhoneGap也能搭配一般的Native App
•現況:目前PhoneGap的架構設計
HTML5 & PhoneGap可以讓UI更容易跨平台
其依賴Browser和PhoneGap的外掛程式來吸收平台的差異化
如果外掛程式很多時,PhoneGap里的PluginManager負責管理之
UI事件是從WebView傳送到PhoneGap的外掛程式
•目標
即使不採用HTML5,也能使用PhoneGap來管里外掛程式
一旦不使用HTML5,PhoneGap就不再搭配WebView
於是,PhoneGap轉而搭配一般的View,如Button等
UI事件(Event)改從一般的傳送到PhoneGap的外掛程式
•收穫
如何攔截App的啟動事件(onCreate事件)和UI事件
以EIT造形加快理解PhoneGap框架的結構
深刻領悟的設計要領:如IPlugin接口設計
熟悉從<重構設計>到<重構代碼>的過程
6.2 重構的設計思考
•重構範圍內共有3個EIT造形的美妙組合
第1個造形:{ Activity-DroidGap }
第2個造形:{ WebView-CodavaWebView }
第3個造形:{ PluginManager-Plugin-}
熟悉從<重構設計>到<重構代碼>的過程
•因為不再搭配WebView,所以前兩個EIT造形都必須重構
•第3個造形最複雜
•上上策是:不重構第3個造形,其內涵和接口代碼都保持不變
•成功地讓第3個造形跨到重構的新平台(即前兩個造形)
6.3 案例的成功關鍵和啟示
•關鍵:在於上述的設計思考
•洞悉:心懷EIT造形去觀察架構
•技巧:從觀察重構的變動震幅,找出上上之策
•啟示:優越架構,帶來易於重構的機會,創造了系統未來性