2012年3月30日 星期五

[嘆世間] 七原罪 - 貪婪

這篇,來自文林苑都更案

---蓮花指(?)分隔線---

這篇,沒有要談內幕,沒有要談八卦,沒有要談是非。
也沒有要聊那篇影片的世界觀和背景。
更沒有要宅Vocaloid和還是宅悪ノP。


只是要抒發一下"貪婪"後的心情

喜歡這段影片,除了它好聽之外,更有影響力的是,它真實的很讓人痛心


這陣子常常聽到很多很匪夷所思的事,像這件都更案,再配上這篇這種都更面臨到的解決方案,要我怎麼相信台灣發生的這一切不是官商勾結?要我怎麼相信這私底下沒有利益流通?

什麼時候民眾開始不相信政府所做的一切是為了百姓?
把一些拿黑錢的高官和炒房地產的奸商殺掉,台灣會不會變得比較好?
機械公敵(I, Robot,威爾史密斯主演)裡演機器人方的理念,是不是光明未來的唯一解?
已經污穢不堪的世界,究竟是素還真的重構理念,還是寂寞侯的天下止武能夠讓社會永續生存?
難道,真的非得出現天罪,重新洗牌可以?

善良、人性、公理、正義…在面前,彷彿不值一提。

有權位的人,敵不過貪婪的惡魔,形成社會亂象。
這種事情在歷史已經不斷地再重演,也說明了後果都不會好到哪裡去。
但是也從來沒停下來過。

還對世界懞懂無知的時候,學校教我們:做人不能貪心,要對得起自己的良心。
現在有誰能夠貫徹這一點?良心都在哪裡?
有利益衝突的時候,有誰記得自己的所做所為會害死別人?
有利益衝突的時候,有誰看到自己的一念斟酹會傷害到別人?

恐龍法官、幫助罪人脫罪的律師、不食人間煙火的人本組織……
當你們做出足以撼動社會信任度的決定和動作時,要人怎麼能不相信背後有利益關係存在?
各個都是高知識份子,唸過的書比我多上十倍有餘,為什麼小學教的道德觀念都忘了?

是不是優渥的環境,就會讓貪婪原罪更加醜陋地浮現出來,而且還能振振有詞地說「這就是成長,這就是社會,這就是現實」?

有一則末日預言說過:在1999年時,惡魔會降臨,人們會張開雙臂歡迎它。
曾經我一度懷疑這個惡魔是指Internet(Internet雖然讓人與人之間的距離更加貼近,但卻失去了隱私和在現實生活中正常溝通的能力)
現在我開始懷疑是貪婪人性所帶來的社會亂象。

末日,也不定是指天災。
誰知道會不會是憤怒的人民直接以武力對抗這不公不義之事?



莫非這篇是假抱怨真推廣?

2012年3月29日 星期四

[傻眼系列] 大學免學費?要不要乾脆水電瓦斯都不要錢?

神啊,我有罪。我不該犯賤去點新聞出來看。

但是這幾個新聞實在.....讓我傻眼,完全不知道該說些什麼。讓我懷疑台灣的言論集會自由是不是放縱得太over了。

學生團體反漲學費 「還應調降」

學團到教部抗議:學費應逐年調降

---來源前言分隔線---



假設真的有這回事好了,不是媒體虛構的。


我先表示我的立場:我不贊成學費免費或調降。
台灣高等教育的學費已經太便宜了,比起其它國家,已經便宜太多太多了,便宜到養出一大群態度不好、專業學不好,又不願意吃苦耐勞的廢物,還不知道自己正在學生和出社會之間的關鍵點中浪費自己的時間。
再更便宜下去,只會讓學子們越來越不懂得惜福,不知道教育資源得來不益(私心認為就像台灣民眾普遍不知道醫療資源得來不益),不知道自己存活在被學校保護好的世界裡。過個五年,看還有沒有哪個畢業生有像樣的競爭力。
我所謂的競爭力,可不是在召喚峽谷的競爭力。

你知道那些學團的嘴臉像什麼樣子嗎?
你有沒有看過小孩子在媽媽的旁邊吵著要糖吃?不給就大哭大鬧,然後引來一堆旁人的白眼。
學團吵著跟企業要錢、靠夭大家都不給幫忙,然後又怪教育部在這時候漲價落井下石。
我是不知道有沒有人覺得那種小孩很可愛啦,我是覺得那很吵很煩。

讓我告訴你一件事:大學生的時間很值錢。那是一段可以學會很多東西,時間又很自由的時光。你可以利用你的空閒時間做任何事。你可以去參加抗議活動、你可以打工、你可以在地上吵著喊沒有糖,你也可以多看兩本書、多寫兩行Code、多練文筆、多看看世間百態,還可以在艾澤拉斯冒險、在召喚峽谷殺人。
這些時間,出了社會就不一定會有了。只要你願意,你可以多充實自己,讓企業注意到你。



---想太多分隔線---

理想中,學生、企業、學校、政府等立場,可以做些什麼呢?
我一向推崇賞善罰惡,也認為嚴竣的競爭環境可以造就一流人才,淘汰無能廢物。所以,學費要調降要有前提:廢物都去死。我可不想讓我自己繳的稅來補助沒用的廢物來完成高等學歷,畢業之後卻又什麼也不會。

無論是用獎學金、或是比較直接的方式來幫助努力不懈的學子,我覺得這是一種投資,付出多一點時間和成本來培育一流人才、減少不入流的傢伙,讓不久的未來,這些學子都能成為可用之才,沒有什麼不好。
至於其它只會浪費糧食的學生,我覺得去當兵來報效國家說不定會好一點,總之不要出來危害社會,形成社會問題。

