2015年8月19日 星期三

在 Asciidoc 輸出結果中加入區塊圖示

在 Asciidoctor 的工具輔助之下,一些預設就有區塊內容,像是「TIP」、「NOTE」⋯ 都能夠在輸出的時候被加上預設的圖示。只要在最開頭的設定值中加上⋯
:icons:font

就可以在輸出 HTML 的結果中,看到本來醜醜的介面被加上的圖示。

沒有深入研究是 asciidoc 本來就有的,還是 asciidoctor 加上的項目。總之,能夠讓輸出的結果更加賞心悅,是一件不錯的事情。

2015年8月13日 星期四

[Soma.js] 設定要注入的物件名稱

依賴注入似乎已經成為許多軟體框架的必要元素,它的概念仍然不易被人熟悉,但其方便性以及能夠帶給軟體開發的彈性是很大很大的。 Soma.js 是 javascript 的一個以 infuse.js 為基底開發的依賴注入程式框架(framework),依循它所提供的規則,可以自動偵測到建構式所需要的參數,使用 this 定義的物件變數,Soma.js 將在所有註冊在它身上的變數中,尋找相同名字的變數置入。

換言之⋯ 只要取相同的名字, Soma.js 能夠自動完成變數對應的工作。很方便,但也是其限制。要是一旦名字不同了呢?要是不同時期開發出來的程式,用了同一個名稱表示不同的名字呢? Soma.js 的對應機制是不是就無法順利運作了?

另一個會改變名字的地方在於程式的最小化,為了極致地減少程式碼所佔用的空間,會以較短的文字(像單一字母)取代變數名稱。如此處理的程式碼,很有可能會使得依賴注入失效。

同樣的情形也出現在同為 javascript 的 AngularJS 框架中,而 AngularJS 的處理方式,是在建立 controller, service 的地方,以陣列取代原先傳入建構函數的地方。陣列中列舉了每個注入引用的名稱,最後一個陣列元素才是建構式。由於程式最小化不會對字串進行處理,因此可以避免注入的對應出錯。

那麼回到 Soma.js 身上,它使用了 injector.createInstance 方法來建立物件,然而只接受一個參數,也只能是建構函數。它是支援在建構函數後頭增加其它的參數,依序作為建構函數的參數,不足的部分的由既有的注入對應機制處理、補齊。

不過,如果傳入的參數是要注入項目的名稱,會發現該名稱的字串,會直接作為參數傳入建構函數,而不是該名稱所對應的物件。因此,如果要傳入注入名稱的對應,不能使用 injector.createInstance 函數來達到。

最後的由其的基底 infuse.js 的文件中找到,它的作法是在建構函數上定義 inject 變數,其對應到建構時所注入物件名稱,經過實測的結果是能夠順利運作。至於物件內的變數要怎麼對應,這個部分就留待未來有需要再進行測試。

以下列個簡單的物件宣告⋯ (注意 inject 是定義給建構函數,而不是建構出來的物件上)
function MyClass(opt1, opt2) {
  // some code...
}
MyClass.inject = ['optName', 'otherOption'];
module.exports = MyClass;

2015年8月11日 星期二

在 asciidoc 文件中使用語法高亮

許久前照著範例輸入,卻怎麼也作不出上面講的語法高亮的效果。輸出的 HTML 還是「平平的純文字」,後來才發現,原來要在文件的開頭加上宣告,似乎這樣會多引入一些額外的 CSS  ,才能讓高亮的效果出現。

在主標題(文件最開頭,寫大標題的那區)加上⋯

:source-highlighter: pygments
這樣在輸入高亮語法時,就會被處理了。

除了 pygents 之外,還可以改成 coderay, highlightjs, prettify 。應該是其它幾種 CSS 主題吧~ 就沒有特別再去測試了,目前這種就讓我很滿意了。

語法的宣告很簡單,只要「[source,語法名稱]」就可以了。像是 javascript, php 這種比較單純,有一些則是要嘗試一下,像是我試了「shell, bashell, hash」三種,最後只有 bash 才被正確解析。

哪天有空再找找有沒有什麼表格,把所有支援的語法都列出好在未來作查詢。

另外,讓我有點意外的,也有支援 livescript 語法。算是一個驚喜吧~

[2015-10-5 補充]
重灌 mac 後發現,如果要使用 pygments 樣式的話,需要安裝 pygments.rb 這個套件。不確定在原來在打這篇文章之前就裝過,還是因為後來的 asciidoctor 安裝不會將它裝入。總之包含其它的樣式(coderay, hightlightjs, prettify)應該都要先安裝對應套件才能使用。

[2016-10-23 補充]
使用以下指令安裝 pygments.rb

gem install pygments.rb

2015年6月26日 星期五

Sinopia 試用

工作需要開發一些能夠重覆使用的 Javascript 模組,當然具有許多支援的 commonjs 與 nodejs 格式是首選,唯一的問題就是一方面希望能夠使用 npm 裡眾多的模組,但另一方>向自己所開發的一些內部使用的私有模組就不方便公開了。

花了一些時間尋找,看了 npm 那個要付費使用的私有模組庫,之後就遇到了這篇要提的 Sinopia。

