搜尋此網誌

2012/07/19

AJAX Web 自動化

  • 試用 ExtJS 4.1
  • 以Tomcat 7.0 做為
  • 使用 DWR 做為橋接browser與server的framework。
  • 使用 Apache OJB + XDoclet 為 O/R mapping framework。
  • 資料庫使用MySQL
  • 透過 ICPDAS I-7188 連接 永宏(Fatek)的 PLC ==> Fatek prorotol
  • ICPDAS 簡訊機。  ==> Modbus/RTU over TCP


監控畫面

 細節

 即地編輯(In-Place Editing)


查詢與報表(PDF)

2012/04/30

在Delphi匯入WMP ActiveX控制項

在Delphi匯入WMP ActiveX控制項

有兩個Media Player,應選擇TWindowsMediaPlayer (wmp.dll),而不是TMediaPlayer (msdxm.ocx)
因為Delphi內建已安裝TMediaPlayerSystem元件盤。


最後應該會安裝至ActiveX元件盤,元件名稱為WindowsMediaPlayer



與房仲相關的概念模型


2012/04/27

SPC Show Chart 探討

SPC Show Chart 探討

在這份文件中,我將再深入探討SPC Client的中以各種形式呈現Chart的設計模型(OOD Model)
我的目標是提出一套考慮更為完整的物件導向設計,使得在接下來的實作階段中能夠花最少的力氣以更有效率地完成程式實作,同時仍然能夠保持軟體品質,易於除錯,易於閱讀與維護,以及易於因應軟體的改變(降低軟體的改變的成本與時間)
當然了,實作之中永遠會有更多煩人的細節,有些細節可能會影響到本次設計的模型架構。但是我們預期此部分的問題可以等待至本設計的核心實作出來後,再以程式重整(Refactoring)的手法來回頭修改(Refine)本次設計的模型架構。
這份文件不會提到任何與使用者介面相關的技術,如果您需要此類的資訊,您應該去查閱Borland C++ BuilderC/C++程式語言的相關文件。另外這份文件也儘量不去提及與特定程語言相關的論題,僅當實際的設計模型使用到與特定程語言相關的技術時,我才會加以說明。同時我也假定您對設計樣式(Design Pattern)已具有相當程度的瞭解,所以我也不會對所模型中所引用的設計樣式做過多的細節解釋 已經有許多的書籍及文章完成這個工作,如果需要的話,您應該先去閱讀這些書籍及文章。
特別聲明: 
我已經儘量參考目前所能夠得到的資訊來寫作這份文件,同時我也已盡力維持設計的正確性與一致性,但是其中或許仍有疏漏。如果有任何人發現的話,請不吝告訴我。謝謝! 

目前SPC模組有7Chart,而每一個Chart都必須支援3種呈現方式(On-Line ChartOff-Line Chart,以及Report),要如何解決Chart與呈現方式的「配對問題」(7x3)?同時仍保有彈性與擴充性?
1.           ChartType抽象出來:每一個Chart可以想成ChartDefChartType的組合。而當ChartType被決定的同時,很多其他的事物亦同時決定了。
注意:此處的ChartType抽象類別



2.         ChartTypeHistogramChartParetoChart,…等7 (這裡繪出2種做為代表)。這是一種利用Object Composition達成C/V的方式。




3.         ChartDisplayChartType分離出來。其具體子類別有OnLineDisplayOffLineDisplay,及ReportDisplay。注意:此處的ChartDisplay是抽象類別。

4.         定義ChartForm抽象類別。ChartForm物件有責任執行真正的Chart顯示與報表產生的工作。它有3個主要的Methods

    1. showChart()
    2. showOffLineChart()
    3. showReport()

ChartForm的子類別理想上應該就是實際的UI物件(例如BCBTForm物件) ,但是實際上恐怕很難達成此要求,同時又為了增加彈性(實際的UI物件可能會改變),所以我們可以使用Adapter樣式來處理實際的UI物件(見下一步驟)



5.         完成!!

每個ChartType物件有責任建立出正確的ChartForm物件(Expert樣式)。當ChartDefdisplay方法被呼叫時,ChartDef物件會將此呼叫委任給其內含的ChartType物件的display方法處理,而ChartType物件的display方法會根據子代類別的override版本來執行(多型),而ChartType物件的display方法其實也是將此呼叫委任給其內含的ChartDisplay物件去處理。而到此處,ChartDisplay物件才會將此呼叫委任給真正執行任務的ChartForm物件。

此處值得注意的地方在於ChartForm的子類別往往只是一個Adapter(Wrapper),其目的在於使得我們可以以一致的介面處理背後的UI物件(這裡的UI物件即是BCB中的Form物件,而此Form物件上已有QCToolsSPC繪畫元件,但是此Form物件未必會繼承ChartForm)。所以圖中的HistogramChartFormParetoChartForm類別即扮演著Adapter的角色。其典型的做法即是使用Object Composition的方式包裝實際的UI物件(Form物件),然後將呼叫委任給其所內含的UI物件處理。