學校和企業可以多規劃合作案。企業可以和學校或系內合作,提供實習機會,讓學生能在出社會前更早一步接觸業界所會面臨的壓力和所使用的技能。讓學生在學校裡的所學能夠快速和業界接軌。企業就不會三不五時靠夭「應屆畢業生還要花一、兩年的時間從頭訓練.....學校在衝三小」之類的。企業也可以藉此機會觀望一流人才的流向,使其在畢業前就有更好更穩定的出路。

重點當然就是學生啦!學生要自愛,你們能夠用很便宜的價錢得到許多教學資源,幾乎都是靠台灣人民所繳的稅來支撐著的。正如前面所說:你們的時間很寶貴,多看一本書、多寫兩支程式就是為自己儲備更多競爭力。所以一天不要浪費四個小時到八個小時的時間在喊歡迎光臨和搖飲料,更不要花四個小時到六個小時掛facebook上面的遊戲和獵人頭。
(一天花一個多小時在玩遊戲抒抒壓我自己倒也常幹)
相反地,除非你有確定想做的事,否則最好盡可能地充實自己,並且和外面的企業廠商接觸實習機會,或是乾脆做一些你們可以和三五好友同學能夠一起做的小案子,讓你的所學能夠在某些程度地應用在業界,一方面讓你學起來不會無聊;一方面接觸出社會後所會面臨到的工作壓力。不只是錢,還有更多的是責任和時程,和面對一大群比你老的傢伙報簡報的心理壓力。

當然,在學的過程中有想做什麼事,需要把握當下來去做,就不要懷疑,沒有殺人放火走私販毒就去做。青春和機會是不會再給你一遍的,不要留下遺憾最重要!愛你所選



---訐譙分隔線---


啥?你說這太理想,台灣不景氣不會有這種環境?
關我屁事!真要想做不會自己想辦法去找機會哦!連這東西都要我幫你鋪好路,那要不要我幫你打手槍?

2012年3月22日 星期四

[嘴炮軟體] 可用性(usability)

這篇不談測試、數據、程式…等這些資訊相關的玩意兒,單純聊一下可用性

可用性 (usability) 是什麼玩意兒?很重要嗎?可以吃嗎?不考慮它會死人嗎?
ISO對usability做出以下定義[1][2]:

The extent to which a product can be used by specified users to achieve specified goals with effectiveness, efficiency, and satisfaction in a specified context of use.
(這個也可以定義?不知道該說嚴謹還是無聊)

簡單來說,可以將它視為使用者用某樣工具達到一個特定目標的容易程度,即對操作介面感受到的有效性(是否能夠達到使用者的目的)和效率(達到目的所能減少的時間)
看吧~ 使用者介面 (User interface)。
根據研究和分析,可用性包含了以下幾個因素[4]:

  • Learnability: 使用者在第一次用就能學會的容易程度
  • Memorability: 經過一段時間之後再重新使用這UI還能熟練操作的容易程度
  • Efficiency: 使用者能用這個UI多快完成任務
  • Errors: 包括使用者有多容易出錯、錯誤有多嚴重、以及有多容易從錯誤中回復回來
  • Satisfaction: 使用者用這個UI時會覺得愉快的程度

上面的list直接引用第4篇的ref,該文裡有針對上面列出的因素進行說明和提出案例,裡面寫得很詳細,值得一看!

總之,它可能不是一套軟體、系統的核心技術,但是會直接影響到使用者的喜好厭惡。

---可用性理論雜七雜八分隔線---

知名的大公司做出來的產品,肯定都對可用性下過一番苦心。

說到這個總少不了扯一下Apple,賈伯斯對這個東西就真的很會。
我覺得與其說他會設計,倒不如說他很重視使用者在操作的當下所得到的感受,講得難聽一點,某些程度來講算是掌握使用者的情緒。只要能保證使用者在操作產品的當下心情是愉悅的,就一定能賣!
另一個直覺想到的就是微軟。雖然微軟做出來的產品好不好一直飽受爭議(看看那IE56789精美的相容性),但是不得不承認他們在做使用者介面真的做得不錯。
至少,電腦一開機進到桌面以後,不需要經過什麼訓練就能直接操作OS或其它軟體,做一些基本的操作都可以很直覺,包括像他們的Office系列,要用、要學都可以快速上手。
主觀認為,Linux的桌面開發了好一段時間,才有一點像樣的成果,前幾年的Linux就算有桌面也不是很容易使用....(這裡不要扯"Unix系列操作command line和open source coding才是王道",我沒有說Linux功能不強,但是桌面和相關軟體的可用性比不上微軟是事實)

其實我個人對可用性的標準沒有真的很高,稍微摸一下,能夠操作一些基本的功能,能滿足普羅大眾的需求,就差不多有80分了。所以,大部分的套裝軟體,能賣錢的、能存活的,就我主觀上、時代經驗的客觀上,可用性應該都不會差。
想想看,如果你接觸到一個功能很強大,但是讓你摸不著頭緒該如何使用的軟體系統,你會不會想立刻讓它從你的桌面上消失?如果你還有其它可能滿足你需求的替代品,你會不會拿用替代品來玩玩,然後讓那個強大但是每次使用胃都會痛一次的東西從你的記憶裡刪掉。


連操作都不討喜的軟體,沒有人喜歡使用,怎麼會賣錢?一天到晚做出這種軟體的公司,怎麼會存活?

不過這句話在台灣軟體產業界就會活生生被打臉。
在台灣,使用者介面設計師這種行業超級少,需求量比起一般的程式設計師,還要少少少少。我不確定到底是軟體廠商不知道可用性的重要,還是根本連可用性這三個中文字 (the word "usability") 都不會寫,搞到後來都是一般的工程師在畫畫面(還稱不上是設計咧!)

