[C# 實作筆記] 將 Zip壓縮檔內的文字檔轉至記憶體內的List集合

    目標:

  1. 在 C#.NET 程式內處理 *.zip 壓縮檔 (內含文字檔)的解壓縮 (decompress)。
  2. 將解壓縮後的文字檔讀進記憶體內 (memory),並將每行 (per-line)的字串 (string)儲存至 List 集合 (collection),以俾方便處理。
    主要做法:

  1. 因官方未提供處理解壓縮 .zip 壓縮格式機制,所以需下載 3rd party 的類別庫 (class library)。這裡以 SharpZipLib ( formerly NZipLib) 類別庫來處理解壓縮。
  2. 利用 SharpZipLib 內的 ZipInputStream 開啟 .zip 壓縮檔。
    string fname = @"C:\Download\TxtData.zip";
    ZipInputStream zipStream = new ZipInputStream(File.Open(fname, FileMode.Open));
  3. ZipInputStream 會依據所指定的緩衝區大小,依序將已解壓縮的文字檔內容讀至「位元組陣列 (Byte array)」;同時再利用已新增的 MemoryStream (記憶體串流)物件讀進 Byte array。
                    MemoryStream memStream = new MemoryStream();
                    int bufferSize = 2048;     //指定的緩衝區大小
                    int readCount = 0;           //回傳已讀取的位元組數目
                    byte[] buffer = new byte[bufferSize];
     
                    readCount = zipStream.Read(buffer, 0, bufferSize);   
                    while (readCount > 0)
                    {
                        memStream.Write(buffer, 0, readCount);
                        readCount = zipStream.Read(buffer, 0, bufferSize);
                    }
  4. 閱讀全文 »

透過 Google 找 Coding How-to 的好範例

我經常在文章發表或講課時說教:不要再花心思去學 How-to 了啦。 如果是對於工作上要用來謀生、不得不熟練的 How-to,那是另當別論;但是對於自我的學習成長、創新能力的發揮,幾乎不會有啥幫助。

"做中學" 的真正意義在於: 做了以後會去思考 "這是什麼?"、 "為什麼" 是這樣子?

尤其是軟體開發人員,總是要去思考,自己的職場生涯,是要往 "重複性的密集量化工作",還是 "知識性的創新設計" 之路來走?

軟體開發人員,太多太多,總是很容易把精力與時間浪費在不必要的地方上。 而且,對自己的成長卻沒啥幫助。

什麼叫作 "浪費在不必要的地方上"?

舉個例子。 上個月有位網友透過 Msn 問了我一個問題: 請問你會不會寫 C# 連結到 ActiveX 元件上?

ActiveX 是什麼? 我也不知道。 我直覺的就回答說:不是透過 MSDN 查一查範例就可以知道的?

那位網友回答說,他有查過,因為微軟已經不支援在 .NET 環境上開發 ActiveX 元件,所以看來,他必須自己要來自己從頭到尾寫 C# 連結 ActiveX 元件了。

姑且不論為何還要使用 ActiveX 元件,看來應該是要 "Re-Use (重用)" 已經寫好的元件吧。 但是,微軟轉移到了 .NET 環境卻不支援 ActiveX 必然會有其原因,可能是 安全性、穩定性與效能等問題。反正,我對其不支援的原因也不會有興趣。

但是,我只知道,那位網友要自行寫 C# 連結 ActiveX 元件這事,根本就是在浪費生命!

閱讀全文 »

關於 Excel DDE Tick 資料變更事件的處理

透過看盤軟體來接收即時性的報價資料,最便利的工具莫過於 Excel 了。 諸多交易人幾乎是利用 Excel 透過 DDE 連結方式來取得報價資料並自行撰寫程式 (如 VBA) 來分析處理。而事實上, DDE 是一種老舊的傳輸規格 (Microsoft 已制定了 RTD 規格, Real Time Data, 用來取代並不穩定的 DDE 傳輸,但國內看盤軟體似乎並未支援),不僅 .NET Framework 沒有直接支援,要處理即時性的 DDE 接收,有些實做的地方還挺麻煩的。

舉個例,在 Excel 的工作表內,設定某一個 CELL 的公式 (formula)欄為:

CATDDE|'STOCK2330  '!CurPrice

代表的就是會接受來自看盤軟體 (本身即為 DDE Server)所傳送過來的資料,並且每次會即時更新跳動 (Tick)的資料。

稍微懂一些程式撰寫的交易人都知道,當某個 CELL 的資料發生變動時,只要寫好所對應的事件處理 (Event Handle)方法,就可以處理變動欄位的資料了。 Excel 預設所提供關於 CELL 資料變動處理的事件程序為 "WorkSheet_Change()",如下:

Private Sub Worksheet_Change(ByVal Target As  Range) 
         'do something
End Sub 

理想上很簡單,不是嗎? 問題是,如果 CELL 的欄位是屬於公式 (formula)型態的 (DDE 連結即為其中之一),那麼就無法利用上述的事件程序來處理。 因公式計算後所變動的資料,並不算在資料變動的事件內;屬於公式計算後所變動的資料,是需要利用 "Work_Calculate()" 程序,如下:

Private Sub Worksheet_Calculate() 
         'do something
End Sub 

老實說,我搞不懂 MS 幹嘛這樣分,我也不想搞懂,只要能達成我所想要的功能即可。 但真正的問題來了… 比較上述的程序,哪裡不一樣? _Change Event 有參數,反之 _Calculate Event 則沒有!

這可是相當相當的麻煩了! 因為透過第一個程序內的參數 (Range Object),可以很方便地得知是哪一個 CELL 的資料變動,但第二個程式則否。 所以若要知道在某一個工作表是哪一個 CELL 的資料變動,就必須寫 FOR LOOP 迴圈,一個一個來判斷是哪一個 CELL 欄位的資料變動。 我幾乎看到許多寫判斷 Tick 資料變動的程式,都是以該事件程序 (Worksheet_Calculate) 來處理。 當然,欄位不多還 OK,但是若是像我這樣,一個工作表是撈約 100 檔的權值成份股、約有 500 ~ 800 個 DDE 欄位的話,那肯定效能會大出問題,連動當然會影響到 Tick 資料的正確性了。 整整爬文了一整個早上,總算才找到真正正確處理 DDE CELL 型態的事件程序了。 不應該使用 "WorkSheet_Calculate()"、而是採用 "SetLinkOnData()" 程序才是。

參考 MSDN 對該程序 (SetLinkOnData Method) 的說明:
"Sets the name of a procedure that runs whenever a DDE link is updated."

閱讀全文 »

VDB 理論與實作 by .NET (1) — 虛擬DB、Value 與 Business 物件的關係

VDB 理論與設計 — Ringle Lai;本次範例實現 — Steve Chou:編排與修正 — Kenming Wang。


虛擬DB(Virtual DB) 並非特定平台的實做技術,其主要特性如下:

針對某一個特定的任務,將該任務所需的相關資料由各種不同的資料來源取得至 記憶體(Memory)中,讓相關的處理程式可以「就近處理」這些資料;其與資料來源的實體儲存格式無關,且在取得資料後,應該保持與資料來源「離線(offline)」的方式來進行存取,而 虛擬DB 只提供資料的存取,不負責進行運算。

也因此,Java 世界中的 Value Object 其實也是「虛擬DB」的一種體現;至於在.NET Solution中,最適宜表現虛擬DB的技術就是 ADO .NET 中的「DataSet」技術。而 Business Object 與 Value Object 最大的差別在於 Business Object必須要有「企業運算邏輯(Business Logic)」。舉例而言,下圖就是一個典型的Business Object的類別圖:

典型的 Business Object 類別圖
(點擊圖片鏈接看原圖)圖、典型的 Business Object 類別圖

根據前述的 Business Object 的定義,我們可以發覺在上圖中,Business Objcet只有兩個,分別是:

  • Order Class – 因為其有一個【CalculateTotalAmount】的 Business Method;
  • OrderItems Class – 因為其有一個【CalculateSubtotal】的 Business Method。

而在該圖中,Product Class 因為只有一個 Getter 的 Method,因此可以將之視為 Value Object,至於 OrderItems 也有一個【Quantity】的屬性,因此也具備了 Value Object 的性質。

一般來說,Business Object其實通常具備了三個主要特質,分別是:

  • 資料面 – 這通常會以【屬性(attributes)】來呈現。
  • 企業邏輯 – 這通常是除了 Getter 與 Setter 之外的 Method。
  • 結構面 – 也就是類別間的靜態關係(包括 Association、Aggregation、Generalization 以及Dependency 等)。

然而,當我們有了 虛擬DB 的概念後,資料面的部分可以交由 虛擬DB 代勞,因此,Business Object就只存在了企業邏輯以及結構面。

我們可以利用UML的 Composite Structure Diagram(複合結構圖) 來表達 虛擬DB 與 Business Object 兩類元件的關係:

虛擬DB 與 Business Object 間的關係
(點擊圖片鏈接看原圖)圖、虛擬DB 與 Business Object 間的關係

淺論 Visual Studio .NET 專案開發的目錄規劃議題

在這一期剛結束的「系統分析設計與實作」的課程中,有位女學員問了一個問題:

「由於老師上課時都是以 “類別 (Class)” 為單位,來說明類別之間的連結關係;但是,在微軟實際的發佈(Deploy),卻是以 “DLL” 為單位,而一個 DLL 檔案,可能會包含了一到多個類別,若是被呼叫的某一個類別有經過編輯修改後,則整個 DLL 檔就必須重新編譯,相當地麻煩。 所以,到底該如何規劃這些類別的配置呢?」

先說明一下這個問題,是屬於 “相依性(Dependency)” 的設計議題。 小至以類別、套件(Package) 為單位,大至以模組 (Module)、子系統(Sub-System)、系統,都有這類相依性的設計考量。

DLL,全名為 “Dynamic-link library (動態連結函式庫)”,中文版的 Wiki 解釋是這樣的:

「所謂動態連結,就是把一些經常會共用的程式碼(靜態連結的OBJ程式庫)製作成DLL檔,當執行檔呼叫到DLL檔內的函數時,windows作業系統才會把DLL檔載入記憶體內,DLL檔本身的結構就是可執行檔,當程式需求函數才進行連結。透過動態連結方式,記憶體浪費的情形將可大幅降低。」

上述這一段的解釋應該是從系統實作(Implementation)的角度來說明的。 在邏輯性的設計觀念呢? 應該是稱之為 元件(Component) 最為恰當了; 在 UML 的塑模(Modeling)階段,則是以 套件(Package) 為單位較適合; 至於在微軟的 Visual Studio .NET 中,則確然是以 “專案(Project)” 為單位無庸置疑了。

而 VS.NET,則有兩種專案開發的容器(Container)類型,一就是上述所提的 “專案”:另一個就是所謂的 “方案(Solution)” 了。 一般說來,方案即為 “大” 的容器,一個方案可以包含一到多個專案,而且,最頂層的容器,必然是以方案為單位,也就是說,即使只有一個專案,也仍需要有一個方案存在。 這是相當合理的,較早免費版的 VS.NET Express 版本,只能以獨立的一個專案為開發單位,這反而不妥。 畢竟,專案開發時,必然會有多個相關連性的專案存在,以方案將多個專案 “聚合(composite)” 在一起,是比較恰當。 從 UML 圖來表達方案與專案的複合結構關係,可以參考如下圖:

.NET Solution 與 Project 的複合結構圖

那麼到底一個系統的開發,分為幾個專案比較恰當呢? 這當然還是要看專案的性質與規模而定。 但我強烈建議,無論如何,最起碼一定是至少兩個專案: 含企業邏輯(Business Logic)的 Model 專案,以及 UI(User Interface) 專案

UI 專案相依於 Model 專案,反之則否。 所以當 UI 未來會變動時,例如從 ASP.NET 改為 Windows Form,Model 專案是不需要作任何變動的。 當然,這樣的規劃起碼有個前提: 不會把 企業邏輯 實作在 UI 專案,而這點,應該也是軟體開發最基本的彈性度考量了。

再講究一點,對於大規模如 ERP 系統的開發,更需要考量到未來系統的變動性與延展性等議題,所以對於彈性度與可容易抽換的再利用性,自然要求就更為嚴謹了。 可以參考一下先前我曾寫過的一篇:「淺論資訊系統的分層結構」,那個圖內的每一個框框所表示的套件(Package),都會被規劃為一個個的專案。 所以,在 UI 層,會有個 UI 專案;在中間層(Middleware),則會有如 “Control”、”Business Model”、”Boundary” 三個專案的規劃。 參考如下,在 VS.NET 建立一個 Solution 方案,例如名稱為 “ERP System”,然後再建立起四個專案目錄。

ERP System (Solution)
— Web_UI
— Control
— Business_Model
— Boundary

“Control” 顧名思義,屬於在 Enterprise 系統中 MVC 基本框架中的 Control,它橋接了 UI 與 Model,也讓其兩者沒有耦合(Coupling)在一起; Model,也就是物件導向中,代表問題領域概念呈現所稱之為的 企業物件,也是軟體的主結構。 只是,國內短線專案很少重視這一塊,往往會與 Control 層糾纏在一起,以及退化成為資料庫內的 Data Model(資料模型); Boundary,連結資料庫或者外部系統。 連結資料庫這一層稱之為 “DAO 物件(Data Access Object)”、連結外部系統這一層稱之為 “Adapter 物件”,此兩者都會因連結的資料源(Data-Source)變動而必須調整,但不致也不應該影響到 Control or Model 層。

上述例子中的 ERP System 方案,在開發階段中,規劃了四個專案目錄,所以未來經過編譯後,會有四個 DLL 檔案(當然,若以 WebUI,可能有它特別的格式,但是,對於微軟的角度來說,執行期間(run-time)的一組群組(Group)起來的物件或函式庫,都可稱之為 DLL)。 再經過分層結構的相依性分析,就會瞭解到 DLL 之間的相依性關係,以及抽換某個 DLL,是否會影響到另外的 DLL。

除此之外,分為如上四個專案,還有個好處: 在開發階段可以平行分工

例如,開發 UI 專案的團隊,不用也不需瞭解後端包括 Model 層或連結資料的 Boundary 層,它只需要負責與 Control 層溝通即可; 而 Control 層,會定義系統功能的規格,包括呼叫的名稱(也就是 method 名稱)、參數與回傳值等,只要先規範好這些規格,供 UI 團隊連結呼叫即可,開發初期不需要得等到實際連結到資料庫這段工作;而 Model 這一層,甚至可以延後到系統實際上線(供 End User 操作使用)後,對於所謂企業邏輯共用性的設計需求考量,再施以結構的重整,也就是現在很熱門、從程式碼的角度來稱謂的 “重構(Refactoring)” 了。

【單元課程】活用 .NET LINQ 架構設計與源碼實作(2009/03/21,22,28, 18Hrs)

自從微軟推出 .NET Framework 以來,最了不起的創見,莫過於 DataSet 了。它可以說是橋接 UI 展示層與資料來源層的最佳機制。 利用 DataSet,可以實作虛擬化的資料庫於中間層(Middleware),呈現二維的關連資料庫供 UI 或企業物件等的操作存取。

而最近如此熱門的 LINQ 呢?
它是連結異質資料來源的最佳框架! 可以這麼說,微軟在企業層級的耕耘,其企圖心已昭然若揭:
 利用一致性(當然是微軟自己訂的)的存取語言 (Language INtegrated Query),封裝了實際連結各種異質的資料來源。

所以,透過 LINQ,你不用再去煩惱如何整合異質的資料來源,微軟會幫妳做到! 存取之後的結果,就是放到 DataSet,供 Client 存取;再則,再透過微軟另一個也是相當了不起的機制— UI Data-Binding(資料繫結),所以如 DataGridView 元件,當設定繫結了如 DataSet 之後,無論任何一端的資料變動,如資料輸入或資料來源的變更,Binding 機制均會作同步更新。

但是,廠商提供了這麼好的機制框架,它仍算是工具。企業層級的系統開發,主要仍取決於軟體開發者的設計觀,要能讓系統有所謂的彈性、延展性與再利用性,是不可能被工具給綁架駕馭的,系統是可以生生不息的,甚至爾後當微軟又推出更 Fashion 的 LINQ-II,系統的主結構仍不會被這些枝幹的汰換而嚴重衝擊的。

坊間的 LINQ 書籍,包括絕大部分的原文書,都是將 LINQ 當成如 SQL 語法一般來教導說明。那是一種工具上的說明指引,但並不會企業層級系統的設計規範。 所以,這些工具書籍不會跟妳說, UI 元件 → Form → LINQ → DataSource,這仍是換湯不換藥的 Client/Server 思維。把 Form 當成 Controller 是有問題的,是與系統設計的上述三理念違背衝突的。

本單元課程,旨在傳授,如何活用 LINQ 等機制,以設計企業層級的具彈性、延展性、再利用性的系統。除了架構的設計原則,同時我們也準備了大量的設計實例(含原始程式碼),一步一步地,從基礎導引,到整個系統的串連實現。 所以學員們上完課後,可以將這些範例當成範本,並用之於現實的工作實務上,相當地實用。 至於 LINQ 細節上的語法存取等,那是可以透過工具書,或者線上 MSDN 就可以查詢的。 我們的課程與坊間的 LINQ 工具書籍,可以達成很好的互補— 作對的事情,以及把事情做好!

※※ 課程期間,附完全免費的 午餐(含素食)、小蜜蜂咖啡、下午茶點、美味的吊鐘燒與餅乾甜點等。品味咖啡的同時,學習軟體設計思維,那會是一件令人相當愉悅的快樂學習之旅。
—————————————————— 課程說明 ————————————

§ 上課報名資訊


§ 課程大綱
閱讀全文 »

軟體思維顧問

專職軟體輔導與教育訓練的獨立顧問。輔導企業資訊單位如何有效組織系統開發與維護;輔導開發人員達成有效的專業分工。傳授如何把軟體作軟 (Keeping Software Soft)的技能,得以提昇系統的彈性/延展,並進而創造系統的再利用價值。

Personal