1.           這裡的解決方案中如果以C/V (Commonalities/Variabilities)分析(CVA)的角度來看,ChartDefChartTypeChartDisplay,以及ChartForm類別即代表了Commonalities (見下圖),也就是代表一個共同的抽象概念。而Commonality類別的子類別則代表了Variabilities
這種手法可以讓抽象類別來「封裝」Variation (也就是物件導向所說的「易於修改),但又能讓系統保持概念上的穩定性。所以請記注一句物件導向的內功心法:「Abstraction is the key!

2.         此例多處利用抽象類別封裝具體類別的方式「封裝」的新觀點。因為具體類別即代表系統中可能變動的部分,所以此符合物件導向中的「Find What Varies and Encapsulate It!」原則。
3.         封裝行為「封裝」的另一新觀點。分析問題時不要認為「封裝」只是指「資料隱藏」,而要採用更為廣義的定義「封裝指封裝任何事物」。此例的哲學即在於「封裝display的行為」。
4.         此例的關鍵處大部分使用Object Composition而非Class Inheritance。此亦符合「Favor Object Composition than Class Inheritance」原則。
5.         Adapter樣式不僅只是用來轉換不同的介面而已!其真正的價值在於讓我們在設計時無須擔心有任何具體類別無法符合我們的模型。因為有了Adapter樣式,我們可以轉換任何介面不符合的類別。

物件導向的基本觀念

物件導向的基本觀念

前言

物件導向系統是由物件所構成,但是大多數的人似乎從來沒有仔細思考過一些問題,例如:
物件導向到底是什麼?背後的原理為何?
物件的概念是物件導向最基礎的概念之一,但是許多人對物件的認知似乎只不過就是「封裝」、「繼承」、和「多型」這樣而已。如果基本功夫不先練好,未來許多更高深的武功學起來也將事倍功半了。
在臺灣,許多人進入物件導向的領域多是由OOP入門。但是OOP通常假設讀者已具備足夠的物件導向觀念。同時OOP只是程式語言實作物件導向觀念的產物,在許多物件導向觀念上並未清楚地呈現與區分,所以若是在物件導向觀念尚未建立好的情況下學習OOP,結果反而會造成許多觀念上誤解。本文的目的就是在澄清這類的誤解
這篇文章中以GoF的「Design Patterns」為基礎來整理出一些物件導向的基本觀念,希望能讓大家對物件有更清楚與深刻的認識,在面對現今迅速發展的物件導向相關技術與方法論的同時,能夠更快速掌握其要點與精髓,而不至迷失在複雜的技術細節中。
這篇文章的主要目標對象是已經稍具OOP觀念的讀者。如果你沒學過OOP,或者OOP尚無足夠的經驗,這篇文章也可以提供一些基本的物件導向觀念。
在閱讀這篇文章時請不要讀得太快,因為這是篇闡述觀念而非應用技巧的文章。許多概念都依賴前面所定義的概念,所以在往下讀之前請先確認對已讀過的概念已有清晰的理解。

註:Eric Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns – Elements of Reusable Object-Oriented Software. (有中譯本,培生出版,葉秉哲 )

軟體開發流程的哲學

不論是RUPXP,與軟體生命週期等的軟體開發流程,其實都是用一種「由高階觀點逐步往下對應至低階實作的過程」的哲學來開發軟體系統。基本上各家學說都還是秉持著分析、設計、實作、與測試的步調,只是對在此開發過程中的一些議題有著不同的觀點。這是因為大家的目的都是為了「以最低的成本,最高的效率,在時程之內,將具有合理品質的軟體交付給客戶」,所以該遇到的問題其實都是一樣的。各家學說也基於這樣的目的,所以嚐試為開發過程中可能會遇到的問題提出一套解答(當然也包含了它們的假設前題),並將這些解答加以系統化與標準化成為一套流程,讓大家可以照著做。
根據Martin Fowler(UML Distilled的作者)的說法,我們可以用概念觀點(conceptual perspective)規格觀點(specification perspective)、以及實作觀點(implementation perspective)來看一個軟體系統。所謂實作觀點就是傳統上以程式碼觀點來看系統­­­­—對應到開發過程的實作階段,相信大家都已非常熟悉,所以不在此贅述。而規格觀點指的就是物件或子系統的介面規格對應到開發過程的設計階段,至於概念觀點就是以物件的邏輯責任(responsibility)來看系統(do what)­—對應到開發過程的分析階段。­所以軟體開發可以看作是一個由概念觀點(高階),經過規格觀點,進而來到實作觀點的過程(低階)
同樣地,物件也具備這三個觀點。由概念觀點可以定義出物件的責任,由規格觀點可以定義出物件的介面,而實作觀點即是物件的程式碼。而物件導向最重視的觀點就是概念觀點
掌握了物件的概念觀點才有可能體悟到物件導向的精義,這對於OOAOOD是非常重要的。許多人無法享受到物件導向的好處的原因常源於此,過度地以實作觀點來看物件導向系統是很難看到其精妙之處的,所以自然無法享用其利益了。
事實上本文中所解釋的觀念都蘊藏在許多設計模式(design pattern)之中,許多人讀了很久的設計模式後,經常還是難以體會其中的精髓,無法活用設計模式,充其量只能拿著GoF那本書的23個模式依樣畫葫蘆而已(甚至永遠只會其中那幾個模式)。相信若是完全理解本文中的觀念後,對設計模式會有更深的一分體認。