使用者介面設計之類的學問,歷史大概和極限編程差不多悠久,還有很多實務上的高手和學術界對此做了非常精闢中肯的分析和指引。我總覺得台灣長久以來對軟體 + 電腦的觀念就一直停留在自動幫人完成複雜作業的機器,使用者介面感覺就都是勘用就好,停留在台灣早期"國難當頭、一切從簡,有就好!"的風格,又他媽的跟簡約風那懂有質感的風格不一樣。
結果當然就變成剛拿到開發出來的軟體的時候都不會用。有些時候是連點出來那個畫面是要做什麼的都不曉得,有些是看到那個畫面後直覺地去操作,結果得不到想要的結果,無論如何,這都是可用性沒考慮清楚所產生出來的結果。
最機掰的是使用者還習慣了。



謎之音如是說:再教育訓練就好啦~


嗯,去你媽的。
軟體做出來,是為了滿足使用者的需求。做了一套使用者都不會用的軟體有個屁用?
軟體做出來是讓使用者用的,不是做出來教他們怎麼用。
所謂的教育訓練,應該是把一些軟體系統裡的細節講清楚說明白,而不是講一些核心功能面的東西。
你有看過一個拍賣網站有在做教育訓練教你買東西的嗎?你有看過facebook有派人去你家教你怎麼在你的friend list裡加入你的朋友嗎?你有看過Google開發的相關軟體有在特別發表什麼演講來說明Gmail還是Google Map怎麼操作嗎?
以上例子都沒有所謂的教育訓練,那你會用嗎?
希望你不是那個在我facebook裡看到這篇文,又常常講"再教育訓練就好啦~"的人材。

---抱怨結束的分隔線---

在約耳趣談軟體一書裡,約耳有提到他的約耳測試12步驟中的最後一個「走廊使用性測試」(hallway usability)[6],指的就是在走廊上隨意抓五~十個路人進來試用你做出來的程式,並且觀察他們在操作系統時所遇到的問題。如此做法,可以抓出約90%的可用性問題。
還放出一個網址讓人免費查閱他自己寫的線上使用介面設計書[7],真是貼心!

其實保持著一個重點,做出來的UI就不會太差。"Eating one's own dog food" (吃自己的狗食) 就是把自己實際去操作產出來的系統。自己的感受如何,用戶的感受絕對會更為負面,所以要是如果自己的狗食都無法說服自己,怎麼拿你產出來的狗食去餵你的客戶? (哦幹這句話好髒)

在約耳續談軟體一書中,約耳又提到一個Beyond usability的東西:社會性介面 (social interface) [3]。書裡有很多例子,設計、行銷上也做了一些概略性的說明。我對這個方面還不很了解,我得再多看一些書和例子,做一些冥想才有辦法想通。只知道,這個東西沒做好,usability做得再好,軟體一樣會失敗,而這個,牽涉到的不是資訊產業會搞的東西,而是社會學人類學等社會科學;要做的研究不是書上翻一翻,上網查一查就搞得出來的,而是要走出門,去到不同的人群裡訪談研究不同族群之間的差異。

很有趣,不是嗎?跟人有關的東西就有理工科完全無法預期的變數,對此,社會科學反而是可以依賴的研究技術。(不然你用工程的角度來告訴我為什麼簡訊這種比電話還難用100倍的東西會受歡迎)
台灣學術界、產業界都不甚重視社會科學,認為研究出來的東西對產業界沒有幫助。事實上,只要和人、族群等有關的議題,社會科學都能提供比科技產業還要更可靠的研究技術和成果。社會科學提供的幫助很隱晦,不這麼直覺,但是只要用對方法,絕對有效,而且效果非凡。
不久的未來,我將引入這套技術,作為軟體開發方向的決策參考,讓社會科學能夠得到更多的重視。為了台灣的產業,也為了我的摯愛。

ref:
[1] Usability from Wikipedia
[2] 易用性 from Wikipedia
[3] 約耳續談軟體
[4] [HCI] 談人機介面設計與Usability
[5] 要求手繪 Logo 字體的迷思!怎麼讓現成字體也很有個性 by evenwu from T客邦
[6] 約耳趣談軟體
[7] User Interface Design For Programmers

2012年3月18日 星期日

[Programming] 設計模式 (1) - 策略模式 (Strategy Pattern)

さ~我們就來看看抽象(abstract)和介面(interface)的設計應用,看看它如何讓程式變得彈性又功能強大,而把物件導向程式帶領到另一個次元去~

在開始之前,你可能會需要先看看之前幾篇[1],了解一下物件導向程式設計的起因和操作。
所以在這裡,是都假設對抽象、介面這些都明白了,只是還不知道怎麼去應用在實務上而已。
另外,class都沒建的程式設計方式就不在這裡討論了。

----廢話的分隔線----

首先呢,我們來看看我們的需求。
  1. 建構一個"財產"類別。
  2. 已知的財產很多種,如土地、土地改良物、機械設備、交通設備、雜項、物品等。
  3. 會需要對財產進行異動,如新增、減損、重估等,異動流程有些一樣,有些不同。
  4. 日後要能夠對財產種類和異動種類進行擴充。
看起來算是很實際的例子吧?如果有觀眾在做ERP,這種案例應該隨時會遇到。
這個例子,也是我在出社會後第一個進行開發的專案。雖然還是有些許的不一樣,但大體上差不多啦。

這個,應該就能夠滿足他的需求....
如果你是哪個經理還是老闆,你覺得你的員工壓榨起來讓你很舒服,或是做出來的軟體日後不需要維護,你就可以這樣做。
我光是畫這張圖就累了!除非拿槍指在我的頭上,否則我無法接受我自己寫出來的程式長這個鳥樣子!
但是,相信我,一定還是有些人會這麼做。當我和沒有正確程式設計觀念的人共事時,就發現沒有什麼事是不可能的。