Sinopia 並不是一個英文單字, Google 翻譯認為它是荷蘭文,是一種楬紅色顏料的名字。看不出和軟體本質的關連,就此打住不提。

它是一個依靠 Nodejs 建立網站的方式,建立一個能和 npm 套件溝通,提供自定模組的服務。當然,如果對它要求不存在於自身裡的模組,它會將要求轉向發到公開的 npm 主機。幫你把公開的套件抓回來。

除了抓下套件之外,也提供了在上面註冊帳號,讓自訂的模組也能使用 npm 既有的公開(publish)模組流程,將新的版本上傳。


試用了幾天之後,感覺還不錯,找個時間再試試看它能不能在 windows 上也順利運作。這樣平常工作的開發,應該會順利許多。

2015年6月5日 星期五

翻譯 LiveScript Style Guide

前陣子同事在說明專案要用到的 LiveScript ,提到網路上有個 LiveScript 的語法建議。個人還滿認同程式的寫作風格一致所能帶來的好處。因此就把網路的版本抓回來,由原來的 markdown 語法,改成另一個我正學習的 asciidoc 格式。

同樣把內容放在 github 上,也許第一次翻譯這種東西,多少會有所缺失。不過好歹也算是有個起頭,希望哪一天能夠幫到對它內容有興趣,但英文不好的程式同好。

翻譯的內容在這裡

2015年4月29日 星期三

fswatch 使用筆記

最近時常使用 asciidoc 的格式在建立文件,撰寫筆記。也練習使用 vim ,看看能不能如人家所說的「vim 成為最後一個學習的文字編輯器」。過程中遇到一個問題,雖然在 vim 中可以直接呼叫命令列指令來編譯出 Asciidoc 格式的文件。但是每次作點小修改,就得重複 :w 與 :!asciidoctor % 兩個指令,打久了很煩。
有沒有一個偵測到檔案儲存,就能自動替我執行 asciidoc 指令的方法呢?所以我找到了 fswatch 這個東東。

2015年4月22日 星期三

提醒、改變別人

騎車在路上,偶而會遇上一種特殊的「塞車」,明明機車等待區空上許多的位置,但就是會有機車只顧自己進入,沒有留位置給其它人。和汽車之間產生我稱之外「關門」的狀態,進不了等待區的車子,就這樣一台台往後面堆,輕微的時候只卡了兩三台,嚴重的時候超過十幾台。

每次看到都覺得,這種行為真是自私又白目啊!

幾次由汽車的另一側繞過進入等待區,默默觀察了這種人的反應,結果仍然是一無所覺。後面的機車似乎和他們一點關係都沒有。對於可以避免的塞車狀況,他們完全沒有意識到只要一個小小動作,像是往前一些或是向兩旁的一個車位,後面幾乎所有的機車都能進入等待區,而緣燈亮時,大家都能很順的起步、加速。不會有卡成一團的狀況。

同樣的狀況也發生在其它地方,像是有些人一進了電梯或是進到捷運車廂後就馬上慢了下來,甚至完全不動。而在後面要進入的人就被堵在門口。只是直覺得認為「我進來了」就什麼都不想了,結果造成其它人的困擾。也許本身沒有什麼惡意,但造成的困擾卻也是事實。

對於這種人,不會出聲去提醒。因為「人無法改變其它人」的觀念根深蒂固,所以會認為這個人的個性就是如此自私,與其花費力氣去提醒,不如用點精神找其它路走。因為我的成長過程中,沒有多少次由旁人教導提醒。大多的觀念是在生活的觀察和體悟得到。因此對於「教好別人」這件事,並沒有什麼興趣。把它認為是「本性的一種」,覺得每個人都應該自己找到對的答案,不需要由別人教。

教別人程式的時候,如果發現對方的學習態度不佳,或自以為是的往錯的路子上走。說個兩三次後通常就放棄了。教學的極積性會因為學習者的態度不佳而急速下降,最終進入「放生」的階段。理由是「既然自以會學夠足夠的東西,不需要我指導,那麼我也不白費力氣」。

態度夠好的留下,態度不佳的直接踢除,這種模式似乎曾經在其它地方看過。思考一下我找到了答案,就跟某些公司的老闆只想要現成的員工,即戰力就留下來,而沒有經驗的就踼掉重找。培養員工從來不在這種老闆的心中出現,那麼,我的思考邏輯,是不是和這種老闆沒有不同?

回頭審視過去的自己,並不是每一件事情都能夠「悟」出正確的作法。也受過其它人不少提醒,若是少了這些改進的建議,我應該達不到現在的水平,也沒有今天這樣的價值觀。以自身的經驗為例,人也許不能很輕易地完全改變另一個人的想法,但卻能夠影響價值觀,或是待人處事的方向。

如果自己都無法只依靠本身的力量找到每件事情的答案,那麼,又有什麼資格要求人去「自行成長」呢?就好像小時的聽到大人常說「長大就懂」的感覺是一樣的。

