03/10/2006
軟體開發進行式
三到五月間陸續寫的一點小記事。當初原本的標題是「軟體開發未來進行式」,到現在,有些已成為事實,所以就把標題改了。
- 各種應用軟體,會更傾向於以 widgets、plugins或 extensions 的方式,整合於功一較大的應用環境之中 --> 在大多時候,你不再需要開發出像 MS Office 這樣 stand-alone 的大程式
- Client 端的應用程式容器:Firefox, Eclipse, NetBeans, 以及依附於作業系統 desktop 各種 widget containers 如 Yahoo, Google desktop.
- 往後 Clinet 端應用程式,既使不見得與 Web 的應用有絕對關係,但仍會採用與 Web 相關的技術開發,如 Javascript, XUL, Java WebStarts, Flex(2) 等
- Server 端的應用程式,會採用可擴充與整合的模組式設計 --> 這裡的整合,是指像 drupal 這樣應用層級的整合,而不只是像過去的 Application Server,只是把不同功能的應用,deploy 到同一台伺服器上而已
- Server 端系統基礎架構
-
- Database, Application Cluster, Web Tier, HTML/Ajax/SVG Thin Client
- Grid Enviroment, Web Tier, HTML/Ajax/SVG Thin Client
- 分散共有的未來式架構
-
- SOA + Web Tier (Mash-up), HTML/Ajax/SVG Thin Client
- 大融合:SOA Web Grid
- Application Builder 與 Production Enviroment 的整合更良好。採用線上即時組裝與試行的方式來開發系統,針對需求直接測試解決方案。在大部分情況下,(採用UML)從頭進行系統分析與設計的開發方式,將不再需要。
22/08/2006
從 Separation of Concerns 談 AOP 與 SOA
AOP (Aspect-oriented Programming) 強調的是面向分割 (separation of concern),並且試圖由程式語言 (compiler)、框架 (framework) 或執行期 (runtime) 層次對橫切物件功能的服務考量 (crosscutting concerns) 提供支援。
AOP 本身是開發應用程式框架的有力工具,透過 AOP 的手法,可以輕易解決傳統 OOP 窒礙難行的問題。例如充斥在整個系統中的橫切服務--包括日誌、交易、安全的議題,都可透過 AOP 的支援而輕易實作出來。
不過 AOP 也引入一些問題,例如透過 AOP 手法建築的系統,其元件間的互動關係較難以理解及追蹤,因此個人認為 AOP 適用於開發 application framework 的底層,但卻並不適合拿它直接來開發應用系統。
而個人對於 SOA 所謂的 Concerns 則有二種看法:
- Business Concerns: 如何達到 (business) services independency
- 如同 AOP 中之 crosscutting concern:這在 SOA 中給它負予了一個可怖的稱謂,叫 Enterprise Concerns,其實也不過就是 log, monitor, access rights 這些非使用者功能導向的服務需求。不過 SOA 不在程式語言、編譯器或框架(framework)上解決此議題,而在架構層級解決
SOA 之所以也能達到 separation of concerns 的訴求,完全是因為它將服務的兩端抽象化,並將呼叫訊息化。在 client 與 service 之間,可以加入許多的 proxy, router, interceptor 這樣的東東,因此可以在兩造之間加入許多的 QoS(Quality of Services, 即上述的 Enterprise Concerns)。
這樣一來,這些 QoS 就可獨立出來個別設計,再於佈署時期或執行時期動態的設定,也就達到 separation of concerns 的訴求。從這個面向來說,SOA 達到了最為動態的 AOP。不過,相對的 SOA 之切點的設定便無法如傳統 AOP 的作法 (在程式語言上下功夫) 那樣的精密了。
13:35 發表於 Developing | 永久網址 | 留言 (0) | Email this | Tags: SOA, design, AOP, OOP, framework
16/07/2006
從 Inversion of Control 談 SOA 與 IoC
- IoC 強調的是依賴注入,控制權反轉。在控制權反轉這事上,SOA 與 IoC 所扮演的角色相同,都是希望元件開發者所開發出來的元件,具有 "Don't call us, we'll call you" - the Hollywood Principle 的特質。然而 IoC 相形之下,著重於元件開發層次,它強調個別元件如何實作,才能達到這項訴求 (例如: type 1 IoC: interface injection, type 2 IoC: setter injection, type 3 IoC: constructor injection)。而 SOA 相形之下,則著重於系統及整體架構。SOA 提供了在系統架構層次,如何達到控制權反轉這類機制的思維。
- 關於依賴注入,SOA 較之 IoC 有更高一層的訴求,即是希望達到 "沒有依賴",或是最低限度依賴的程式。IoC 導向的系統元件,可以達成兩個元件之間,僅相依於兩者間的特定介面。在這種情況下,只要這一介面關係存在,就能替換其中各別元件的實作。而 SOA 則希望能做到,讓系統中的每個元件,儘量使用同一組介面或協定,而不是依賴於其中某些元件的特定介面。如果整個系統都使用同一組介面或協定,代表整個系統 中的任意元件,都可以任意組合。為達到這樣的訴求,系統元件介面便需傾向於使用粗粒度 (coarse-grained) 的介面。
- 由於粗粒度的介面無法提供如細粒度 (fine-grained) 介面那樣豐富的語意,因此只好轉由介面參數身上著手,這也就是為何 SOA 強調使用文件導向的參數(亦即參數本身為一含括豐富語意的文件)
- 沒有 IoC,就做不到 SOA:試想,若你的系統架構設計沒有辦法做到控制權反轉及依賴注入,又如何在系統上線後,指定元件之間的參引關係,或是將許多元件編織 (waving) 起來,成為一個作業流程呢。所以有人說,SOA 的觀念或想法並不是用來取代現有的軟體設計觀念,而是在面對模組重用或系統整合時,所需 "額外"、"附加" 考量的思維。
18:55 發表於 Developing | 永久網址 | 留言 (0) | Email this | Tags: SOA, IoC, OO, design
16/02/2006
物件導向不再無限上綱
這是我在之前的 blog 中所提到的觀點。有幸 Jini 也在他的 blog 中提出回應,讓我有機會,將這樣的想法作更進一步釐清。
首先讓我聲明一點,在我的前文中,以「EJB 3.0 叫好不叫座」作為標題的一部分是不適當的,因為該段的內容所評論的,主要是針對物件導向方法與軟體架構設計而發。把 EJB 3.0 放在一起討論,將不相關的議題混在一起,模糊了敘述的主軸。
所以,在這篇 blog 中,我將針對物件導向方法與軟體系統設計上的一些心得,加以陳述。
* 典範轉移,物件導向不再獨領風騷
近兩三年來的確有許多軟體設計上的新思維,取得了前所未有的注目,諸如 Aspect-Oriented Programming(AOP)、Service-Oriented Architecture(SOA)、Meta Programming(以 Java 來講是 Attribute/Annotation-Oriented Programming、Declarative Programming,甚至簡單講就是 reflection)。當然這些程式設計典範(paradigm) 在推出時,都會強調並不是用來取代物件導向設計,而是與物件導向相輔相成。
讓我這樣說吧! 以上所出現的這些新的設計典範,沒有一個是在設計小程式時需要用著的。你會發現不管是 AOP, SOA, MP 甚至是簡單的 reflection,都是在設計大系統、設計 framework 才會用著的東西。例如,EJB 3 中大量採用 Annotation 來簡化部署描述,為什麼?以物件導向的觀念來說,一個系統最好全部採用物件導向的機制來實作,這樣才有「概念的整體性」性嘛。Annotation 算是物件導向技術嗎?我不認為。那為什麼還要犯了「概念整體性」、「思想純淨性」的忌諱採用這種方式呢?
原因是很簡單的,當我們(至少是我)開發大系統或 framework 時,我需要元件(想像成 EJB) 與平台(想像成 JavaEE 容器) 間,或各個元件彼此之間有更容易的溝通與互動方式,也就是我前文所講的:
當你往上堆砌系統,或一開始即採用架構導向系統開發方法(Architecture Oriented System Development)時,比較適當的思維模式,是將系統看作一部"機器",你考慮的應當是系統各部元件之間的連結,彼此間如何互動,最後才是各部元件 各自的角色與職責。
以純淨的物件導向技術來實作的話,容器或框架會定義出一些(有時是很多)介面,讓符合其規格的元件實作。當然這就算是一種 IoC(Inversion of Control),一種 callback。而這也是 EJB 2 大量採用的方式。但為什麼 EJB 3 要採用 Annotation 呢?這證明什麼,至少在某方面,Annotation 的思維可能較之物件導向思維,更適於解決某些系統間的溝通、互動角色。
* SOA 與物件導向思維之關係
SOA 的確如 Jini 所說,是透過支援一致的呼叫介面,讓異質系統可以互相串連的(當然用在同質系統中也行啦!)。然而我認為服務導向(或訊息導向) 與物件導向精神還有一個很大的不同點:服務導向架構更傾向使用 coarse-grain 的 API。相對的,物件導向方法為了充分表達領域物件的語意,通常會設計出 fine-grain 的 API。coarse-grain API 跟 fine-grain API 有什麼差別呢?
我以 EJB 中最符合 SOA coarse-grain API 型式的 JMS 來說明。我們撰寫 MessageDrivenBean 時,通常只需撰寫 MessageListener 的 onMessage(Message inMessage) 方法,然後在這個方法中,呼叫其他的物件(有可能是以 fine-grain style 寫成),就可以製造出一個能夠自由組裝資訊流程的系統。試想,如果我們這裡不用 coarse-grain API,而用 fine-grain API 來作為訊息傳遞介面會如何?我的經驗是,fine-grain API 大大的阻絕了物件/類別的重用性。這一點只要想想,用 SessionBean 是否可以像 MessageDrivenBean 那樣擁有組裝的靈活性就可明白。所以這裡的重點是,fine-grain API 適合用來表達領域物件,而 coarse-grain API 適合用來作為整個系統的通訊介面。
* Annotation、Reflection 與物件導向觀念可能潛藏的衝突
這裡我說的是 "潛藏",也就是在不良設計的情況下,並不是每個用到 Annotation、Reflection 技術的程式都會與物件導向觀念產生衝突。我從物件導向的三個特性說起。物件導向的特性是「封裝」、「繼承」與「多型」。接著我們再來想想 Annotation 的運作方式,它是在原始程式碼中定義一些 -- 好吧,就是 annotations,然後呢,在 compile time 或 rum time 時針對這些 annotations 做些處理。
當我們自己寫程式去處理 annotation 時,事實上是敲開一個類別,東看看、西看看 -- 偷窺別人的內在總是自在又痛快的事情,如果能夠痛下 鹹豬手自由 "存取" 一番,那更是淋漓盡致啦 -- annotation + reflection 給你這項偷偷摸摸的特權。而 (該死的) AOP, byte code generator 更讓你能打開類別的外衣,在裡面亂搞一通。
最明顯的,這裡嚴重的侵犯了類別的隱私(封裝性)。透過 reflection,你可以把類別的祖宗八代都叫出來。然後呢,有些本來該是用多型手法解決的問題,卻透過 annotation 或 AOP 之類的技法去解決。就算你的 annotation 或 AOP 設計精良,很可能程式的可追蹤性已變差;若是設計不良,就會產生比用 switch 敘述來取代多型的 bad smell 更難聞的 terrible smell. 所以這裡重點是,Annotation 不但與物件導向無關,甚且有害於物件導向。為採用 Annotation 的系統框架所寫的元件,極可能比採用 Dependence Injection 進入系統中的 POJO 元件更不易在別處重用。
* 同樣是 AOP,也有符不符合物件導向精神的區別
AOP 有好幾種實作方式,一種是直接在 java 語言中,增加支援 AOP 的語法,然後在編譯期將 AOP 的語法 waving 到 class byte code 中,這是 AspectJ 採用的方式。另一種是在架構上,以物件導向的方式(例如 proxy/interceptor pattern),實作對 AOP 的支援,這是 Spring AOP 所用的方式。通常前一種方式對 AOP 特性的支援較為完整,例如可以在 statement 中對被剖析的程式動手腳(加入 advice);後者則較差,像 Spring AOP 最細的 pointcut 就只到 method 層級。
照理說既然第一種方式對 AOP 的支援較為徹底,那我們應該多多採用 AspectJ 囉?事實上,我個人卻較傾向 Spring AOP。原因是,在 Spring AOP 中,可以用物件導向方式解決的,都盡量採用物件導向方式解決了。在 Spring AOP 中,不管是 pointcut 或是 advice 都是在實作特定的介面,因此這些類別,就算離開 Spring AOP 的環境,也還有重用的機會(只要你高興,你可以在一般的物件中呼叫)。而 AspectJ 的作法是增加 java 的語法,加入 aspect 元素(就像 class 元素一樣),在其中定義 pointcut。然而 aspect 與 class 的關係是單向的,不用說這些 aspect 不能離開 AspectJ 的編譯器下運作,就算是一般的類別,都不能呼叫這些 advice(對,懂得人會問為什麼要這麼做?我的理由是,給我自由。)
這裡的重點是,對於解決一個問題,你可能有好幾種作法。這幾種作法中,有些作法可與現有系統完美的搭配,而有些作法卻是充滿阻抗,與系統格格不入。選擇很明顯,給我 AOP,但請盡量用物件導向的方式。
* 有時候就是用不到物件導向的思維
或說的仔細一點,不要物件導向過了頭。例如,你在開發報表程式,你希望這樣的程式可以在資料庫欄位異動時,仍可在畫面上正常顯示。這時候,你絕不會想要對 報表所在的表格進行領域塑模。因為這時候你該注意的,不是表格代表的領域觀點,反而是所有資料庫中共有的架構特性,你該塑模的,是想辦法將資料庫綱要,與報表的樣版合協互動的方法。沒錯,報表程式中的資料庫綱要在 Java 中的確也是用 class 來表示,你會比較看重它的連結(介面)觀點。
其他的程式,像是 OLAP 程式,或是可以自由組裝欄位內容、資訊分類的 CMS 系統,我也是寧願採用較為簡單的 ER 觀點。直接處理表格裡面的欄位資料,會比較具有靈活性。這有點類似於 coarse-grain API 的作法。
* Java 失去物件導向的純淨性,卻換來開發應用系統更大的自由
Java 1.0 與現今的 Tiger 相較,哪個 Java 版本較接近純淨的物件導向語言呢?無疑的大家會同意是 Java 1.0。任何事物一開始出現,總是有美好的中心思想,但受到世俗濁流的影響,不可避免的要由純淨走向混亂。有些語言為了避免被人發現這個現象,乾脆直接招認。像是 C++ 說自己是 Multiparadigm Programming,Perl 的哲學是 There’s More Than One Way to Do It。那麼 Java 呢?
當物件導向取代結構化程序設計觀點時,我們也是花了好久習慣,但終究沒有引起太大的阻力。原因是物件導向的功能完完全全的含括了結構化設計的所有功能。今天的困難是,還沒有一種獨立、總括的思維,可以完全含括物件導向的思維。或許架構 + 元件算是吧! 但是為了解決架構與元件間連結、互動的問題,我們採用了種種沒有中心思想的作法。失去了純淨,增加了選擇。
結論
群雄並起,各領風騷。物件導向架構的語法元素,取代程序性語法元素,成為基本的建構單元。今天我們看待一個 class,就像往昔我們看待一個 procedure, function 那樣自然。
一開始的時候,程式是資料結構 + 演算法。後來呢,程式變成是一堆一堆物件的連結,但其實物件裡面也是資料結構 + 演算法。而今呢,注意一下你的企業系統:Data Warehouse + SOA。Data Warehouse 是比較大的資料結構,SOA 是比較大的演算法(流程 -- 活動的組合)。
看起來好像沒什麼不同,不過,以前你企業裡面的資訊系統是一座座孤島。而今呢?整個企業是一支可以合協運作的大程式。這就像是一堆單細胞生物,與一個人的區別。
20:05 發表於 Developing, Thinking | 永久網址 | 留言 (4) | Email this | Tags: Programming, object, oriented, design
20/05/2005
軟體開發的新生活運動
不曉得是幾十年前從 "歷史" 還是 "生活與倫理(現在小學還有這門課嗎?)" 唸到的,那個在現代聽起來有點八股的新生活運動。我倒不是要在此強調復興中華文化,講究禮義廉恥,四維八德。只是新生活運動所推行的:「整齊、清潔、簡單、樸素、迅速、確實」六項生活記律,倒是與近代軟體開發思潮所標舉的簡易之風不謀而合。
整齊、清潔
程式必須依照一致之風格來寫作。沒用到的變數要刪除,測試用的訊息不要當成註解留在文檔中。更進一步的說,系統的設計架構應明確,類別間的階層與引用關係應形成清晰的脈絡,若是系統關連猶如錯綜複雜的網路,在維護上就相當困難。
要做到整齊清潔的設計,除了一開始開發系統時,就要儘量依據物件導向之原則,採用適當的設計模式外,在設計過程中還要不時的對既有設計加以重構。這就好像是種植盆栽,軟體就像是種在盆裡的那顆樹。一開始時,我們會依照自己的期望來形塑,但當它開始成長,就必須讓它依照其本性生長,但成長到一定的階段,又必須適度的加以裁剪。在如此環境下長成的系統,就會自然適性,有風格卻又避免掉明顯的匠氣。
簡單、樸素
好的設計應該易於理解、易於改變、易於重用。「簡單就是美,不做過度設計,不開發系統用不到的功能;以更少,做更多」這幾乎成為 Agile Methodolodgy 的金科玉律。每個方法 (method) 應設計成只完成一件事,並避免在方法執行過程中產生與方法名稱無關的副作用。每個類別應僅代表一抽象或具象概念,當某一類別同時代表一個以上的概念,就會在重用時在引用端導入不必要的特性與關連,而降低重用性。
樸素的概念,也讓我想到 Plain Old Java Object (POJO) 的應用。Hibernate 與 Spring Framework 共有的特性之一,就是善用 POJO 既有的能力,來簡化物件模型。也因為 Hibernate 與 Spring Framework 只是簡單的讓 POJO 來代表 Model 的觀念,而不把其他的責任(如實體層的存取,使用者動作的反應) 加在模型上,讓這 POJO 得於遊走於 3-tiers 或 4-tiers 之間,讓我們見識到了樸素的能量,真是願原力與你同在!
簡單、樸素也適用於使用者界面的設計。除非你在設計遊戲軟體或多媒體動畫,除非你極具有美學概念,否則把應用程式弄成五顏六色,並綴之以五花八門的圖示(這種界面風格被稱為小丑裝),還不如直接讓應用程式以作業系統預設的風格呈現。
迅速、確實
Small iteration, Continuous integration 以及 Build automation 所提供的,正是迅速的開發程序。而正是因為著重確實,所以才要 Unit test,才要 Test driven design,才要代碼未動,測試先行。
迅速、確實從程式的 performmance(表現,效能)上來講,則代表系統要能有效率的完成操作,又能確實的達成系統的功能。
開發速度(迅速) 與開發品質(確實) 永遠難以兼顧,若能保持簡單、樸素的原則,要做到迅速、確實,就會容易一些!
07:45 發表於 Developing, Diary, Thinking | 永久網址 | 留言 (2) | Email this | Tags: Programming, software, design, development, principle
06/05/2005
Open for Extension, Closed for Modification
除了 Design Patterns 之外,近年來物件導向設計領域還開始講究 OO principle. 像是從前年開始流行起來的 micro kernel framework -- PicoContainer 及 Spring Framework 所講究的 dependency inversion,本身也是一種 principle。而 RMI, EJB 及 Jini 等遠端物件技術,則符合另一 principle -- Program to an interface, not an implementation. 這些 principle 之所以存在,最主要的目的就是讓我們在設計系統時,可以增加系統的擴充性與維護性。對這些 principle 有與趣者,可以到 Object Mentor 尋找相關資料。
由於昨天部門讀書會剛好討論到這個議題,我便就這個主題發表一下我的看法。像是這個讓人覺得矛盾的 Open Closed Principle, 也就是 Open for Extension, Closed for Modification,到底 Open (開放)了什麼東西,Closed (禁制)了什麼東西。用簡單的話來講,這項原則強調:
* 在設計一類別時,應保留足夠的彈性,讓採用此類別的程式,透過擴充的手法,即可新增或變更系統功能。
* 在設計一類別時,應具有適當的封閉性,避免讓採用者直接修改類別原始程式,才可達成其功能。
我想寫過稍大一點程式的朋友一定會這種經驗,當我們在程式中採用一個類別時,有時候發現該類別少了許多我們所要的特性或功能,這時候我們可能採取以下幾種作法,來達到呼叫者所要的功能:
* 你可能動手直接修改該類別某個 method 的實作
* 你可能在該類別中新增你所須要的 method
* 你可能透過建立一個該類別的子類別,再採用其子類別,來達到你所需要的功能
* 你可能將該類別的某些職責(responsibilities),透過 composition 或 delegation,交給別的物件處理,就可以達到你所需要的功能
究竟採取何種作法,除了視採用者個人的偏好外,還與原始類別設計的好壞有關。各位可以看到,上面的這幾種方法中,越上面的方法,對你原本系統的程式修改越多,而越下面的方法,對原程式的修改越少。因此如果一個類別的設計,能讓採用者越喜好使用下面的方法來達成其功能,則原始類別的設計,就越符合 Open Closed Principle。
我再舉一個 JDK 的例子,在我們使用 JDK 裡面的 API 時,就不太可能會想要動手去修改 API 裡面的實作。例如:當你發現 JButton 少了你所需要的屬性時,你大概不會動手修改 JButton 的原始碼;反之,你可能會新建一個 JButton 的子類別,再於其中加入自己所需的屬性,這就符合了Open Closed Principle (甚至所有的 JComponent 都允許你用 putProperty 的方式,在不用新建子類別的方式之下,動態新增屬性)。還有不少 JDK API 的設計,也都符合這項原則,像是 sort 只要傳入 Comparable,JButton 有 addActionLisenter, JTable 有 TableModel... 不勝枚舉。
07:30 發表於 Developing | 永久網址 | 留言 (0) | Email this | Tags: Programming, software, design, oo, object, oriented
23/01/2005
滑鼠筆
之前因為常開 Net meeting,在會議中,除了圖文簡報、言語溝通外,當然少不了採用電子白版塗鴨筆戰。當時就興起了一個念頭:有沒有造型像筆一樣的滑鼠,讓我在使用電子白版時更加便利,而不必以一般的滑鼠來模擬?
於是我便 google "滑鼠筆",果然有這種東西。看了其中幾個品項,最中意的是:
http://lab.digitimes.com.tw/patnews/patnews.asp?NewsKey=00003715
打定主意之後,便前往台北最熱門的幾個資訊商圈尋寶。台北站前 NOVA 廣場,K-Mall 的商家泰半沒聽過這東西。光華商場的老闆們相較下就較見多識廣了,雖然大半的商家還是沒聽過,不過已經有些商家回問我 "你怎麼會想用那種東西?"、"用起來很不習慣!"、"賣的不好,貨全退回去了。"
一連串的 "否定句" 之後,我開始懷疑是不是滑鼠筆真的不好用,並逐漸昇起放棄的念頭。就在我繞完大半圈,準備打道回府之際,卻讓我在 "現代生活廣場" 地下一樓的某個店家,找到這樣的東西。
http://tw.f3.page.bid.yahoo.com/tw/auction/c11977867
http://www.v-mouse.com/
那個店員是個熱忱的年輕人,他也很是訝異我為何要買那樣的東西,並讓我試用了一下。
嗯~ 試用過的感覺,果然跟一般的滑鼠很不一樣。習慣是鋼鐵的內衣,我想大部分人都會因跨不過變更操作這個門檻而作罷吧! 我想我可以習慣的,就像我習慣 IBM 筆記型電腦上的小紅帽一樣。不過,最終我還是放棄了。原因是,我發現它的滑鼠左右鍵設計的太過接近,讓我常會按到不對的鈕。另外,它的筆頭是圓的,讓我有一種很難對準鼠標的錯覺。
嗯,這又讓我想起到:如果你的產品讓使用者感到挫折,那麼使用者就會讓你對你的產品銷售業績感到挫折(約耳談軟體:程式師的使用介面設計手冊 - 第1章: 控制你的環境使你快樂)。而且如果你第一次沒有做好產品設計,第二次再推廣同樣概念的產品時,就會更加費力。就滑鼠筆的例子來看,我甚至認為這項「良好的概念」,已被「糟糕的可用性實作」打壞,從此難以翻身。
建議延伸閱讀:
《設計心理學》、約耳談軟體:程式師的使用介面設計手冊
09:20 發表於 Goodies, Thinking | 永久網址 | 留言 (1) | Email this | Tags: Taiwanese bloggers, 滑鼠筆, design
14/08/2004
Software: Thinking of a Better User Interface Design
- Panel Based:面版型使用介面。像是 ICQ、MSN、WinAmp 等,強調使用便利性的程式,便會使用這種介面。
- Dialog Based:採用對話窗作為應用程式介面。常見於極小型的工具程式,或組態設定程式。
- Explorer-Like UI:指的是長的像檔案總管一樣的使用介面。這種介面可以很容易的讓使用者從大量的文件或物件中,選擇要操作的對象。像是 mail client 也大都是這種設計。
- SDI: 單一文件視窗介面,這種介面設計常見於小程式,像是 Notepad。如果用在大一點的程式中,就必須要加上許多浮動視窗,像是 OpenOffice。這種設計的缺點是,要開啟多份文件的話,就要開啟多個視窗或應用程式。不過話說回來,也許這能讓使用者更專心於目前的文件上頭。
- MDI: 多文件視窗介面,這種設計常用於中、大型應用程式。優點是可以在同一個視窗中顯示多個子視窗,缺點是如果某個子視窗最大化,要選擇其它視窗,得靠 "視窗" 選單。如果用 Swing 的 JDesktopPane 實作,沒視窗選單可用,就得要將最大化的子視窗縮小,才能切換到其它子視窗,真是夠難用的了…。個人對 MDI 介面的另一個抱怨是,即使文件子視窗最大化之後,還是有一條很醜的子視窗標題列。
- TDI (Tabbed Document Interface):這種設計與 MDI 一樣,具有同時開啟多份文件的能力。與 MDI 不同的是,TDI 採用頁籤切換文件。好處是在文件切換上較為簡便,缺點則是一次只能看一份文件、要比較兩份文件 (或一份文件的不同位置),就相當麻煩了。目前我看到做的最好的 Tab 視窗介面,是新版的 NetBeans Windowing System。
- Split -Pane:分割視窗;為了解決 TDI 與 SDI 一次只能觀看一份文件的限制,有些 SDI 或 MDI 使用介面會搭配 Splitter,讓你可以把視窗一份為二。像是 Word 就具備這種功能。另外還有一些軟體、是為了特殊的使用性,才採用這種設計,像是 WinMerge(檔案比較)、FileZilla(FTP)、7-Zip等。在 MDI 中,把這種功能發揮到極致的是 Notepad++。
- MDI + TDI:MDI 與 TDI 各有優缺點,如果能把這兩種介面設計結合起來,就能達到功能互補的效果。一個著名的例子首推 UltraEdit,另一個不錯的例子是 CPad。以上這兩套應用程式,在子視窗最大化之後,都不會有那一條醜醜的子視窗標題列。
- Dockable UI:是指應用程式的視窗可以隨意拖曳、停駐在某些地方。常見於 IDE (整合開發環境) 上。Visual Studio.NET 及 Eclipse 都有強到不行的 Dockable Interface。雖說如果應用程式的整體 Layout 設計得當,那麼有沒有提供 Dockable UI 並不是那麼重要,但若是像 Eclipse 那樣,使用者可以無限制的外掛其他 plug-ins,那 Dockable UI 就相當重要了。因為原始系統開發人員、永遠無法想像,最終在使用者電腦上執行的,是怎樣的組態…
以 上就是目前我所能想到的 UI 類型了。由 UI 演進的軌跡來看,最先進的設計非 Dockable UI 模屬。但一定非得像 Eclpise 或 NetBeans 那樣 Docked Evey Where and Tabbed Evey Where 才是好的設計嗎? 我覺得不儘然。
以下面的 NetBeans 視窗為例