這個時候,我們應該平心靜氣地,把這些類別中相同的部分取出來,讓各個類別繼承。
然後就變成下面那樣子....
我們先把各個財產都有的屬性全都拿出來,放到一個Property(財產)抽象類別去,然後讓每一種財產都去繼承。這樣子看起來,好像還不錯?至少變數都拿到抽象類別去了。

然而,尷尬的點在於下面的那些財產,他們還有異動的方法還沒抽出來。如果是上面那樣的話,等於我在每個類別裡都要再另外寫異動方法;那如果是下面那樣....
好像就可以不用重寫太多東西了?會不會有哪裡怪怪的呢?
需求的點在於:異動流程有些一樣,有些不同。我們應該把哪些一樣的流程丟到Property去?哪些放在類別本身?
需求又說:日後要能夠對財產種類和異動種類進行擴充。這就表示,根本沒辦法知道哪些流程重複性比較高,哪些流程比較少用。

我們學過一個東西叫做介面 (interface),能夠強迫每一個實作它的類別實作一些方法。所以,我們還會看到下面那種東西…
如果你學了一套新方法,不確定怎麼用的話就不要亂用。幕容復就領悟過:再怎麼華麗的招式,也只是招式上佔上風,如果使用這些招式會因不熟練或其它因素而減弱傷害力,還不如不要用。這也是為什麼,日本的劍道和空手道的上段高手,每次練習的時候還是有再練基本的揮劍和正拳中段攻擊。

扯遠了。反正,如果一種方法不會讓你的工作量變少,就不要亂導入。看看上面那張圖,想像一下:這和第二張,剛把變數抽出來放到Property裡有什麼不一樣。
沒什麼不一樣!這樣還是得在每個類別裡實作異動方法啊!!
還有,不要覺得複製貼上程式碼是很容易的事。這種事情做多了,就像用火燒藤甲兵一樣,會損陽壽的。等到哪天業主一道指令叫你改掉什麼東西,你會發現你的時間都浪費在以前不知道複製幾次的程式碼上面。

----各種可憐情境的分隔線----

GG (good-bye garbage),跟那些爛code說再見吧!這個時候,就可以看到優秀的程式員如何用知識解決問題(工作量大的問題??)。
我們來整理一下問題。前面遺留下來的困難點在於那一堆神鬼莫測的異動流程,因為有些財產用的異動流程有一樣,有些不一樣,所以很難去特別把哪一種異動流程抓出來繼承。
那麼,就全部抽出來好了。

設計守則第二點就寫著[2][3]:
Program to an interface, not an implementation.
寫程式是針對介面而寫,而不是針對實踐而寫。
原因則是....
以前的作法是:行為是繼承自超類別的實踐方式而來或是繼承某個介面並由次類別自行實踐而來。這兩種作法都是依賴「實踐」,我們被實踐綁得死死的,沒辦法更改行為(除非寫更多的程式碼)。
所以,我們接下來的作法將迥異於以往。
我們另外做一個Operator的介面,然後把各種異動流程方法獨立出來,並且實踐該介面。這麼做,無論是Property或是Land...等財產類別,都不會被這些演算法套牢了。這就是「程式是對介面而寫」,或是「對超型態而寫」。
這樣子設計,財產那裡需要什麼異動方法,就加在這裡就好了,和財產本身就一點關係也沒有。各類財產需要哪些異動方法,再自己呼叫就行了。

於是,經過整合以後,我們就可以得到這個圖....
看見沒?那些有的沒的異動方法全和財產分開了!而Property那裡和Operator有關的,就是定義一個Operator類型的屬性,而財產本身如果要做什麼異動的時候,把各個演算法定義清楚,就可以操作了。

就像這樣....
//土地財產
public class Land extends Property {

    ///Constructor
    public Land(){
        ID = "";
        PropNo = "";
        PropNoSeq = "";
        cost =0;
        val = 0;
    }
    
    ///不動產新增流程
    public boolean Add(){
        operator = new EstateAdd();
        return operator.operate();
    }
    
    ///不動產減損流程
    public boolean Dero(){
        operator = new EstateDero();
        return operator.operate();
    }
}

那麼,假如我想要把不動產的新增流程,改成使用動產的新增流程,我只要改.....
    ///動產新增流程
    public boolean Add(){
        operator = new ProductAdd();   //這裡
        return operator.operate();
    }

一行就好了。


當然,你要把它做得更細緻一點的話,也可以再改一下.....
看到了嗎?利用這套模式,就能夠把程式變得彈性很夠,隨時能夠加以擴充,而不用修改到原本的程式。abstract和interface的混合應用,由這個例子可以看到,能夠把程式(或是系統架構)變得有彈性,程式之間的相依性變得低一點。
而這個,就是設計模式 (Design Patterns) 中,所謂的策略模式 (Strategy Pattern):
策略模式定義了演算法家族,個別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變動,不會影響到使用演算法的程式。

設計模式沒有對與錯,只有有效或無效而已。
是否有效改善程式結構,讓軟體變軟。


----還有一些打破主題的廢話分隔線----

設計模式這種東西,其實是一些先賢烈士面臨到需求環境的多樣化後,加以設計,並且一般化而成的設計方法。當然,他們遇到的情境和我們將要面對的可能又不太一樣,若要直接套用,會是有風險在的。但是如果能夠把設計模式裡的想法和精髓融會貫通,情境、需求有變,就做出不同的設計就行了。