所以,如何去提醒而不傷人自尊,又能有效的傳遞訊息。以及如何篩選合適的人,把自己的心力用在對的人上面,畢竟這個世界不缺蠢人,那種人就真的救不了,也不必去救了。這些都會成為我未來人生中的一個重要課題。

今天並不是等待這個世界會變好,而是在自己能力所及的範圍內,去作一些些的改變。

2015年4月19日 星期日

改寫既有的程式


最近手上在處理一個改寫程式的工作,把既有的程式進行模組化,抽出成外部的函數庫。在整理的過程中,重新定義一些溝通使用規則,並且引入單元測試,讓之後的每一次修改都能夠由測試來確保既有功能運作正常。因為對於測試驅動開發的不了解,實作的過程當中吃了不少苦頭,單元測試的引入並沒有預期中的讓我思緒清析,反而讓我常常陷入混亂的狀況。

從前的程式撰寫只需要思考「如何實現功能」,而測試驅動開發則是要求先思考「如何測試功能被實現」,對於剛開始運用這種開發方式的我,花費的精力不是原來的二倍,而是三倍以上。因為想完測試方法後,還要再去思考「如何實現測試方法」。如可在可控制、模擬的環境下實作測試程式,和以往開發直接輸出測試用訊息不同,測試訊息是給開發人員看的,因此是「人工判斷」正確與否。而合格的測試程式,則是想辦法「讓電腦能判斷」,並且輸出「未來的自己看得懂」的訊息。


另一個不同,以往輸出測試訊息的程式碼,是混在主要的程式當中。久而久之,程式的行數會因為許多的測試輸出與測試註解而膨脹,變得較難以閱讀。因此測試程式因該獨立於主要程式之外,並且在輸出成果時被排除在外。因此除了必要的公開方法之外,還需要思考額外需要增加的檢驗方法,好讓測試程式得以觀察是否如預期般的表現。雖然可以利用改變方法的存取識別子或是介面來進行封裝,但是開放「只有測試才需要的公開方法」,至今仍然無法完全適應。

發現其它錯誤時,在測試驅動建議「先增加能捕捉到這個問題」的測試程式,然而自己常常習慣性地直接著手修正,往往修到一半才發現應該撰寫測試,又得還原已經寫好的程式,回頭寫測試。早就不知道自己在這一來一回之間,浪費了多少的時間。

講了許多缺點,但測試驅動給了我一些好處。有些時間精神狀況不佳,連自己都不太清楚自己寫了什麼,但由於寫好的測試把關,不至於讓寫好的功能被被弄亂,而「為了撰寫有功能的測試程式」也逼得我去思考各種可能讓程式錯誤的可能,相對而言程式變得更加穩定。只不過由於花費了大量的時間,會讓人不自覺得焦急起來。還許多一點的時間去熟悉,增加速度吧!

還是會持續使用測試來改變自己累積多年的程式寫作習慣,雖然過程式一定會遇到許多困難。只能不斷告訴自己要有信心,這樣子的付出,在撰寫程式時不斷的換位思考是值得的。接著,就是不斷的練習,直到對它的精熟能夠變成一種本能,期許未來的某一天,對於程式的撰寫能夠再提升好幾個水平。

2015年4月13日 星期一

模組化設定值的開放與否

有一次和同事討論程式的作法,發現兩個人對於「模組化」程式的開發有滿大的不同。我認為應該多使用預設值,只公開必要、儘量少的設定值。而同事則認為應該讓參數有多種的變化性,這樣開發程式比較不會因為某些沒有被參數含蓋的變化功能,導致得回頭的查看、修改模組程式。

討論到最後,並沒有達到完全一致的共識,因為彼此提出的論點和舉的例子都無法說服對方。當然尊重別人的程式撰寫風格的前提下,都沒有強迫對方要照著自己的方式走的意思。最後我採用較為折衷的方式來開發,作為這次討論的結束。
回到家又再思考了一遍這個問題,回憶一下從前是如何作下「儘可能少開放」方針的原因。很清楚的知道並不只是單純的跟著「封裝原則」的建議。而是有其它理由支持這個論調。還好,最後終於讓我回想起來了⋯

2015年4月4日 星期六

爪哇程式語言

話說 Java 程式語言,從我大學開始學習它,也過了十多個年頭。不得不說由它的身上得到不到的東西,畢竟它是「物件導向說明最常用被使用程式語言」,關於類別的繼承、介面的實作,後來的 MVC 開發方式到最近似乎每種框架都要具有的「依賴注入」,都是先在 Java 身上先發現的。只不過因為沒有一直持續跟著它的發展,導致於 10 個年頭過去了,感覺自己離它越來越遠⋯

在我心中的 Java 有種「老兵不死」的感覺,不時出現的新語言,似乎都都隱隱取代它的勢頭。由於不像 C 語言可以作為撰寫靭體之用,Java 的地位理論上是可以取代的,就靠著從前火紅的時候累積了大量使用它的開發者,與許多已被眾人使用的框架,使得在沒那麼多人拿它作主要程式語言的狀況下,還能維持一定的佔有率。就拿自己作為例子,每每以為自己已經「完成脫離」了 Java VM 的時候,它就會冒出來,告訴我現實並不是如此。

