2015/02/26

新奇的技術 -- dbExpress

在 Paradox 玩了一段時間之後,便開始挑戰大系統的實作,接著便入手了這本書--「C++ Builder資料庫程式設計-人事薪資系統實作」
C++ Builder 資料庫程式設計 人事薪資系統實作  陳惟彬著
開始了解BDE以外的資料庫連結方式,在當時天真的以為dbExpress就是資料庫程式設計的全部。

不論如何,開始了我進入兩層架構的階段。

dbExpress Component + TDataSetProvider + TClientDataSet,每每在設計程式介面時,都不覺得麻煩,總覺得dbExpress怎麼能做到這麼多畫面的變化,現在回想起來還覺得好笑,那是Data Aware Components,並不是dbExpress限定的。

當時的MySQL已經進入5.x的版本,4.0顯得已經落後許多,接著開始嚐到dbExpress Driver的惡夢,各家的Driver對於MySQL版本的支援度都不相同,幾經嚐試,都快要放棄對它的使用。

後來找到「Just Software Solutions DbExpress drivers for MySQL V5.0」
BCB6也支援的dbExpress Driver
圖片來源:Just Software Solutions DbExpress Drivers for MySQL V5.0
(https://www.justsoftwaresolutions.co.uk/delphi/dbexpress_and_mysql_5.html),這位開發者真是佛心來的,免費開放給Delphi / C++ Builder的開發者使用,C++ Builder 6和MySQL 5.0.51a也能搭配得相當愉快。
Interbase V6.0資料庫
圖片來源:Borland

在練習一陣子後,意外地發現有個可以替代Paradox,而且還能商業應用的資料庫服務:Firebird,更重要的是,dbExpress Driver是針對Firebird孿生兄弟--Interbase V6.0而設計,對於Firebird也發揮了百分之百的相容性。
Firebird資料庫
圖片來源:Firebird官方網站

了解Firebird和Interbase的關係後,便花了好長一段時間在BDE轉化為DBX的資料連結元件上,了解到更換升級並不是想像中這麼困難。

而關鍵的TClientDataSet也能順利和其它三方元件(如:QuickReport、Indy等)一同工作,在這個階段也算是我在DataSnap上完成了初步學習,只是當時還是傻傻地不明白為什麼寫個程式原來是這樣麻煩的道理。

就在整個專案導入了dbExpress之後,卻發生了下一件事情。



「客戶想要Web版。」


一層非常好用,BDE的採用

在剛接觸C++ Builder時,大部份時間都在連接埠的輸出、輸入外,接著就要把資料儲存,以便後續的報表輸出,當時最簡單使用的就是Paradox,手冊和範例最多,於是就用它了。

那Access怎麼不考慮?

因為公司沒買。(冷)

好吧,接著便是發展所謂單機版的資料庫應用程式,話雖如此,也是過了一年的快樂時光。

那時最常使用的工具--Database Desktop


Database Desktop、BDE、PX、DB、Repair Paradox Tables等,我想有接觸過的開發者就不用多談,還沒用過的,應該也不需要再用它了。

2015/02/24

淺談軟體架構 (Software Framework)

1. 架構是什麼?
2. 架構組成的元素?
3. 以實例說明上述兩點。

A1.
架構是一種規範,用以實現「業界標準」或「特定基本任務」。
算是一種基礎設施,提供後續目標的發展。

A2.
組成的元素:概念及手段。

A3.
以 VCL framework 為例,它是為了實現以 Windows SDK (業界標準)打造的 Application(特定基本任務)。
Delphi 是尊循「物件導向」概念,利用 Object Pascal 封裝 Windows SDK 實作出 VCL framework;並按此規範產生的商品,用以實現 VCL Framework。
程序員可按此「框架」設計其符合自身的「商業應用」和「業務邏輯」,並做出最終軟體成品。

整理的重點


參閱:維基百科 - 軟體框架

2015/02/19

淺談 REST,使用 Delphi

在 XE 推出後,我才開始認真的開發 DataSnap REST Application。

其中,Developing DataSnap Applications。看了很久,也實際做出個產品出來。

只是在回憶開發過程時,卻意外地把 REST 和 RESTful 混在一起,導致有誤人子弟的嫌疑(感謝 Sryang 大的提醒),這部份預計在年後,我再把這兩個消化,再另開一篇理解文出來。

2015/02/17

試用 Devart MyDAC 在 FireMonkey Andoird 的專案教學

在 Delphi.Ktop 論壇中,有看到該如何選擇 Connection,讓 Android 平台可以連線。

最常搭配的是 MySQL ,今天就來嘗試看看 Devart MyDAC 的威力!

首先,我們先到 Devart 的介紹網頁來下載 MyDAC,安裝方式很簡單。

Just do it!

Devart MyDAC 安裝首頁,剩的便是「Next」
安裝好之後,就是 MySQL,這邊為了加速展示,我採用的是 xampp-portable-win32-5.6.3-0-VC11.7z 。
XAMPP 的執行畫面
接著便是設定 XAMPP 裡 MySQL 的遠端連線:
*****開放一個帳號擁有「%」的權限*****
擁有「%」的帳號示意圖

最後就是在我們的 FireMonkey 專案中,設定「TMyConnection」,如下圖:
除了基本的連線資訊外,Options.Direct 也請別忘記檢查一下!
TMyConnection.Connected 可以成功後,整個專案大致會長成以下的模樣:
再一步就要可以看到成果了!
連接好你的 Android,我們就可以做測試了!底下附上成果圖:



因為是試用版,所以在啟動後會跳出說明訊息。
可以成功執行!這裡因為是使用 MyDAC 試用版,所以會跳出試用版說明:
每個 TDataSet只能載入 6 個 Field 為上限。


很想再多說點什麼,但真的太簡單了,快去實作吧!

2015/02/16

我的 DataSnap 開發二部曲 -- 使用 REST DataSnap


按照近幾年 Delphi XE 的 What's New 所提及到 DataSnap 的資料所示,REST DataSnap 的傳輸效能還有再往上的空間,想要在萬年範例上使用 REST DataSnap 要有心裡準備。

但 REST DataSnap 可是跨平台的第一交椅,非得用它不可。

所以在衍生出參數化查詢的做法,並回傳物件集合,如:TJSONArray 等。

當然,這也和 FireMonkey 的 LiveBinding 有關係,可以直接和物件關係綁定,這是新的概念。

除了新概念外,能大量減少不必要的資料傳輸才是加快反應時間的問題核心。

REST DataSnap 提供底下兩種傳輸方法:

TDSProviderConnection:對應的就是 REST DataSnap 裡的 TDataSetProvider。設計方式依循 Com-base DataSnap 的做法:一個 Table / Query 一個 ClientDataSet。

後來因為這方式太不靈活,於是我採用的是另一種方法:

REST function:利用公開的函式庫,下載所需要的物件,再另行處理。


--- 未完待續 ---

2015/02/14

DataSnap 可以做和不能做的事

DataSnap 產品開發這麼久,整理一下到目前為止,DataSnap 能做和不能做(或難以實現)的工作。

事實上,DataSnap 重點只在於資料的交換,所以在設計上 DataSnap 可以輕鬆做到的事情有:

自定義文字格式的傳輸,XML、JSON 的格式還有各自的元件可以幫忙解析。

半人工:
壓縮、加密封包很簡單,除了 SSL 外,還能夠自己決定壓縮功能及自訂的加密(RSA、MD5等)方法,在 SSL 現在已經沒這麼安全的網路世界中,透過自訂加密法更能保護自家的資訊安全。
負載平衡(Load Balancing):COM-base 有個 TSimpleObjectBroker 元件可以輕鬆在用戶端完成這個工作,但在 REST-base 下就只能自己全人工設計,可以在仿照這個元件的設計概念重新實作看看。

介紹完可以做的事後,接著不能做或難以實現的工作也要提一下:

分頁任務完全無法勝任;在 DataSnap 的官方設計上,有提供分頁設計方法只有一個:TClientDataSet.PacketRecords。這還是在 Stateful 下,也就是先前提到的萬年範例才能夠支援的屬性。

那 DataSnap 完全無法做到分頁功能?
當然可以,你能透過 TDataSetProvider.OnDataRequest 事件,把用戶端當前的狀態(如頁數、表格名稱等),然後開始實作。
或是採用網頁設計中常見的手法──使用 SQL 限制輸出筆數,來達成分頁的效果。

嚴格來說,分頁不在 DataSnap 的設計規範中,所以「分頁」任務對 DataSnap 來說只能是一種奢求。


--- 未完待續 ---

2015/02/13

DataSnap 有狀態( Stateful )開發研討

做為一個簡單易用的 DataSnap,就從萬年範例開始說明:

基於 COM 架構:
DataSnap COM-Base 設計架構


基於 RESTful 架構
DataSnap RESTful-Base 設計架構


咦?好像差不多?
因為實在太像了,所以好像沒什麼變化,坊間有提到 DataSnap 的書籍大都是這樣的寫法。

先來說說萬年範例在實作上有什麼好處:
1. 需要的 Table 或 Query 可以一口氣全丟到 TDataModule,在 Client 端只需要呼叫指定的 TDataSetProvider 即可。
2. 不論是 Server 或 Client 在設計資料存取上都非常簡單,可以全力專注開發 UI/UX 介面。

缺點是:
1. 當 Table 或 Query 變多時,Server 會堆積非常多的元件,久了會造成設計時的災難。
2. 多數 DataSet 被開啟時,Server 負載會非常沉重,頻寬也會被大量占用。
3. 不論是 COM-base 或 REST-base,Server 對於多 Client 的處理都是採 Blocking 模式,Stateful 設計下若有大量 Client 開開關關 DataSet,Server 上光是排隊處理資料載入就會更浪費系統資源。

Com-base DataSnap 在有狀態的設計下,還有 Client 異常斷線造成 Session 無法釋放的問題,除了坊間外,新的版本上也是利用「超時釋放」的方式來解決,雖然做得不漂亮,但至少是解決問題了。

REST-base DataSnap 在 Client 交握上就寫得比較好,幾乎沒有發現有 Session 卡在 Server 上的問題,明顯感受到 DataSnap 進步了。

REST-base 架構在 Server 端還可以在 TDSServerClass.LifeCycle 下設置 Session 行為,調整為 Invocation,立馬就將 Stateful 改變為 Statusless,REST DataSnap 穩定性將會提高。

REST-base 看起來是不錯的選擇,COM-base 可以靠邊站了嗎?

從當時的說明手冊來看,REST DataSnap 是最佳的選擇。

接下來會提到關於開發 REST DataSnap 時發生的事情。

--- 未完待續 ---

2015/02/11

決定 DataSnap 輸出的通訊協定

DataSnap 提供豐富的傳輸方式。其中包含:

基於 (D)COM / COM+ (MTS) 的有:
  • Socket
  • Web HTTP

基於通用協議的有:
  • CORBA
  • SOAP
  • RESTful

在 XE 之後的版本,基於 COM 的 DataSnap 已經停止開發新的功能。

主要的原因是基於 COM 的 DataSnap 無法在行動裝置上被使用。

但如果仍然是以 Windows 桌面平台為主力,使用 COM 版的 DataSnap 仍然能享有最大效能的網路傳輸服務。

DataSnap 區分為 Server 端和 Client 端設計。

基於 COM 的場合:
Server 端設計上又分為邏輯程式及橋接程式設計:
1. 邏輯程式設計:以 COM / MTS 等註冊元件服務的方式存在。
2. 橋接程式設計:決定 Client 可以使用 Socket / HTTP 的通訊協定連入。

Client 端:
依照 Server 能夠提供的通訊協議,設定指定的連線元件進行連接。

基於通用協議的場合:
代表 CORBA 開發的 VisiBroker 在 Delphi 7 之後的版本已悄悄消失,不再被預載入 Delphi 的產品內,有在開發 CORBA 版 DataSnap 的開發者一定底子很好。但我是直接放棄它的使用,哪怕它有再好的能力,因為 Delphi 早已不支援 CORBA 新的技術版本了。

SOAP 在 Delphi 5 時可紅極了,設計 SOAP 的技術資料不斷的被推出,只是 SOAP 的技術理論要搞懂真的不是件簡單的事,Delphi 真的把 SOAP 變簡單了嗎?

RESTful 是從 Delphi 2009 加入的開發方向,基於 Indy WinHTTP 技術再替 DataSnap 注入新的氣象,在當時行動裝置主要以 JSON 做為與伺服器的資料交換,於是 RESTful 就此晉升為跨平台解決方案的主力。

Server 端:
邏輯和橋接會併入同一個開發專案使用,Delphi 按服務通用規範打造橋接程式內容,使用者只需專注在邏輯程式的開發即可。

Client 端:
依照 Server 能夠提供的通訊協議,設定指定的連線元件進行連接。

以上可以得知,不論 Server 端如何變化, Client 端的設計是很固定的。

而且,它的通訊協議也有個專屬名詞:MIDAS

--- 未完待續 ---

2015/02/09

多層,究竟有幾層?試著定義一下。

一層:
如果沒有使用到資料庫,那一定是「一層架構」,所有的操作全在使用者的電腦上完成,大都利用序列化陣列來當作資料庫也就足夠滿足需求。

※Delphi.KTOP 的資深版主 Jason Wang 表示:
「dBase、Foxpro 等這類的檔案型資料庫也屬於一層架構的一種。」

簡而言之,沒有內建 Service 的檔案型資料庫,都稱得上是一層架構。

在Delphi開發上,最常見的檔案型資料庫就是BDE + Paradox或是Mircrosoft Access。

Delphi / C++ Builder 經典的兩層架構
兩層:
檔案型資料庫升格為遠端資料庫伺服器(RDBMS)後,商業邏輯可以透過遠端資料庫伺服器分散運算,原本應用程式便可服務更多使用者,這就是兩層架構。
而大部分 Delphi / C++ Builder 的開發者,有聽過 BDE、ADO、DBX、FireDAC……等元件,都是使用兩層架構開發。雖然資料庫和開發機器有可能在同一台電腦上,但脫離不了「資料庫邏輯」←→「應用程式邏輯」或「資料庫存取封包」←→「應用程式資料集」交互的過程。



DataSnap 定義的三層架構
三層:
DataSnap 即是把 BDE、ADO、DBX、FireDAC 從使用者電腦拉開的代理者,而在使用者電腦上看不到上述任何元件的影子,這時開發者必須很清楚資料流各階層的傳遞流程及生命週期,就像程式設計中「變數」的設計週期一樣。

利用DataSnap橋接服務(Bridge Service),原本Delphi不直接提供資料連結的平台,也能夠透過這個服務來使用。

但絕大多數的開發者在這個階段,因為對三層的設計方式不熟悉,以及文件資訊不足的惡劣條件下毅然地放棄對 DataSnap 的使用,退守回兩層的開發,這實在是很可惜的事情。

其實 DataSnap 本質並不難,只要關鍵流程透通,三層上的天空很廣大的。

超過三層的「多層」:
你聽過「負載平衡」、「驗證」、「快取」等服務器名稱嗎?這些都是三層架構的一種,因應不同需求而採行的策略,完全取決系統架構的設計導向來定義,沒有一定的套路。

設計前的彈性很足,但框架定義完卻很難修改,所以大型專案必須經過長時間的規畫及時間來鑽研系統的穩定性。

多層大致上已經說完了,是不是還很模糊?

換句話說,就是現在網頁設計規範所提的「前端技術」和「後端技術」

前端:
泛指使用者能夠輕易看到的視覺變化技術。(例如:HTML5、JavaScript 和 CSS)

後端:
使用者看不到的繁瑣處理機制。(例如: PHP、ASP.NET 等)

而連接這兩者中間的那一「層」,就是「中間層」,如同 IIS 所扮演的角色一樣。

多層的架構牽涉的面向太廣大了,所以之後的重心還是放在三層 / 前中後端的內容上。

--- 未完待續 ---

DataSnap 能夠解決的問題?

 

作者:吳祐賓

 

Delphi.KTOP 的資深版主 Jason Wang 及 Sryang 等網友提供了很多相關資料,整理了以下內容: 多層架構可以解決兩層的四大問題: 

 

1. 省錢。
2. 跨網際網路的安全性。
3. 資料庫連線數大量增加,造成效能低下。
4. 一致性的使用者端應用程式開發。


先談談如果要解決上述問題,除了 DataSnap 外,兩層架構下有沒有其它解決上述問題的方法

 

跨網際網路的安全性問題

 

沒有任何一家公司會希望自家的資料庫遭受攻擊,在資訊安全這方面,我們會採用:

  1. 防火牆。
  2. 軟體或硬體 VPN。
  3. 遠端桌面連線。 

 

防火牆的場合:

 

 資料庫仍然需要掛上網際網路,也無法避免 Port Seek (埠位掃描)的攻擊,故實務上更改 Port 的方式也很少被採用,頂多是暫時性的權宜做法。



VPN 的場合:

 

資料庫並不直接連上網際網路,而是透過加密的 VPN 連線,進而讓使用者能夠存取資料庫的資源。

 

SecureBridge 是軟體 VPN 中的佼佼者。圖片來源: Devart

 

利用 VPN 加密封包及分散處理的效果,達到資料安全性傳輸的功能。

 

只是連線數造成的資料庫效能低下仍不可避免,以及網路持續連接的能力讓人緊張,如果是跨國連線,恐怕網路穩定性會讓使用者抓狂。

 

遠端桌面連線的場合:

Windows 內建的遠端桌面有較佳的幀率

 

 離資料庫越近的主機越好!只要網路連接有基本良率,就算斷線也只是畫面中斷,下次連線仍然可以接續上次中斷點使用。

 

最重要的是這種連線方式具有最佳的執行效能。

 

Citrix 的遠端桌面對網路頻寬的要求極低

 

但因為是畫面傳遞,所需的頻寬必須要有一定的水準,版權數和主機承載能力(兩者指的都是「財力」)是評估的重點。

 

而且,資料庫在大量連線時的效能損失的問題依然存在,可以保證的是使用者不會因資料庫連線異常導致輸入資料流失。

 

實戰上也有看到 VPN + 遠端桌面連線的雙保險機制同時被使用,提供給開發人員作為參考。

 

DataSnap 如何能解決兩層開發的問題?

 

 1. 提供 HTTP / HTTPS 及 TCP/IP 兩種通協定,並且可以自定封包格式內容,被破解機率在這一關就大幅下降,等同 VPN 的防護機制。

 

2. 資料庫連線數問題,連線數太多會造成資料庫效能降低;但太少時所花在連線交握的時間也不會讓使用端占上太多便宜。這部份的微調可視實際場合使用「連接池」( Connection Pool )來降低連線消耗。

 

3. 連線不穩定的問題,如果 DataSnap 採用「無狀態」(Status-Less)設計模式,在離線狀態下仍能進行編輯工作,等到連線狀態穩定後再與資料庫同步即可;這和微軟提出的「公事包」概念有異曲同工之妙。

 

只是 DataSnap 要做到上述的功能,大都需要自己額外寫程式,看到這裡想打退堂鼓的人應該不少。

 

按照 DataSnap 歷史路線來看,想要省力開發也不是沒有方法,RemObject Data Abstract 就是其中一個很好的合作伙伴。

RO DataSnap Server 端設計畫面。圖片來源:RemObjects

 

所謂的歷史路線指的是:Borland 一直到現在的 Embarcadero 本身沒有足夠的資源可以完善 DataSnap Server 端,所以讓 3rd-Party 廠商來合作完善,各位可以驗證看看現在的路線是不是依然使用合作策略方式。

 

當然不甘寂寞的高手們(沒錯!指的就是現在看這篇的你!),DataSnap 也提供原始碼讓開發者來設計符合自己需求的 Service ,喜歡全架構運籌帷幄的開發者們快來挑戰吧!

 

雖然能解決這麼多問題,但在少量用戶端的場合時,傳輸效能上並沒有更優於(趨近於)現有兩層架構下各 DataSet (ADO, BDE, FireDAC) 的功能。

 

畢竟就是要透過 DataSnap 再轉一手資料庫封包,這是無法避免的現實。

 

--- 未完待續 ---

2015/02/08

DataSnap? Midas? 你是誰?我應該選誰?

我想你知道 DataSnap ,但對 Midas 可能有點陌生。但提到 DataSnap 就不能不提到它的過往,底下就來介紹一下。
Delphi 3 MIDAS Logo

Midas 全名是:Multitiered Destributed Application Services;
中文是「多層分佈式應用程序服務」。

當時,Oracle 和好朋友 SQL Server 還是個天價計費的時代(現在依然價格不裴),每一個會連線到資料庫的使用者,都是燒錢的版權費用;而 Borland 和 Microsoft 的資料庫通訊的戰爭也還在持續中,這時 Borland 提出由中間應用層來負責對使用者電腦傳送資料封包,除了可以替企業省錢外,還能夠在通訊協定的戰役上扳回一成。

於是 Borland 開始進行輔導企業導入 Midas 這個工作,很有趣的, Midas 產品是另外收錢的「企業服務」,所以也不是任何企業都想使用這個服務。

隨後,好消息是,Midas 的開放,被納入 Delphi 4 以後企業版的產品線中,於是 Delphi 核心技術之一的多層開發更進一步的讓更多開發人員知道。

Midas 在當時是計劃變為中間層元件 (2003.李維.Borland 傳奇.第四章 未完的傳奇),那不就是 BDE 嗎!還好 Borland 最後沒有這樣做,有彈性的中間層開發才能面面俱到。

一直到 Delphi 6 ,Borland 為 Midas 改了個名字: DataSnap ,也確定了往後中間層開發的路線,一直到今天,這個路線一直都沒有太大的變化,也因為如此,才有了這篇的出現。

總結:
Midas 歷經 Delphi 3、4、5 ,從 Delphi 6 開始更名為 DataSnap,直到現在的 XE。
本質都是「多層分佈式應用程序服務」。

另外,Oracle 和 SQL Server 的授權方式也因為 DataSnap 而改變,所以省錢的這個條目已經被消滅,還有使用它的理由?

我想,可能還少講了 Kylix,在 Kylix 3 停止開發後,直到 XE 2 ,以不一樣的跨平台開發手法重生。

在 Kylix 還活著的時候,Linux 本身除了 JAVA 外,並沒有比較好的資料庫連線的方法。
DataSnap 也就應用在這個場合上,就算到現在的 XE ,這個理由也依然適用。

--- 未完待續 ---