不過,約耳在他的書上表示:設計模式是一種讓程式設計生活從普通變得不錯、有趣的一種途徑,即使沒有它,程式一樣能動,只是可能維護上會變得比較麻煩(可能麻煩很多)、程式跑得慢一點…但是它還是能跑。
而低階一點的C/C++,如果指標沒弄好,出了差錯,程式會直接死在你面前,別想它會繼續往下走,你的程式設計生活就會很悲慘,所以做C/C++的程式員是非常辛苦的,可能會有抓不完的bug,和無法預期到的exception。但是在這種環境下訓練出來的程式員就特別強[5],邏輯能力強不強是超乎另一個次元的問題(被指標和遞迴洗禮過的人應該不會邏輯能力差吧?),程式員本身的韌性也夠。理解指標和遞迴的能力,與成為優秀程式員的能力有直接的關係。
所以,約耳覺得,在學校裡學Java、.NET這種高階語言,訓練出來的學生層次感不明顯,無法很立即能夠判斷哪些程式員是真的非常優秀非常聰明的。

Java和C#給程式員的幫助真的太多囉~它們就像是電腦一樣;而C/C++就像是紙張報表和筆。熟悉C/C++就會發現平常要想一天做半天的東西,用Java兩秒就解決了,而且還有很多容錯機制和回收機制,不用怕出錯。而使用過Java的人,要再回去寫C/C++…可能連字都不會寫吧。
我就快到了不會寫字的生活了。

ref:
[2] 深入淺出設計模式
[3] Program to an interface
[4] 約耳續談軟體

2012年3月14日 星期三

[Programming] 物件導向 (5) - 介面

什麼是介面 (interface) ?這個名詞有沒有很熟悉?還是覺得很陌生?還是覺得很熟悉常常聽到又不知道具體的意義是什麼?
我們常常在講的使用者介面 (user interface) 或人機互動 (human-machine interaction),從維基百科上已有具體的文字定義[1]:
簡單來說,就是一個能夠有效控制機器,或是從機器裡得到回應的空間。廣義來說,作業系統、程序控制器、重機械控制器、汽車方向盤和計速器…等,都算是使用者介面。
我個人是將它想像成人和機器互動的中間那一層,而人可以從中間那一層去控制機器,機器會透過中間那層來傳達讓人知道的訊息

那在物件導向程式設計裡,介面又代表什麼?
這裡所說的介面,並不是指「使用者點了什麼按鈕,然後程式就會執行什麼動作」的那種介面,這是被歸類在使用者介面的範圍裡,和OOP中的介面不一樣。
這裡所謂介面,指的是一種特別的抽象類別,裡面有一個(或一群)方法,讓不同物件實現這些方法的時候,能做不同的事
這是不是聽起來很熟悉?現實出來的效果是不是有點像多型?沒錯~它是一種多型的實現方式(請參考三相之力[4])。

定義講多了,就好像都在嘴炮理論一樣。我們來看一下實際的例子。
有一個類別圖如下。反正就是有一個系統設計者,丟了這樣的類別圖給你,要你做出一個interfaceAction的介面,然後讓Fighter和Archer這兩個類別可以實現它。
這就是介面的長相:
public interface interfaceAction {
    void Run();
    void Walk();
    void Jump();
    void Sit(); 
}
這是Java語法。其實C#、PHP等OO語言都差不多,而且這裡要注意的不是語言上的差異。
一個介面,這樣寫就算完成了。眼睛一看就會發現它沒有定義各個方法實際要做哪些事,就只是把方法名稱列出來而已,等其它類別來實現 (realize) 它

然後如果有其它類別要使用這個介面的時候,它就會這樣去做:
public class Fighter implements interfaceAction {
    public Fighter(){
        System.out.println("Fighter Creation!");
    }

    @Override
    public void Run(){
        System.out.println("Fighter running...");
    }
    
    @Override
    public void Walk(){
        System.out.println("Fighter walking...");
    }
    
    @Override
    public void Jump(){
        System.out.println("Fighter jump once!");
    }

    @Override
    public void Sit(){
        System.out.println("Fighter sitting!");
    }
}
這段程式第一行比較要注意的是,在Java裡要完成一個介面時,中間要掛implements關鍵字,然後在後面加interface的名稱。假如程式很複雜,需要implemets兩個以上的interface,那就把interface名稱用逗點隔開就行了。
然後,這個實現interfaceAction的類別,要逐一實現interfaceAction裡的每一個動作,不然基本上編譯器不會給過。然而,每個要implements interfaceAction的類別,裡面的方法動作可以不一樣,多型就這麼實現了。
基本上使用上就是如此。如果有其它類別,比方說是Archer類別,要實現interfaceAction,就用同樣的方法來實現介面,並且在要把interfaceAction裡的方法也都寫過一次。

你可以把它想像成一個使用者介面(像是遙控器的按鈕和面板),上面每個哪裡有幾個按鈕或哪裡顯示東西都是固定好的,然後把它接到不同的機器元件上面之後,它的按鈕動作和顯示出來的東西就不一樣。OOP的介面只是把這種概念實現出來而已。


啊?你說每個動作都一樣,重寫一遍太麻煩?那就不要用interface啊!
我這樣講並不是不負責任的說法,不過這是設計上的問題,下次再說。你在這裡只要先知道:實現interface的元件,必須把所有interface裡的方法都實現出來
也許你會在程式書上面看到「abstract和interface之間的比較」之類的章節[3],我不打算在這裡提。因為abstract和interface之間雖然行為上有這麼一點相似,但是它們的概念卻是大大的不同。我認為,直接從這兩種東西的原始定義來看程式和用法,會容易理解許多。



ref:
[1] User interface from Wikipedia
[2] Interface (computing) from Wikipedia
[3] Java Gossip: 介面(interface)型態
[4] [Programming] 物件導向(3) - 三相之力

[嘆世間] 奴隸與責任制

有人說會寫作的人就有基本的影響力,所以我決定三不五時就寫一些內心的想法。
就從台灣的責任制開始吧!


wikipedia上面所編輯出來的「責任制」來看,它是一種工作制度,允許員工在預期時間內完成公司所指派的工作或任務,而不受上下班打卡的時間限制。
制度的起意是好的。畢竟每個人的作息條件不一樣,有些人適合在晚上的時候工作,有些人相反,所以只要把工作指派給它,並交代完成時間,就不需要再太強制去要求員工的上下班時間,這種和工作內容沒有實際關係的事情上。