老牌的 IDE Eclipse 得在 Java 上運作,這個有許多外掛,但不見得總是能裝得好的東西,讓人又愛又恨,愛它的功能多,許多沒想到的事情都被它許多外掛包含進去了,恨的是它只要一出錯,就不知道要如何解決,只能怪自己的功能太低,不知道要如何對外掛程式除錯。

最近開始研究公司在使用的 Jenkins ,又是一個 Java 為基層技術的東西。還是掛在湯姆貓(tomcat)上,那個自己在用的時候履履當機的玩意兒,居然的被人家用得那麼好,不單功能穩定,連外掛的安裝、升級都整合在裡頭,自己搞的那個站,真的是上不了台面啊~

不過,真要問我會不會回頭去深入研究這門技術,老實說並不會。因為它經長大到不是我這個水平的人可以輕鬆進入的。許許多多成名已久的框架沒聽過,許多習慣的用法沒有人教,它的門檻高到不值得讓我學習,先學學其它能夠在更短時間掌握,能在工作中派上用場的東西吧!

Java 會有未來嗎? 我覺得,如果它入門的門檻依舊,我想之後學習它的人會越來越少,最後慢慢的像一些老牌的程式語言,只剩下銀行業這種不敢換既有程式語言的地方,還會繼續使用吧!

行動與拖延

經過一整天的「休息」,睡了大概超過十二個小時來補之前連續的睡眠不足。一大早吃完早餐後,強迫自己坐在電腦前面,處理拖了一個星期沒有完成的待辦事項。一個小時不到,完成了表列的工作。讓我有點吃驚。

吃驚不在於發現自己作事情多有效率,那些在清單上的項目,其實都不怎麼大。而是吃驚於能夠全部在一小時內完成的 4, 5 項工作,居然沒有辦法被平攤在一星期中完成。更令人在意的是,這種事情發生了不只一次,想起花了個把個月才學起 GitHub 如何貢獻專案,在一個下午完成了第一次送交,但又拖了許久遲遲沒有開始其它的貢獻。

我是一個很會拖時間的人嗎?我這麼問自己,想探究倒底是什麼原因讓這些「小事」被一拖再拖。完成待辦事項後,藉著休息片刻的時候作了一下反省。

貢獻在 GitHub 上的專案

這篇文章是用來記錄我從零開始學習 git,為了能夠貢獻一點程式到 gitHub 上。希望這篇記錄不單能作為學習的記錄,也能夠幫助到其它也想幫忙 gitHub 上專案,但是不知道如何下手的人。

先備知識

首先要先談談 git 的特性,和其它老牌的版本管理不同,早期在建立本地「沙箱(sendbox)」的時候採用 checkout 來得到某個特定版本資料,而 git 則採用 clone 的方式,將版本庫整個複製回本機上,因此除了要和遠端的版本庫同步的工作外,都可以在沒有網路的本機端完成所有操作。

要注意的是,本地和遠端的版本庫實際上是獨立的個體,依需求可以隨意連結或斷開關連。因此一個本地版本庫同時對兩個以上遠端保持關連是可行的。在推送(push)新版本的時候,只需要告訴 git 遠端主機是哪一個就好了。許多的 git 特性,都是由這個特性延申而來。

情境說明

先說說我的情形⋯

  • 在網路看到想要加入的專案,開放讓人貢獻程式碼
  • 但自己並沒有寫入這個專案的權限,既使有權限,也不知道應該如何作修改
  • 聽聞程式碼送交後,會有人進行審核,但找不到送審的地方,也不知道審核者在哪裡
  • 在討論區裡知道了有 fork 這東東,但版本庫 fork 回來,接著就不知道要作什麼了


關於我學習中間撞牆的詳細過程,不是這篇文章的細節。也許哪天有空再寫篇雜記吧!

2015年3月24日 星期二

第一次貢獻程式碼

數個月前立志要作個能貢獻程式碼的工程師,除了回饋之外,最主要還是練習技術。當時選了 mozilla 作為目標,選擇了最簡單的官網內容維護的 github 專案。沒想到才一開始就卡住了,自以為 hack 程式有一些經驗的我,完全看不出來程式碼是如何被貢獻、審核通過的。

在群組中發了文,只聽到「fork」這個關鍵字,但仍然搞不清楚它究竟是在作些什麼,因此決定先把 pro git 那本網路書先看一看,找找有沒有說明這部分流程的內容。

經過兩三個月斷斷續續的看,終於讓我試著抓回一個 issue ,修改後發出所謂的 pull request ,也在一次回饋修正後,被順利併回主幹,放上網路。在興奮自己也能夠對真實世界有所改變之餘,也驚訝這一連串的工作,就在一個下午的短短數小時內完成。

為了這幾個小時內,實際工作不到 30 分鐘的事情,花費了我幾個月的時間去學習。只能說,自身的能力還有許多地方得趕緊加強,不然很容易一下子就被這個世界洮汰了。

2015年3月19日 星期四

用 Sublime 建置當下正在編輯的文件

