Thursday, August 30, 2018

使用 Node.js 的 Sequelize 如何看到自動產生的 SQL 語句

解法: 在初始化的時候,傳入一個函數給 options.logging

var sequelize = new Sequelize('database', 'username', 'password', {
    logging: console.log
    logging: function (str) {
        // do your own logging
    }
});

如果原本的 legacy code 的深處使用了 Sequelize.js ,但是,又沒有留下接口可以從高階模組去設置 options.logging 。由於 Node.js 是動態語言,在 testing/development  的時候,可以考慮直接去修改 node_modules/ 資料夾裡的內容來啟用 logging 選項。

Tuesday, August 28, 2018

準備 DB integration test

本來我的作法通常是這樣子:

  • CREATE TABLE new_table LIKE old_table;
  • INSERT new_table SELECT * FROM old_table;
先透過上述的指令,將資料表的子集合資料做成新的資料表,然後再透過 MySQL Workbench 將新的資料表匯出。最後再刪掉暫時存在的資料表。

==============
最近改用了新的方式
1. 對原始的資料表,透過 MySQL Workbench 只匯出 schema ,做成一個匯入的 SQL script
2. 透過 MySQL Workbench 下 query ,query result 只能做成 CSV 匯出。但是,可以透過其它的線上工具,將 CSV file 轉檔成為 SQL data file 

integration test / Export Database Data to SQL insert statement

寫 integration test 的時候,有時候會需要透過 SQL query 去抓取部分的 table ,然後再塞入 testing 資料庫裡頭。這件事,透過 MySQL Workbench 來做的話,它可以很快地 export result set as CSV file 。但是,變成了 CSV file 雖然可以透過 LOAD 指令來匯入,更一般的指令,應該還是 mysql insert 。

那要如何將 data CSV file 做成 mysql insert statement 呢?

(1) CodeBeautify 圖形化介面
(2) csvsql command line 指令

Friday, August 24, 2018

OO design for testability (Miško Hevery) --- 心得(續)

這兩天重看了一篇 OO design for testability (Miško Hevery) 的前 15 分鐘,又有新的領悟。

本來我覺得整個 talk 的重點是在於四個常見的錯誤不要犯,重新讀一次之後,我覺得重點是更抽象的設計原則:

設計 OO 的程式的時候,要把 class 分成兩大類:
(1) 一類是 Object Graph Contruction & Lookup ,比方 Factory ,它會有 new  operator。
(2) 一類是 Business Logic ,它會有 conditionals 和 loop 

依照這種方式設計,如果要測試 Business Logic 的時候,就可以透過 test unit ,重新 wire 一些 fake 的物件去測試 Business Logic 。

而如果要測試 Factory object ,也可以獨立於 business logic 來做測試。



可以測試的程式應該要有性質是:你可以單單只依賴整套軟體組裝起來的方式,就控制軟體的控制流 (You can control the path flow of your software purely by the way the application is wired together.)

於是又提到了一個專有名詞 Seam
A seam is a place where you can alter behavior in your program without editing it in that place.

跟 Seam 相關的另一個詞是 enabling point
Every seam has an enabling point, a place where your can make a decision to use one behavior or another.

Object Seam


附帶一提,我後來針對 seam 去查資料,發現 seam 出自一本書 WELC。在 Working Effectively with Legacy Code 裡,除了作者最建議的 Object seam 之外,作者還介紹了其它兩種 seam:
preprocessing seam 和 link seam 。

object seam 的 enabling point 是「我們生成待測物件的位置

link seam 在 Java 可以透過 classpath 環境變數做為 enabling point 。原文對 link seam 的描述:
The enabling point for a link seam is always outside the program text. Sometimes it is in a build or a deployment script. This makes the use of link seams somewhat hard to notice.

preprocessing seam 的 enabling point 則是 preprocessor define 語法

參考資料:
(1) Testing Effectively With Legacy Code
(2) How to use link seams in CommonJS
(3) Seams in Javascript







Friday, August 3, 2018

Conditionals v.s. Rules Engine

在 Rich Hickey 的 Simple Made Easy 這個演說中,他講了幾句有關「條件判斷」的話:

  • Conditionals are complex in interesting ways, and rules can be simpler. 
  • You can get rule systems in libraries, or you can use languages like Prolog.


首先,我本來考慮要直接研究 Prolog ,不過,Prolog 並沒有很容易學,畢竟是個不同 paradigm 的程式語言。但是查了一陣子 Prolog 的資料之後,也有想出一些有趣的東西:

比方說,Prolog 這種語言的核心是 unification,除了可以實現 rules engine 之外,還可以用於 data validation 和 data extraction, data transformation 。 想了一想之後,我想到了一件事:寫 validation 時,使用的 JSON Schema ,其實也可以視為是 rule 。

後來,我從 rules engine 的角度去查資料,這回查到的 library 就很有啟發。 json-rules-engine ,就可以讓 nodejs 可以使用類似 Prolog 的能力。

仔細想想,本來直接寫在 if 裡頭的條件判斷 (conditionals) ,被用 rules engine 這種「增加一層抽象層」的方式改寫,程式就會變得更有彈性 (flexibility) 。這又是再一次地應証了那句老話:

You can solve every problem with another level of indirection

Thursday, August 2, 2018

Clean Micro-service Architecture

Clean Micro-service Architecture 又是 Robert C. Martin 的文章。

大意如下:

Clean Architecture 與 microservices 是兩個正交的概念

  • Clean Architecture 是指軟體系統的設計要可以清楚地區分成 entity, use cases, controller & gateway & presenter 這三個圈圈。之後才可以不斷地配合需求而修改。
  • microservices 是一種 deployment option (布署選項) ,而且這個布署的選項有它的 trade-off 。此外,還有其它的布署選項。使用不同的布署選項,是為了達成不同的 scalability  。

其它相關的布署選項還有:

  • 在同一個 thread 裡的 jar ,彼此透過函數來溝通。 
  • 在同一個 process 裡的 thread ,彼此透過 mailbox 或是 queue 溝通
  • 在同一台 machine 裡的不同 process ,彼此透過 socket 溝通
  • 在 Internet 上不同的 services ,彼此透過 asynchronous API 溝通
引述文章裡的一小段話 --- The deployment model is a detail. Micro-services are deployment option, not an architecture. 作者主張:「開發軟體系統,要視實際的需求,再來決定要用哪一種合適的布署選項。」

注意: jar 也可以達成 independent deployability (可獨立布署性) 和 hot swapping (程式碼熱抽換。) 所以也是相關的 deployment option