這種制度的發明,是基於資方的天地良心和勞資雙方對彼此的信任。相信所指派的工作內容和工作量是合理的、相信員工會用自己的責任心來完成事情…所以,如果勞資雙方其中一邊的天平傾斜了,事情會變得如何?
資方打著責任制的名號將大量的工作分配給少量的人力,使勞方無法在有限時間(正常上班時數)內完成自己的工作,必須加班才能把事情做完-可能還做不完。因為是責任制,所以資方不給額外的補助。
另一種情況是,勞方以沒有責任感的態度來執行責任制,以制於上班時間不穩定、預排好的會議因私人因素無法參與,使團隊裡應該協調討論的相關事項無法達到有效的溝通效果。
雙方都不信任彼此,就會開始進行這兩種天平加碼的拉鋸賽,最後什麼事情都沒辦法完成。

注意囉,再來就是台灣的現實面。

我愛台灣。台灣好山好水,物產豐饒,政府勤政愛民,人人知書達禮,而且是中華文化的繼承人。嗯....其實沒有這麼好,台灣還是有一些浮出水面的敗類,但是浪漫如我,我還是願意相信大部分的台灣人都這麼優秀,至於要戰兩岸嗎?來啊!幹。
總之,我愛台灣,所以我不願以看熱鬧的心情來詛咒台灣。但是身為台灣人,看到台灣的就業、社會現象,我得說一聲:幹你媽的

在台灣,責任制已經是常態,但有良心的責任制卻是少得可怕。台灣的資方經常為了壓低人力成本,希望能夠利用把每個月付給員工的薪水發揮到最大效果,而分配給員工過多的工作、過長的工時,或是減少輪班班次等,讓員工事情永遠做不完,事情只會一天比一天多,一天比一天勞累。
我個人是做資訊業的,我就體驗過什麼叫「一輩子都奉獻給公司」的感覺。
當時在我出社會的第一間公司,主管是個資訊產業的大外行,又自以為了解軟體工程,認為管理流程是製作任何東西的一切,忽略了被流程包起來的技術方法,用錯誤的方法做事,花了一大堆時間在做虛工、重工和補那些補不完的破洞,然後一副學到東西的樣子,還要員工花自己的晚上的時間上課還是開會等。
不是我對它有什麼偏見。有哪個軟體資訊業的廠商,會把按鈕觸發的一切動作都寫在那個按鈕上的?有哪個軟體資訊業的廠商,在做報表的時候會把同一張報表畫個四、五次的?有哪個研發團隊會連自己要什麼都不知道就下去寫程式的?有哪個研發團隊不懂資料結構、演算法、設計模式…等技術的?我不是真的很懂,我想學,我想從實務中學習有用的技術,但是在這個研發團隊裡學不到,只會要你在有限時間內用複制貼上的方式把source code貼來貼去,之後有錯再來追進度來改。這些,全是資訊技術方法的問題,流程不管這個,但是對軟體廠商來說是個建國根基,偉哉主管不懂,也不管,只知道一些他想知道的,他可愛的研發團隊也不管,甚至我懷疑他們連我在寫什麼都不是很清楚。
所以我離開了。如果你是這間公司的員工,而且反對我的說法,麻煩,舉個實際的案例來說服我一下。如果只是想對我發脾氣的話就省省吧~就事論事,別扯其它的。
我相信還有很多從事軟體資訊業的先進大德們,也和我有同樣的感受。其實仔細觀察,就會發現這種現象不只充斥在資訊業而已,服務業、保全業、醫師....等各行各業,在現今的台灣社會裡都看得見,而且非常普遍。

普遍,不代表正常。所謂的正常的制度,應該是一種能讓公司、讓社會永續運作的制度流程。這種具有台灣特色的畸形責任制[2],完完全全展現出華人短視近利的缺陷和不尊重員工的惡習,為求短時間的成本減少,而必須付出更多的成本來填補破洞。
最簡單的例子:把一個人弄累了、弄垮了、弄不爽了,使該員必須(或一定會)離開它的崗位,那麼,資方需要多少時間培養一個和他有相同技能,能夠完完全全取代他的人?這些時間,對資方來說都是成本。資方可能再繼續使用同樣的方式逼迫新人盡速上手,再一次的壓縮休息放鬆的時間,雞生蛋蛋生雞的哲學問題就又實現一樁了。
這種畸形的責任制,可不單純只是影響工作或某某產業而已,還會延伸到許多社會問題

  1. 家長在忙工作,沒空陪小孩、沒空教養小孩,小孩就容易孤單,容易學壞。
  2. 家長習慣性地試著用錢來改善沒空陪家人的家庭關係,容易造成價值觀的偏差。
  3. 工作量過多,家長帶著疲憊身體日復一日、年復一年,使人還在還有生產力的年紀,就已無法再工作。
  4. ....

再更多的連帶關係,我這裡就不再多談了。早在好幾年前就已經有一大堆的文章曾經點出這些問題了,但是沒人理還是沒人理,也沒看到政府用什麼有威嚇力的方式壓制這種情況。