為了避免那些常常出現,還看不懂的 Node.js 語法干擾我學習前端技術。打算狠下心來花時間對 Node.js 作點深入的了解。首先要先在同樣也在學習中的 sublime 進行設定,可以在編輯器中以快速鍵的呼叫 Node.js 執行正在編輯中的檔案,來加快學習的進度。Sublime 既然被稱作強大的文字編輯器,那一定有相對應的功能吧!

開始研究

sublime 可以由選單 Tools > Build System > ... 的列表找到內建的幾種建置模式。可以手動選擇,或是讓它停在 Automatic 的選項上,由 sublime 自行判斷。當選好或被判斷出適用於特定種類建置方式時。 Tools > Build 選單的狀態會是「可點選」,藉由點選它或是以快速鍵 「Command + Shift + B」或 F7 執行建置的動作。

不過 Node.js 不在預設支援的建置模式中,所以需要自行定義,由 Tools > Build System > New Build System... 選項,會開啟一個新設定檔,讓使用者可以自行定義。

2015年3月17日 星期二

學習 Unit Test 之三

在開發程式中使用單元測試,「封裝」這個概念似乎和單元測試相衝突。

封裝的原則是把程式邏輯隱藏,只保留必要的屬性、方法對外公開。這個基於保護的原則在單元測試中需要「觀察改變」的需要相互衝突。單元測試為了測出邏輯是否正確,就必須有對應的類別方法能夠觀察、確認數值的變化是否符合預期。將方法 public 變得無可避免。

在滿足單元測試需要的公開方法之後,希望達到「封裝」的目的,不要曝露出過多實作細節。就需要有個「過濾」的機制,這個時候「介面(interface)」就可以派上用場。其它程式只知道介面定義的方法,而不知道實作的類別額外公開的方法,原來為了單元測試的需要所開放的程式碼,就被介面所隱藏,以此達到保護邏輯的目的。

回過頭來看看之前所學,難怪看到的程式原則中,總是寫著「對介面撰碼」而不是「對父類別撰碼」。而程式碼中的註解文件(xDoc, 如 JavaDoc)中,也具有能將方法標注為「隱藏」的語法。看起來可能都是由於單元測試的發展而演化而來的吧!

2015年2月19日 星期四

學習 Unit Test 之二

萬事起頭難,Unit Test 也不例外。在練習使用的過程中,「要如何開始」這個問題困擾了我很久。手上有的是剛寫到一半的值物件類別,不能確定是不是應該替他們寫測試程式。只是單純的檢查「資料記到變數裡」,沒啥意義。經過一些測試,慢慢抓到一些模糊的感覺,在這裡作點記錄。

回到程式的本質,就是處理資料。所以撰寫測試程式就應該是確保「資料被正確地處理」。所以測試程式的輸入和輸出,應該是不一樣的。既使只是數字變成字串,或是物件變成 XML 格式字串都算是改變的一種。當然輸入、輸出的改變可能是數值計算、整理作為 API 回傳值或著是分析、篩選出滿足條件的內容之類,總之,就是「有處理,就有測試」這樣子原則。

所以,一開始建立值物件的時候,不需要寫測試程式。在撰寫由檔案/資料庫讀出、建立值物件時,就要測試來源資料和值物件的內容。當確保了值物件的初始建立後,就可以拿這些建立好的值物件來進行其它運算,分析的工作。這樣,不用在測試程式中一行一行的打程式建物件,把更多的時間用在思考如何驗證結果,撰寫邏輯規則。

沒有資料,就很難進行的模擬的測試。反覆使用程式碼一個個地建立物件,足以消磨一個人的心。而且一旦物件格式改變,那麼需要異動的程式碼可能也會隨著專案發展變多。所以由統一建置的「工廠」來提供資料有是需要的,能夠快速複製新的版本,再修改來滿足其它測試需要。

所以,我覺得測試驅動的程式發展,應該是由值物件,以及建立讀取外部資料來產生值物件的類別開始。接著才會有許多不同變化的資料組合來模擬不同情境。

2015年2月16日 星期一

重構時間

最近回頭看看自己的工作清單,發現有許多事情常常會一拖再拖。不知不覺之間,一兩周就這麼過去了,感覺真是不應該。開始思考發生了什麼事情,讓事情被拖延,或是問題實際上出現在事情的安排上,讓它們本身就具有「容易被拖延」的特質。

觀察了每天時間分配上,有許多片斷但無法控制的時間花費。像是在通勤上遇到塞車,和人相約的等待,回到家等水開,等肉退冰。這些時間不是完全不能預測,卻很容易被人遺忘。當然時間是公平的,把這些時間抽出後,讓我突然發現每天回到家裡的時間少得可憐。如果再加上臨時起意的出門、聚會之類的,感覺上能夠讓人作事情時間實在是不足。

不過,再去看看每天作的事情中,發現有趣的是,一些「真心想作」的事情常被擺著沒動,反倒是遊戲,尤其是手機線上遊戲的進度無論再怎麼忙,似乎都能維持的進度前進的狀態,不會一擺擺上了兩三天。自問自己不是一個容易沈迷遊戲的人,反而是一個無法對遊戲「很認真」的人,所以要作一出「放著遊戲不玩」的決定並不困難。