什麼是物件導向

物件導向方法的目的與優勢在於提高軟體重複使用的程度,讓軟體更易於理解與維護或修改,更重要的是能良好地因應需求的變動。這對現代日趨龐大複雜的軟體是非常重要的因素。這也是物件導向越來越風行的原因之一。
雖然物件導向有這樣的好處,但是真正能享受到好處的人似乎不多。其中的原因多出於對物件導向觀念的不良或誤解。事實上,相對於程序導向來說,物件導向更為複雜與困難。雖然物件導向好像一把威力極大的寶劍,但若是內力不足的話,即使得到這樣的利器,終究還是難以享受到美好的成果,不僅無法善用其優勢,甚至反而可能先誤傷了自己。
所謂登高必自卑,底下開始介紹一些物件導向的基本功夫。基本功練好了才有可能學好更高深的武功,不是嗎?J
Ø         介面
大家都知道,物件的client(物件的使用端)會呼叫物件所定義的方法(method)要求物件執行某些動作。唯一可以使用物件的方式便是透過物件的介面呼叫。在繼續說明物件介面的觀念之前,我們必須先複習一個基本的程式設計觀念­
函式(方法)簽名(signature)
註:「呼叫」在物件導向理論中大都是用「物件的client端傳送訊息(message)給物件」這樣的說法。
一個函式(方法)的名稱、參數型態與個數、與回傳值構成了函式(方法)的簽名。要留意的是:函式(方法)簽名並不包括函式(方法)的實作部分(也就是程式碼的部分)。用C++的說法就是:函式的宣告(declaration)就是函式簽名,而函式的定義(definition)就是實作。在C++中,函式的宣告通常放在標頭檔(header file),而函式的定義(實作程式碼)通常放在CPP檔。
以下我們可以開始介紹一些物件介面的重要概念了:
n          介面(Interface)
物件介面指的就是物件所訂定的所有方法簽名(表示物件提供給外界使用的溝通方式,也就是可以送給此物件的訊息類型)。至於這些方法是如何實作出來的則不包含在介面的概念之中
介面是物件導向最基礎的概念。我們想叫物件做任何事,都必須透過介面完成。
n          型態(Type)
型態是指某一個特定的介面(亦即特定的一組方法簽名)。例如當我們說:「A物件擁有Window型態」時,就是說A物件具有Window型態中所定義的一組方法簽名,A物件具有Window的行為,可以接受Window型態所定義的訊息。通常型態都具有一些邏輯上的意義,例如Window型態、Drawable型態、…等,這視我們的需求而定。
由型態的定義可知,物件可能同時具有多個型態,而多個物件也可能具有相同的型態。但是請注意:具有相同型態的物件並不一定表示有相同的實作。(記得介面與型態是不包括實作的嗎?)
n          繼承(Inheritance)
介面也有繼承的觀念。在介面繼承中,子介面會包含父介面。說得白話一點,就是子介面會包含所有父介面中訂定的方法簽名。
Ø          類別
在物件導向中,類別只是用來定義物件的實作細節而已。在類別中會訂定出物件的資料成員、方法所使用的演算法,以及其他種種的實作事項。換句話說,類別實現了物件的介面。
這裡要請注意的是,千萬不要把物件導向程式語言(Java.NET、…等)中的interface和這裡本文中的介面搞混了。並不是程式語言中使用interface關鍵字定義的資料結構「才有介面」,而使用class關鍵字定義的資料結構「沒有介面」。這是一個物件導向程式語言所經常造成的誤解!物件導向中的介面是一個抽象的概念,凡是物件都一定具有本文所提的那種抽象的介面
以下介紹類別的一些重要觀念:
n          繼承(Inheritance)
類別繼承被視為由一既存的類別定義出新的類別的方式。子類別會享受到父類別所開放的實作(資料成員與程式碼)。類別繼承的目的通常是為了重複使用既存程式碼(reuse),是重複使用的方式之一。
雖然類別繼承看起來非常的方便,但是過度使用類別繼承經常會產生巨大而混亂的繼承體系,而且父類別對子類別的繼承方式也經常有某種假設,更嚴重的是造成軟體無法更良好地因應需求的變動。所以在OOD中,反而偏好使用另一種重複使用的方式(後面會說明)—委託(delegation),以避免此類問題的發生。
n          抽象類別(Abstract Class)
許多物件導向程式語言都提供定義抽象類別的方式,但是初學OOP的人往往都感覺不到抽象類別的存在目的為何。有些人乾脆就把抽象類別視為擺放共用資料與程式碼的地方,然後以類別繼承的方式使用這些共用的東西。
事實上,抽象類別的用處不僅止於此。抽象類別的主要目的是為後代族系的具體類別定義一個共通的介面,讓物件的client端透過抽象類別來操控物件,避免client端直接與具體類別耦合,降低變動的修改難度。抽象類別通常會定義一些未實作的方法(稱為抽象方法),然後把部分或是全部的抽象方法留給後代子類別去實作。
在物件導向設計模式(design pattern)中,抽象類別佔有極重要的地位,幾乎在每一個模式中都會發現抽象類別的蹤影。
n          具體類別(Concrete Class)
這大概是物件導向中最為人們所熟悉的概念了。但是這也可能是許多人無法真正進入物件導向殿堂的原因之一。J
具體類別定義了真正的實作,它裡頭不會有任何的抽象方法。事實上物件就是實體化(instantiate)一個具體類別所產生的。換句話說,物件是具體類別的實體(instance)
如果說抽象類別表達了系統中不變的部分,那具體類別就是系統中變化的部分。這個觀念在OOAOOD中非常的重要。
具體類別常會覆載(override)父類別的一些方法,這就是所謂的多型(polymorphism)
Ø         類別繼承v.s.介面繼承
類別繼承是用來以一個物件來定義另一個物件的實作細節;而介面繼承則描述了物件之間的可替換性。
在許多程式語言中,這兩個概念沒有被明顯的區分出來。在Javaextendsimplements區別二者。Extends表示繼承某一類別的實作,而implements表示繼承介面而已。
所謂的「可替換性」表示在任何需要某特定介面的地方,只要傳入符合此特定介面的物件(亦即此傳入的物件繼承了此特定介面)即可。至於這個傳入的物件是否是同一類別並不重要。
Ø         類別繼承v.s.物件複合
物件複合(object composition)指的就是一個物件包含其他物件。當物件接受到client端的訊息(呼叫)後,將此訊息交付給其內含物件去處理。
就語意上的觀點來說,類別繼承表達了is-a的語意,而物件複合表達了has-a的語意。二者都是一種reuse的手法,只是類別繼承稱為白箱重複使用(white-box reuse),而物件複合稱為黑箱重複使用(black-box reuse)
為何類別繼承稱為白箱重複使用呢?那是因為子類別若想繼承一個父類別時,通常子類別對父類別的一些實作方式必須有相當的瞭解,父類別對於子類別的繼承方式通常也有某種預期,這稱為父類別與子類別之間的合約(contract)。所以父類別對子類別來說是某種程度的「白箱」。
相反地,在物件複合機制中,物件只是將request轉交給內含物件處理。物件本身就如同內含物件的一個client端而已,它對內含物件實作方式的瞭解並不像類別繼承中父、子類別間那樣,所以內含物件好像是一個「黑箱」。
由於類別繼承中父、子類別之間的關係過於緊密,所以必須謹慎使用類別繼承機制。否則很容易造成系統的高度耦合。而物件複合則可避免此類問題。
所以請多使用物件複合,小心使用類別繼承。
Ø         委託
委託(delegation)指的就是當物件接受到client端的訊息(呼叫)後,將此訊息交付給其他物件去處理。這種機制在前面所提到的物件複合中也提到過。
在類別繼承所形成的多型中,父、子類別可以使用例如thisself等的關鍵字互相存取。但是在委託中,呼叫者物件必須將自己傳給被呼叫者物件,方能讓被呼叫者存取到呼叫者。
呼叫者物件通常面對的被呼叫者只是一個抽象類別或介面,呼叫者物件根本不知道真正被呼叫的物件為何。此與類別繼承不同,因為子類別知道父類別為何。
因為呼叫者與被呼叫者間對彼此實作沒有任何瞭解,所以委託機制通常用以降低物件之間的耦合度。

結語

Ø         物件導向設計原則
n          Programming to interface, not to implementation.
n          Favor objects composition over class inheritance.
Ø         難以因應需求變動的設計:
n          直接使用類別的名稱建立物件
n          與特定操作相依
n          與軟硬體平台相依
n          與物件佈局或實作方式相依
n          與演算法相依
n          高耦合度
n          過度偏重以繼承方式擴增功能
n          類別不易修改