我只是個不學無術的傢伙,不敢說永續運作的制度應該如何推動,也不知道有哪些方案能夠推動。不過身為一個資訊業的小齒輪,還看過所謂的40工時,意即每週工作40小時,平均每天工作8小時,也就是從早上吃早餐的時間,做到吃晚餐的時間。讓人工作一天的壓力,能夠在吃完晚餐後得到放鬆、集中力得到休憩,做自己喜歡做的事,看書進修或看電視打電動等等。(有人會質疑打電動背後的意義,就算無法獲得個人能力上的進步,也能精神上的放鬆,那就有意義)
尤其是程式員,平常就都是在用大腦在工作的,每天沒有適度的休息和放鬆,怎麼能期待得到精神飽滿狀態下的生產力?為什麼台灣的老闆都想不透這一點?一個人沒吃飽沒睡好,身體還有病痛,能夠把工作做好嗎?這麼簡單的道理居然看不見?在過勞的精神狀況下工作,做出來的成果品質會有多好?多少人為疏失的起因都是源於精神疲累?
說到這裡,不要跟我鬼扯「有成就的人應該多花點時間在自我進修和成長上。」或是「愛你的工作就不會有壓力。」這種鳥事。媽的我以前老闆最喜歡講這種話了。
每個人休息的方式不一樣,有些人確實會用看書、玩未知的技術來作為休息,有些人會看電視喝酒打電動睡覺來紓壓,無論如何,它們的特點就是他們會得到放鬆。而老闆在要求自己的員工用進修來當作放鬆,當你叫你的員工進修時,對員工來說就是指令,那只會無止盡地延長工作時間,因為透過這種方式進修,並不會得到休息放鬆的效果。

因為我愛台灣(光這篇文我就重申了三次了),而且看到了這個問題會深深影響台灣的未來,所以想要把這種畸型的制度鏟除
多麼異想天開的想法!一個寫程式的小工程師,怎麼改變這種幾近成為定局的大環境?老實說,具體的做法我還沒有想到。所以我認為,至少從自身做起,有原則地挑戰這種制度,並且宣揚這一套想法,讓台灣的勞工有尊嚴地做他們的工作、愛他們所做的事,就能夠一點一滴地蠶食掉這種詭異的觀念。說到這....我也不知道為什麼台灣上一代兩代的人們會認為做管理職就是升遷,一輩子做技術員就是沒出息,一個可以解決手上任何問題的技術員,為什麼會被視為比廢物主管垃圾經理還要沒價值?
我所謂有原則的挑戰制度,並不是真的用很強硬的方式跟主管講:「老子就是不加班,有本事你就來做我的事!」,也不是徹頭徹尾地去反對責任制。而是,每天該做多少事就做多少事,該做多少時間就做多少時間。有時候事情比較多,比較急,需要大家一起趕,或是需要幫其它同事cover一下什麼事,那當然也是沒有問題啊,但是那僅限於偶爾為之,不能他媽的每天都忙每天都趕,或是每天都在有多的事情要做,像是下班前半個小時說要做什麼事,明天一大早要看。他媽的我絕對會叫你去死,你不去死我就殺了你。

當我把這個念頭和我幾個我認為有企圖心的朋友們知道時,讓我在這麼冷的天氣裡又被淋了一頭冷水。
同學S是我一位強者同學(強者我同學真的不是我),在我找工作的時候他幫了我不少忙,也給我滿多的信心。問起我所能接受的工作時間的時候,一開口就說「不能再多一點嗎?一天12個小時?」,後來還補「我是社會化比較深入」「和不錯的工作夥伴共事還是不錯,多花一點時間沒什麼的。」之類的話。
學弟D是一位當兵接我業務的同學,我觀察他的心得是正義感也很強,是非分明。當我問他對現在台灣的責任制有什麼改善的方法時,他跟我回「移民,或是當公務員」。
What the ....咳FUCK!!
為什麼大伙們都知道那是個問題,卻都還是接受它,或消極地逃避它?我知道改善這個問題不是容易的事,但是最重要的第一步,應該還是要先從勞工的觀念開始著手吧!告訴人們勞方不是奴隸,不應該奴性這麼重!我也知道一切嘴巴講都很容易做到很難,但是用時間、用行動來證明這套理論才能提供更多的生產力,不就能夠慢慢的改善這個環境了嗎?很難,我也知道要達到那種理想很難,但是如果不走出第一步,也就永遠停留在現在這個階段了咧!
讓我大受打擊的是…強烈的企圖心,強烈的正義感,在面對這件事情的時候居然這麼消極,居然如此被動。
難怪在台灣創業這麼容易,因為老闆的奴隸都不會想反抗。



看到這裡,還記得我寫這篇亂七八糟的動機嗎?
沒錯,就是為了影響力。約耳在他的管理經驗書[3]裡提到:
「平庸的程式員和優秀的程式員之間的差別,並不在他們會多少種語言,也不在於他們喜歡Python還是Java。重點是能夠和他人溝通自己的想法。優秀的程式員藉由說服他人而獲得影響力。」

「如果你有能力寫作,不論是在何處工作,很快就會發現自己會被要求寫規格文件。這意味著你已經發揮自己的影響力,還讓管理階層注意到你了。」
所以,我決定開始認真寫些有的沒的,來傳達我的理念和想法。
首先,就是這篇「奴隸與責任制」。

16世紀,葡萄牙人將西非的黑人渡到南美洲當奴隸。黑奴為了自由,為了持續自己的文化活動,發展出卡波耶拉(巴西戰舞),作為對付葡萄牙人的武器[4]。500年前,幾乎什麼都沒有的黑人們,為了自由,有勇氣研究出這套徒手攻擊技能來對付葡萄牙人的火槍;500年後,地球的另一端,百姓富有、物產豐饒的21世紀台灣,存在著幾近奴隸制度的扭曲責任制,而且沒有人想反抗。
真的是這樣嗎?

接下來的詩篇,將由我們親手撰寫。究竟會是悲歌,或是凱旋之歌,取決於我們的一念之間。
站起來吧!

ref:
[1] 責任制 in wikipedia
[2] 責任制,阻礙國家進步
[3] 約耳續談軟體
[4] 卡波取拉 in wikipedia

2012年3月3日 星期六

[Programming] 物件導向(4) - 抽象