難不成「不會太認真」,是造成進度能不能持續的原因?當然不是囉!但是太認真,反而會讓事情不容易開始。回想要開始「認真作」一件事情的時候,常常會思考它將需要一段能夠專注、不被輕易打擾的時間,最好還能夠進入所謂的「沈浸」狀態。但是一天之中,會有幾個半小時甚至更長的時間,能夠專注作件事情呢?所以,那些零散破碎的時間反而被「玩個三五分鐘就好」的線上遊戲被佔滿了。

「重構」、「單元測試」的想法又浮上心頭,能不能把想要作的事情,切碎成三五分鐘能成完的片斷?當事情能夠片斷進行,並且能夠容易地在下次接續進行。我想才是能夠滿足現在大多都是破碎時間的合理安排吧!讓想作的事情持續有進度,不會後輕易地被許多小,但不那麼重要的事情瓜分光。

2015年2月13日 星期五

想試著把「重構」用在文章寫作上

我想要寫一些文件,想把自己的一些片斷想法記錄下來,集結成有順序的文章,這樣的想法其實在大學時代就有了。

作為一個新手,所以了解也知道新手在想些什麼,想把解決問題的想法與方式留下來,因為當我不再會犯新手錯誤的時候,我也或多或少地失去了能夠同理新手的心。能夠把這個時期的一些東西記錄下來,我認為有機會能夠幫助未來哪一天某一個新手早一點入門,那麼這就算是有意義的事情。

不過讓人覺得挫折的是,我從來沒能夠好好的把一系列的文章寫完,心中的熱情往往在持續了一兩篇文章之後就漸漸冷下來,反思其中的原因,最主要的是想法隨著時間不斷改變,已經不是一開始構想的架構所考慮到的,因而硬是把新想法塞進不合身的框框,就足以消的磨太多太多的熱情。

回頭想想,這種一系列文章,可能不適合我這種想到什麼打什麼的人在 Blog 上進行連載。還是以單篇,彼此沒緊密連結的內容比較好一些。真的想要弄個有系統的,還是得另外再花一些功夫去作整理。

忽然我發現,原來寫文章,就跟寫程式一樣。耦合度不要太高比較好,越低的耦合能夠給予更高的彈性。因此決定對於一些打了,還不完整的文章進行「重構」,來看看會發生些什麼事情。也許未來還能分享一些所謂的「文章重構」心得。

2015年1月28日 星期三

改網站版型

發覺原來的網站版型真的不好閱讀,決定最新找幾個合適樣式先套用。之後再找時間把舊文章裡的程式碼樣式調成回來。反正最近的文章應該不會太多和程式碼相關,就先這樣囉~~

專案開發自勉

作為一個程式人員,總想著能利用程式來作些自己覺得有趣的事情。作個能 Open Source 的專案,在心中已經萌芽一段時間,卻一直未能正真進入開發階段。到咖啡館看書的時候,剛好聽到鄰座的教授和學生討論專題,心有所感。綜合之前看過的一些文章,將當下心得記錄下來。
相信工具 讓事情開始進行

相信工具 讓事情開始進行

隨著接觸過的專案越多,考慮的點也跟著的變多。開始的時候滿足於自己能夠「顧全大局」的成就感,但是也漸漸發現自己撰寫程式的速度不如以往。雖然寫出來的程式品質有跟著提高,但也隨著專案進行,發現許多當時考量的東西,最後不是沒有用到,就是需求改變而不敷使用,時間在無形中被浪費掉。倒不如早早開始動工,相信以依照現在的方法和工具,都有機會能夠將偏離的方向導回,沒考量到的部分予以補齊。

當然光是「相信工具」是遠遠不夠的,還要去學,去實踐那些工具和原則。像是不斷確認開發是朝著目標走,以此定義單元測試,並在發展的過程中反覆進行程式碼的重構。否則,只是單純的盲目前進,以及天真的期望哪天醒來,所有的問題會自然消失。

真正了解工具的背後意義,相信它們能夠幫助修正問題,然後就開始實作吧!不斷讓這些工具加入,讓事情發生!

解決問題 遠比用新技術更重要

無論一台機器功能再多,性能再好,如果不能用來打電話就算不上是一台手機。當為了追求的新的技術、新的管理方法、新的設計流程,一旦遺忘了根本的初衷,那麼產出的只一個堆積許多功能的四不像。一個連自己都不知道有什麼價值的東西,當然難以得到其它人的認同。所以產品的定位,想要解決的問題以及讓使用的人得到什麼價值,遠比用哪一種技術重要得多。

不管是 Scurm 專案發展、UML 圖或是 Big Data 、RWD ⋯⋯等等技術,都是為了解決在產品開發上,會遇到的一些問題。但也大多止於「產品開發」上,而不是「滿足客戶需求」或是「創造價值」。雖然學習各種新技術,能夠減少一些時間的無謂浪費,增加一些新的可能。但絕對不應該將所有的焦點都放在「新技術」這個議題上。選擇、引用,甚至是學習新技術,顯然比研究客戶問題、提出解決方案要簡單、不費腦力。看過一些人沉浸在新技術的堆疊,近乎在逃避解決客戶問題的責任。必須引及為戒,不能陷到這種狀況中。