我 將它區分成 (a)左方的瀏覽區、 (b)下方的訊息區,以及 (c)右上方的文件內容區。當然 (a) 與 (b) 採用 Dockable Tabbed UI 是較好的設計。而 (c) 區則未必一律適合採用。原因很簡單,並不是所有的內容視窗都適合像 TDI 一樣,以最大化的方式展示。因此在 (c) 區,採用 MDI + TDI 混合式設計,可能更為合適。
06:05 發表於 Developing, Thinking | 永久網址 | 留言 (0) | Email this | Tags: Programming, software, design, gui
27/05/2004
從 Use Cases 到 Usable Classes
如何從 use case diagram 中推演出 class diagram? 我想這是任何採用 RUP 開發方法或熟悉 UML 技巧的團隊都應該能回答的問題,而且每個開發團隊都應會有自己擅長的作法。以下提供我個人的作法:
由 use case diagram 推導出 sequential diagram
每 個 use case diagram 應該都能以 sequential diagram 作進一步的表示。在 use case diagram 轉化成 sequential diagram 的過程中,use case 中的名詞 (或形容詞) 會變成 sequential diagram 中的物件 (類別) 或其屬性 (但屬性不顯示於 sequential diagram 中),而動詞則會變成訊息 (或功能)。至於訊息所攜帶的參數,則可標示出物件間的參引關係。在推演 sequential diagram 時,我會將相關的功能指定給同一個物件,並將相似的概念結合在一起。這樣作的好處是可以得到最小的物件 (類別) 集。
由 sequential diagram 推導出 class diagram
一 旦求出 sequential diagram 後,要推導 class diagram 就相當簡單了。Sequential diagram 上方的每一個物件圖示,皆可推演出一個 class diagram 中的類別。我會將 sequential diagram 中的訊息轉化成類別中的函式。而類別的屬性則來自訊息的參數或 use case 中的某些名詞。並不是每個 sequential diagram 中的物件都需設計相對的 class。如何設計出每個 class,會視以下幾個因素決定:
- Class diagram 的精細程度:例如,您的 class diagram 是要作為 conceptual notation、 blue-print 還是 implementation detail。
- 設計考量:可能設計為 interface, abstract class, concrete class 或 class hierarchy
- 系統的執行環境:可能該類別已經存在,那就不需要設計了。又或者系統是否存在如 XP 中所稱 big design,或是 [1] 中所陳述的 Architecture。個人強烈建議在開發應用程式功能前,先把系統大架構搞好!
- 所 採用的平台:在 MDA 中,將 model 區分為 PIM 及 PSM。PIM (Platform Independent Model) 是指與 business logic 有關,與 platform 無關的抽象模型。而 PSM (Platform specific Model) 是指與實作平台有關的解決方案模型。在 MDA 還不成熟前,如果要自己設計 solution model,就必須考量實作平台
OK! 就是這樣,兩個步驟解決!
See Also:
- [1] Activity與Use Case的分解規則有何不同呢 - by 高煥堂;解說ACPM軟體開發方法與應用系統整合技術
06:50 發表於 Developing, Thinking | 永久網址 | 留言 (0) | Email this | Tags: Programming, use case, design


