上個禮拜在 HITCON 的天瓏書局攤位,看到這本七月剛出的 PHP 設計模式學習手冊,心中燃起一絲對 PHP 的小火,心想已經荒廢那麼久的 PHP 該是時候補充一下彈藥的時候啦~,尤其是最近剛看完 JavaScript 設計模式,應該能對比一下兩個語言實作上的差異,來更深入的理解這些設計模式應用的場景。
分類: 程式設計
JavaScript 設計模式
上個禮拜參加完 JSDC 2013 以後,我就壞掉啦,本來已經很久沒有讀程式寫程式,這裡拜突然就很熱血得衝去天瓏買了 JavaScript 設計模式跟 JavaScript 網頁應用程式設計。奇怪的是歐萊禮這本書是 Pattern 怎麼會是設計模式,那叫 Learning JavaScript Design Patterns 面子往哪襬阿!根本就是卡位…以後讀者在書局看到 同個出版社有 JavaScript 設計模式 跟 學習 JavaScript 設計模式 時情何以堪阿。。
算了…紀錄一下心得好了,由於之前都在網路上斷斷續續的學習 JavaScript 關於 prototype 繼承的資料,一直學得不是很扎實,所以之前都想寫文章來紀錄自己瞭解的程度,沒想到每次都寫的二二六六,證明自己根本沒搞懂,所以也沒什麼本事表達清楚了。
但看完這本書,突然有種任督二脈打通的感覺阿,把 Object、Prototype、__proto__,物件繼承的關係跟模擬 class 的方法,講得清清楚楚,這也佔了本書幾乎一半的篇幅,這本書最重要的其實就是這個部份啦~後面的設計模式根本只是來貼咖的~只是看完了以後有種憂傷,之前花好多時間亂學的,現在都在書上啦。。變成好像很沒價值的知識了~所以還是要把英文學好點,才能多看一點還沒翻完的…
還有各種產生物件的方法跟差異,也是詳細又清楚,之前本來覺得自己加減知道怎麼模擬 class 就還不錯了,他裡面更是解釋各種方法的優點跟缺點,一項項條列出來,又比較不同方法的差異,跟最好最通用的方法。
阿,好像是我太弱了,所以感覺學到新東西都令我開心,所以還蠻喜歡這本書的。。期待 JavaScript 網頁應用程式設計能帶給我更多新知阿。。
phpconf.tw 2012
phpconf2012 已經是 phpconf 第二屆了,去年就有注意到,但是那時候在高雄沒辦法參加,這次能參加想說會有機會親眼看到很多厲害的人,結果除了有看到講者外,還是跟在家看噗浪、臉書一樣…,總不能到處走問說你是不是誰誰誰吧…。
第一次親眼看到大澤木小鐵的演講,還有沒跟到他時代的 ptt 名人榮尼王,剛發現的議程影片跟相簿,不知道有沒有拍到我…。
node.js child_process send function
最近在用 node.js 寫一些系統管理層面的程式,有些複雜的工作需要 fork process 來做,主要的 process 用來跑 Web 跟處理主要流程,所以不打算做太多額外的工作。
var child = require('child_process').fork('./child.js');
在這裡實作的過程中想到一些設計,第一個部份是我的 child 應該設計成一個適合 require 的子模組,由他自己提供輔助函式,也由該模組 fork 自己。
var child = require('./child.js'); child.start(); child.stop();
var process; exports.start = function() { var cp = require('child_process'); process = cp.fork('./child.js'); child.send('message', {cmd: 'start'}); } exports.stop = function() { if(process) process.kill(); } process.on('message', function(msg) { if(msg.cmd == 'start') { // child process start // do something } });
由於 fork 出去的 child process 是一個子模組,所以對 parent 來說還是有一些事情想要呼叫 child 來做。依照習慣要寫一些匿名函式當參數,意思就是這個函式希望是在 child process 去跑,而不是單純用來當回呼函式使用,結果實際到這邊發現有些事情跟想像的不太一樣,process.send 當參數如果傳函式到 child process 竟然會接不到~。
仔細想想好像也不完全無道理,由於要 IPC,而 json 對函式的轉換好像本來就不太支援。
範例繼續延續上面的,這範例 msg 將收不到傳過去的函式。
.. child.helper(function(res) { // ... }); ..
var process; exports.start = function() { var cp = require(''child_process); process = cp.fork('./child.js'); child.send('message', {cmd: 'start'}) } exports.stop = function() { if(process) process.kill(); } exports.helper = function(handler) { process.send({cmd: 'helper', handler: handler}); }); process.on('message', function(msg) { if(msg.cmd == 'start') { // child process start // do something } else if(msg.cmd == 'helper'){ console.log(msg); // { msg: 'helper' } } });
這裡就讓我想到曾經看過一篇文章…撰寫乾淨的 eval 程式碼的技巧,因此就依樣畫葫蘆…就能動了!
只是要注意透過這種方式傳過去的函式所能存取到的變數已經不是表面上看到的了。而是透過 eval 執行時的 child process 的 context 了。
exports.helper = function(handler) { process.send({cmd: 'helper', handler: handler.toString()}); }); process.on('message', function(msg) { if(msg.handler) { eval('var handler = ' + msg.handler); } if(msg.cmd == 'start') { // child process start // do something } else if(msg.cmd == 'helper' && handler){ handler([1, 2, 3]); } });
node.js web 開發環境紀錄
webframework : express
npm install express
view engine : ejs
npm install ejs
dev-tool : nodemon 監控檔案變化自動重啟伺服器
npm install nodemon -g
css framework : bootstrap
db : node-sqlite3 :memory:
npm install sqlite3
yaml : js-yaml
npm install js-yaml
db-tool : adminer
flow control : async , step 一開始用 step ,後來看到 async 發現 api 設計的好一點~語意比較清楚
從挑選 package 的過程中真的可以觀察到好的 api 設計。