片段時間 就開始 重要的是方向定下來

「我有想法,但沒有時間,找不到適合開始的時間點。」這個問題困擾了我許久,總是在一個念頭的開始,伴隨著公司加班,或是親友或自己的事情干擾,導致最終念頭仍然只是一個念頭,還是沒有被實現。因為如此,我的在職碩士,花了我整整五年的時間才完成,回頭來看還滿有趣的。前兩年我順利的完成所有的該上的課,沒有一科被當或出現危機。然而一個碩士論文卻花了我三年,而實際用在製作我的畢業論文的時間,大概才半年,那忙亂的半年中產出了一篇足以讓我畢業的碩士論文。而那半年之中,還有公司的專案趕工、上線等壓力在,常常強迫自己早點睡,六點起來寫一點文字,最後組成整篇論文。

事實上,我在完成論文的那個時段並沒有比較輕閒,所有的文字都是在片斷時間中撰寫,最後一兩週才抽出比較完整一些的時間去順槁。因此由小看大,表示別等著完整的時間才開始想作的事,既使只是片斷的工作成果,也能夠積少成多讓自己離目標更近一些。有一個明確,短時間不會被改變、大幅調整的目標,就可以開始動工了。大原則不變,其它的東西一面作一面微調方向就可以了。讓事情發生!比大量的規劃卻零產出有意義得多。

需求優先 別卡在細節

一個功能能夠有多少種變化?使用者操作上會不會看不懂?需不需要防呆機制?網站的安全性夠不夠?效能能不能讓主機承受上萬人同時操作?雖然這些問題對於一個成熟產品來說是必要的,需要常常去檢視,研究尋找更有好的解決方案。不過對於一個剛開始的計劃而言,這些都太遠了,不值得讓它們佔用本來就不太夠用的腦袋空間。人們可以忍受要等上一兩秒才算出報表的統計程式,但不能接受一個全世界最快,但只能算加法減法的計算機。

專案的目的是什麼?最核心想達成的功能為何?什麼是達到功能的最小可檢視流程?這些才是最需要常常問自己的問題。不斷的探索使用者遇到的問題,嘗試想出各種滿足需求的可能,去驗證它,分享它,再回頭去看看和大方向是不是一致。等到組合成一個夠完整的解決方案,再回頭去思考其它和需求比較沒有關連的問題或是優化產品的效能。

如果擔心一開始的程式規劃無法面對未來的變化,那就要在每一次的開發流程中,導入重構的技術。去相信重構的技術能幫助我們重新設計程式規劃,然後,開始進行吧!

第一個版本在哪裡?prototype?

產品終究是要給自己以外的人使用,所以,可展示的版本,或稱之為產品的原型,是發展的里程碑。最終目標太遠,往往會讓人失去想要達成的動力。最好能夠早一點作出能夠給別人看的原型產品,一來目標較近,有機會能在燒完全部熱情前完成,二來可以聽聽其它人對於這個東西的看法,能夠早一點作出修改,或是增強部分功能的力度。總之,都要比自己閉門造車完成後,才發現不合交通法規上不了路的好。

也許現在的想法有一些未盡理想之處,不過就像前面所說的,總是要先起了個頭,才能知道要如何改進,才知道對的方向在哪裡。

2015年1月24日 星期六

MVC 框架 - 容器與內容物的分離

我會的程式語言種類並不是很多,對於 MVC 框架的了解也是最近研究測試與重構後,才有了更深的了解,發現有一些自己與別人對於它的誤解,在這裡作作記錄和分享⋯

Context 物件

記得是在學習 Andoird 程式的時候,第一次接解觸到「Context」這的單字,在一些書本不是翻作「上下文」或是省略不提。花了許多時間嘗試理解,最後終於在字典外的一個討論串手有了一些些的了解。如果要我翻譯它的話,我會翻作「關連」。

在 MVC 框架中,會有一個作為組合所有元素的「容器」,在命名時常會使用「Context」這個單字,它的作用就是讓本來沒有交集的元素,相互之間能夠互動,讓值物件能夠被注入到的需要的物件中,讓發出的事件能夠被偵聽的物件收到。維繫這些元素之間互動關係,就是「Context」的責任,所以我認為翻成「關連」會比較好。

在 MVC 的概念中,每個元素都是獨立的,不知道會知道其它元素存在。因此可以更彈性地抽換、組合來滿足需求。而在這些元素之外,需要有個「容器」來裝它們,由於容器的程式實作通常已經被框架的開發者作完了,通常只需要繼承並覆寫需要改變方法,或是 new 出物件後,指定需要包含的類別有哪些,它們之間的關連就會被建立好。

在 Java 裡的 spring 框架,甚至只需要在設定檔指定套件的範圍,就能夠直接作「掃描檔案,判斷類別是否為 spring 元件」的工作,增加新元素變得更容易,也不容易漏了什麼關連。雖然這並不是 spring 框架的特有的能力,不過是我在其它程式語言的 MVC 框架中沒看到的特色。

2015年1月19日 星期一

[Robotlegs] Actor 找不到 IEventDispatcher 的依賴注入