我們常常會對一種模糊不清的東西,以「抽象」來形容它。而在OOP裡,也有抽象的類別可以定義。正如「模糊不清」的形象,抽象類別本身並不能被實體化,而是需要被能夠實體化的類別繼承了以後,才能真正使用。抽象的概念不是指「模糊不清」的東西(模糊不清的東西是要怎麼寫成程式?),而是一種有範圍性的大方向,或是一種大種類的東西。

以下是範例,就和很多教科書一樣,只寫怎麼使用,感受不出它的威力。
public abstract class abstractPerson {
    protected String Name;
    protected boolean Sex;
    protected String Email;
    protected String Offer;
}

public class Engineer extends abstractPerson {
    private LinkedList Skills;
    public Engineer(){
        Name = "";
        Sex = true;
        Email = "";
        Offer = "";
        Skills = new LinkedList();
    }
}

上面那個例子,我設計"人"的抽象類別,然後讓"工程師"來繼承它,若我還有"行政作業員"或"財會小姐"之類的類別,也同樣可以透過這樣的方式繼承"人"。
其它例子....像是"財產"可以做成抽象類別,而"土地財產"、"建物財產"、"運輸設備"這些類別就可以繼承"財產";
或是"棋子"可以做成抽象類別,"國王"、"皇后"、"主教"....各別做成繼承"棋子"的實體類別。

還有另一種思考的方向是.....抽象類別可以視為繼承它的實體類別的大種類,用白話文來說,可以講成"是一種 (is a kind of)"。像前面財產的例子,就可以翻譯成土地財產是一種財產運輸設備也是一種財產…等。用這種方式來思考,是比較容易將抽象類別應用在系統設計上。

2012年3月2日 星期五

[Programming] 物件導向(3) - 三相之力


三相之力。(From 魯阿魯)
好吧,我承認我很宅。


三相之力是LOL裡三種不同類型的中等武器合成的高級武器。會用三相之力來當副標是其來有自的。物件導向程式設計的概念中,有三種強大的能力,算是當年程式設計中跨時代的發明,分別是封裝(Encapsulation)、繼承(inheritance)、多型(polymorphism)。


封裝
如果要以一句話概括封裝的話,應該可以這麼說:外部的程式不能直接去存取物件裡的成員,而是必須透過特定的public存取權限的成員來存取物件內容。如果沒有封裝的概念,物件的意義就變得不怎麼重要了,C語言的struct也做得到同樣的事。把原本散成一團的程式封裝成一個一個的物件,就是為了讓程式裡物件和物件之間的依賴性變小,也就是隅合度變低,讓程式碼不會像一團陽春麵一樣,抓一條麵就把整團揪結在一起的麵全抓出來。
這應該不難理解。試著想像一下,如果你的封裝特性做得確實,外部程式在存取物件的時候就能透過幾個特定的方法而已,而這個物件實際經過哪些動作,外部的程式根本不需要知道。這時候,如果有什麼地方要改,看是物件裡面的動作,或是外部程式要改,而不至於需要把整隻程式和所有動作全部改掉。
然而,封裝只是建構物件導向設計的第一步而已....


繼承
有的時候,或很多時候,你會發現你需要用到的物件和其它物件只差一點點東西而已,只要稍微將原有的物件加以改寫或加工就能滿足你的需求。這時候,你不需要從頭到尾重新建置一遍,只要建立一個新類別,然後繼承那個需要加工的物件,就可以開始加工新類別來滿足自己的需求,而且不用動到一分一毫原有的類別(要動到的話也是可以)。
假如今天B類別繼承了A類別,我們會稱A類別是B類別的父類別(superclass)、B類別是A類別的子類別(subclass),此時,正如前述所說,B類別會擁有A類別的一切特徵,然後再看你要怎麼去寫B類別。
上述那使用繼承的案例,比較明顯的動機是重新使用(reuse)。事實上,繼承更強大的威力不只是reuse而已。透過繼承抽象類別,就能夠把不同的類別整合起來,產生一個更有彈性的架構。比方說,我有人、狗、貓三種類別,我就能夠把這三種類別相似的地方抽離出來,另外做出一個「動物」的抽象類別,並且讓人、狗、貓這三個類別繼承動物,之後,人狗貓這三種類別,同時也有動物的類別特性,之後在呼叫「動物」的時候,是能夠代入這三種類別的。幾乎所有設計模式(design patterns)都會用到繼承,而且都會用到抽象類別或介面的繼承。當我們日後介紹到抽象或設計模式的時候再詳細描述吧!
要注意的是,C++可以允許子類別繼承多個父類別,而Java和C#不行,詳細的原因不太清楚,只知道這種多重繼承會讓程式的複雜度提高很多,就算允許也不建議使用。


多型
簡單來說,它允許一個類別的同一個函數,在不同物件(被實體化的類別)裡做的事情不一樣,但是必須透過繼承才能達到這個目的。所以,先有繼承的概念,才能實現多型。
舉例:既然要繼承,當然必須有一個基層父類別A,還有繼承出來的子類別B和C。此時B和C就能夠透過override把原本A類別裡的方法a',根據自己的需求做改寫。讓B和C各別的a'執行自己的動作。
後來在拜讀了搞笑談軟工裡所介紹的多型,才明白其原理:今天如果呼叫一個物件裡的函式,並不是由呼叫函式的那一端 (sender) 來決定呼叫到的行為,而是由接收端來解釋。當我們由物件D裡呼叫B和C的a',執行的行為並不是由D來決定,而是由B和C來決定,所以,我們會在物件D裡得到B和C各別執行完a'的結果。




透過這三種概念,物件導向的發展空間開始擴大,設計出有彈性、可擴充、容易維護的軟體架構。
只要你會用的話。


ref:
[1] 思考物件導向(1)物件導向與封裝
[2] 搞笑談軟工