今天嘗試將 FlexUnit (1.5)和 Robotlegs 兩個 framework 結合在一起,作為重構程式碼之用。開始還算順利,當我把假類別置換成整理過的實際類別時,測試回報「找不到 IEventDispatch 的 Inject 資訊(如下)」,造成無法開始撰寫第一個測試案例。

Error: Injector is missing a rule to handle injection into property "eventDispatcher" of object "[object TestingLogic]". Target dependency: "flash.events::IEventDispatcher", named ""

在程式碼中查了半天,就是沒有看到有任何需要 Inject 這個類型的資料。因為  Actor 是 Robotlegs 的既有類別,理論上應該不會出現缺少需要的 Inject 物件才是。所以中間一度懷疑是不是之前的同事去手動調整了的 Robotlegs 的核心程式。花了一點功夫,把 swc 解壓縮來看看,也看不出來有什麼異常⋯ (中間還查到另一段無關這次錯誤的歷史程式)

最後把焦點拉回到 Robotlegs 本身,因為 Context 本身具有發事件的能力,因此作為其 Model 元素的 Actor ,應該也是利用和 Context 一樣的物件來發事件,否則 Context 就得偵聽一大堆 EventDispatcher 所發出的事件。所以缺少 IEventDispatcher ,應該和 Context 有關,其中最可能的,就是在初始化的時候所帶入的 DisplayObjectContainer,這個類別有實作 IEventDispatcher 介面。

最後在這個地方的參數加上 new MovieClip(),就解決了這次的問題。也發現到原來在 Robotlegs 的事件發送,是依靠建構時傳入的元件,而不是由自己實作 IEventDispatcher 介面。不知道這個機制在 2.x  的版本有的改變,有機會再去試試看。

作個筆記⋯

2015年1月17日 星期六

學習 Unit Test 之一

為了重構一個專案既有程式碼,開始了重構的學習歷程,這些文章會把一些學習與實作中的心得記錄下來。剛開始深入研究的自己,也估不出來會用上多少篇文章來記錄,就估且用數字來的編號,等到未來遇到更好的文章命名方式,再回頭調整吧!

開始的篇章想先記錄的,是花了一兩個星期看完 Apache FlexUnit 指引之後的感想。作為一個成名已有兩三年以上的技術,在學習上並沒有我想像中的那麼容易,一些套件的名稱有了改變,原有的範例程式不能執行,或是舊版的函數庫已經找不到,得所有函數庫都升級到最新的版本。作為一個已經一段時間新東西可討論的技術,往往看到的都是數年之前的文件,當遇到問題,無人可問的無助感在心頭揮之不去。

所謂的「單元測試」,就如同其名一般只針對「單元」進行測試,所以雖然它也能夠發展成為某些「功能測試」的工具,但並不是它的設計初衷。從前的我一直認為「單元」只是表示它的測試「能夠細到每一個小單元」,並且對於每一項測試並不保證順序,以及每一次的測試都需要重頭執行測試項目初始化感到不解,認為它會造成在測試上的一些不確定性。

2015年1月16日 星期五

越是學習,越是覺得自己渺小

又換了一次工作,新的環境有比較多的時間,讓我能夠好好地對一些技術作深入研究。這在之前的工作中,還沒有發生過。往往是連續的專案進度壓力,或者是不斷需求方向改變。技術的理解往往停留在「能用」但是「不精熟」。

工作上需要用到 Flash,所以就把數年前想學習的 FlexUnit 拿出來學習,花了大約一週的時間看完放在 Apache 官網上的教學文章,總算是建立了一個能夠自動化測試 Flash 程式的環境,不過在回過頭要來修修手上的程式時,卻發現困難重重,不知要如何下手。因此又開始研究起所謂的「程式重構」是怎麼一回事。

重構是讓程式變得「乾淨」的步驟之一,而測試則是確保重構的過程中,仍然維持程式應有的功能。在看相關的資料的同時,發現了許多從前遇到問題的解法,程式架構與設計原則也在重構的重新詮釋下有了新的風貌。收起了自以為已經了解程式的自滿之心,同時也開始漸漸不能接受自己原來寫的程式,就像資料中提到的,我的程式已經長到一個難以擴充功能,也難以讓其它人理解的狀態,而天真的我還認為這是程式應有的風貌。

當然,就我那個時候的程式水平,會有那樣的想法並不意外。學習過程中,想法的被推翻與在連續的錯誤當中試著爬起,都讓人多多少少感到鬱悶,但在回頭看看自己的成長,已經有很大的進步,還是滿讓人興奮。終於能夠再接近高等程式應用一些,達到心中理想的境界。

興奮之餘,也發現到自己的渺小,能力的不足,在這個年紀才這樣的水平實在是不夠。既然現在有了時間可以研究技術,就得好好的把它們都補回來。充實自己的技術,才能發揮出更高階的價值,有資格的得到更多的薪水。畢竟,年紀不小,也到了支出要開始直線上升的時期了,得快快把自己準備好。

希望囉~在這系列的研究工作之餘,也能夠把所學多分享出來。也算完成多年前就希望作到的事情。