分類彙整:工作

jason_fried

[翻譯] Basecamp共同創辦人:不必擇你所愛,也不必愛你所選

如果你常參加創業聚會,或是常去聽那種企業家的勵志演講,你會很常聽到這種論調:你必須擇你所愛,愛你所選!如果你沒有的話,那你乾脆別出來混了。最著名的例子是Steve Jobs 2005年在Standford畢業典禮上的演講:「想要有出色成就,唯一方法就是做你熱愛的事。如果你還沒找到,那就繼續找下去,不要停下來。」

我完全不信這套。

熱愛自己的工作當然沒有錯。但我不覺得這是創業或實現抱負的先決條件,也跟什麼出色成就無關。說真的,事業有成的人吹噓自己對工作的熱愛實在很虛偽。就跟富有的人說自己不在乎財富一樣虛偽。人們常常會浪漫化自己的動機跟過去。他們會把自己現在所在乎的東西想得很重要,而忘記他們一開始在乎哪些東西。人類天性如此,很容易就會這樣。

根據我的觀察,許多出色企業跟重要創新,根本是源自於挫折,甚至是厭惡。Uber的共同創辦人 Travis Kalanick 和 Garrett Camp哪是因為熱愛運輸與物流才創業的。他們創業是因為舊金山很難叫計程車,搞得他們一肚子火。Kalanick現在大概滿喜歡經營Uber的,但他之前真的超痛恨叫不到車回家。巴黎一個腦力激盪的夜晚,讓那份挫折轉變為一棵幼苗,孕育出一間市值數十億美金的公司。

我常常跟其他企業家聊天,很多人開公司都是基於類似的理由:他們想要的東西市面上沒有,或是想用更好的方法去改變舊的做事方式。至於是否熱愛則未必重要。但是對於現有選項的厭惡、對於事物運作方法的強烈意見則影響極大。能否成功也和它比較相關。

我的職業生涯也是這樣。大概在90年代的時候,我想找一個能幫我紀錄音樂播放清單的小工具,但市面上的軟體都很肥大,而且過度複雜。這兩件事都讓我痛恨。所以我就自己想辦法做了一個工具,最後命名為 Audiofile丟到市面上。我並不熱愛音樂蒐集,也不熱愛開發軟體(當時才剛學而已)。我也沒有開一間軟體公司的願望。我就只是看到一個需求,然後設法滿足它,謹此而已。這沒什麼不對。之後也基於類似的情況,開了現在這間公司Basecamp。

老實說,就算到了今天,我也沒說總是很愛我的工作。那些文書工作,那些報告,伴隨公司成長所帶來與日俱增的責任與瑣事。這些事都讓我覺得很煩。不過經營Basecamp對我來說還是比做其他事好。我覺得我做得不錯。每天都要作一些需要創意、很有挑戰性的工作。我一直覺得讓專案管理工具越變越好,是一個值得、能有所回報的理由。每天都能跟這些厲害的同事一起工作也真的很棒。

如果要我上講台發表什麼勵志演說,我會說,如果你想成功、想對世界有貢獻,你需要對你在做的事情有某種內在動機。你必須樂於把時間花在那上面。對於它的喜愛有可能在日後增加。如果真的那樣,那很棒。但不需要一開始就熱愛它。光是渴望一個還不存在的東西,就足以讓你成功。

(本文翻譯自 Do you have to love what you do?,得到 Jason Fried 親自授權。)

big

[推薦]學寫程式的幾本書籍

常常被朋友問到,說他工作上有某某需求,想學某某語言,有沒有適合他的書本?

有的,我的確有推薦的入門書籍。

這裡寫文章一次回答這些問題。

Q: 我沒有任何基礎,想入門程式設計,希望能叫電腦替我做些事情?

我推薦「深入淺出程式設計」。
programming
Q: 我沒有任何基礎,想入門程式設計,學架blog、網站、個人網頁?

我推薦「深入淺出 PHP 與 MySQL」。
php-mysql
Q: 我不想學寫程式,只想學設計相關的HTML&CSS?

我推薦「深入淺出HTML&CSS」。
html-css
Q: 我有一點基礎,但想更了解Python的初級、中級觀念?

我推薦「深入淺出 Python」。
python
Q: 我有一點基礎,但想更了解Java的初級、中級觀念?

我推薦「深入淺出 Java 程式設計」。
java
Q: 我有一點基礎,但想更了解JavaScript的初級、中級觀念?

我推薦「深入淺出 JavaScript」。
javascript

你可能會覺得奇怪,怎麼全是同一套系列的書?

這也沒辦法,因為深入淺出系列就是如此出色。

整套系列,我買入手的、曾經去圖書館借來看的,就在10本以上。

歐萊禮的這系列書籍,跟一般的電腦書籍非常不同,

它會兼顧你學習、應用、樂趣、知識,多個入門最需要的面向。

試了很多本電腦書籍,卻依然一頭霧水的朋友,不妨試試看深入淺出系列。

programming

寫程式不需要天份,也不需要熱情

從來沒有一個技能,曾經被神化到這個程度:

「你不但要有天份,還要有熱情,才適合寫程式。」

那些寫程式的人,好像「從小就立定志向,決定未來要寫程式了」。

缺乏其一的話,你要嘛是個假貨,要嘛走不遠,總之就是不適合。

這種深植人心的刻板印象不但大錯特錯,同時還是有害的。

隨便找幾個工程師都能證明這點。

Jacob Kaplan-Moss(Django創造者)

Jacob Kaplan-Moss的這份簡報提到:

一個平庸工程師的自白

這種關於「程式天才」的神話非常有害,一方面它把行業門檻設置得特別高,令很多人望而卻步,另一方面它也在折磨產業內的人,因為你如果不能 rocks ,就會變成 sucks ,所以不得不用一切時間來努力學習和工作,導致影響生活。…(略)…我們應該改變這種態度,寫程式只是一些技能,並不需要太多天分,它是可以學習的,而且做一個平庸的工程師不丟人,

他本人在Twitter的自介直接寫「不是真的程式設計師(not a real programmer)」,

透漏著他對這種迷思的不耐煩。

Jacob Thornton(Bootstrap作者)

在Github擁有八萬顆星的Bootstrap作者,

前Twitter、現任Medium工程師Jacob Thornton的一篇採訪也是這種迷思的反例:

Jacob Thornton痛恨電腦(Jacob Thornton Hates Computers)

當他說「我痛恨電腦」的時候,並不完全在開玩笑。…(略)…他說「我本來要去唸社會學的」

接著描述了他第一份工作的情況:

我拿到了一個遠超我能力的工作。每一天都可能被開除。所以我非常努力工作,想搞懂JavaScript,因為我不懂它到底在幹嘛。

我一生中最現實的一刻到了。整間公司的人圍在我身邊,要我做一個XHR request。我根本沒做過,我只稍微聽過而已。於是我開始打字、重新整理瀏覽器,然後什麼都沒出來。我反覆做了幾次,知道自己完蛋了,他們發現我是假貨了。接著我突然發現自己忘記加「.send()」。我加了之後再次重新整理瀏覽器,畫面成功顯示。整個團隊感覺像在說「喔,酷。」然後就各自回辦公桌了。

我在那裡坐了15分鐘。心想,就這樣。我搞定了。我不會被開除了。

這段描述一點也不像「程式天才」在職場的表現。

至於支持他一路走來的動機是什麼呢?他說:

我是一個高度在乎同儕的人,我做前端的朋友總是會告訴我哪個地方做很醜或是在哪個瀏覽器上壞掉。感覺真的很棒。我真的只想跟朋友一起寫程式,一起工作。

他本人的Twitter自介寫「computer loser」,

置頂推文是「公司裡第一爛的工程師,但是第三酷」。

這種態度跟刻板印象完全相反。

Rasmus Lerdorf(PHP之父)

Rasmus Lerdorf的言論常常引起廣泛爭議:

  • 我其實很討厭寫程式,不過我喜歡解決問題。
  • 有些人熱愛寫程式。我不懂他們為何會這樣。
  • 我不是一個真的工程師。我把東西弄一弄,弄到能跑之後就不管了。真的工程師會說「這段程式能跑,但記憶體沒管理好,我們來修好它」。我只會說,一直重新開機不就好了。

從他的言論,很難看出他對電腦本身有多少熱情。

他也跟Jacob Kaplan-Moss以及Jacob Thornton一樣,懶得對寫程式的迷思多做解釋,

乾脆直接說自己是loser、假工程師了。

David Heinemeier Hansson(Rails之父)

DHH在接受Big Think訪問時提到:

說來有點好笑。我以前寫PHP跟Java的時候,常常花時間去摸其他程式語言。到處摸看看其他程式語言…隨便什麼都好。寫PHP跟Java實在太悶了,我需要用這種方式讓自己暫時抽離。

我以前寫PHP跟Java的時候,完全不覺得自己之後會當程式設計師。

整段看起來都不像是一個「電腦天才」的自我介紹。

最後讓他愛上的不是電腦本身,而是Ruby程式語言的優雅性。

如果Ruby沒有被發明,DHH現在也許會做完全不同的事情。


這一類可以說明刻板印象大錯特錯的文章實在太多了,

看看工程師們最愛的幾個玩笑:關於工程師 59 條搞笑但卻真實無比的語錄

  • 一個人寫的爛軟體將會給另一個人帶來一份全職工作。
  • 傻瓜都能寫出電腦能理解的程式,優秀的工程師寫出的是人類能讀懂的程式。
  • 開發軟體和建造教堂非常相似——完工之後我們就開始祈禱。

如果工程師都很有天份跟熱情,這些笑話又怎會受歡迎呢。

再看看Medium上很受歡迎的學習系列文章:資深開發者給後輩的七個 Coding 學習心得

其中的幾個建議

  • 也許常常有人說你是錯的
  • 也許常常會有人跟你說「你並不是個 Coder」
  • 不要在意外表,能力才是一切

無非就是想打破這類寫程式的迷思、無意義的資格論神話。

下次又有人學到一半,開始反省自己適不適合、夠不夠資格的時候,

我只想跟他說:你就多找幾種方式學學看吧,不要抱持那種奇怪的資格論。

很多時候其實只是搞錯方法搞錯心態而已。

真的完全學不懂再放棄吧。

寫程式不需要天份,也不需要熱情。


如果您喜歡我的文章,可以在這裡訂閱。我有新想法的時候,很樂意跟你分享。

(Photo via Sano Rin, CC licensed.)

structure

ARCA架構:以 Active Record 為軸心的架構

越來越多的framework本身提供Active Record實作。

不管是Rails的Active Record,還是Laravel的Eloquent,

這些Active Record實作的功能越來越豐富而強大。

它讓開發速度更快了,但也因為太多功能塞在一起,容易寫出極度肥胖的萬能類別。

該怎麼使用這種萬能類別,又不至於讓它胖到難以維護呢?

我從工作中整理出了稱之為ARCA的架構。今天來跟各位分享。

註:本文程式碼多以Laravel框架舉例。但是相關概念通用在任何擁有Active Record的語言/框架。

簡介

ARCA全名「Active Record Centered Architecture」,

也就是「Active Record中心架構」,以Active Record為主軸的軟體架構。

ARCA試圖在享受Active Record帶來的開發速度的同時,拉出一定的架構。

這套架構適用於中型以上(連續開發3個月以上)專案,不適用於小型專案(像是餐廳官網)。

ARCA架構

ARCA架構由幾個元素組成,檔案結構看起來如下(以MVC舉例):

一個元素會是一個資料夾,或是一個檔案(類別)。

/View資料夾
/Controller資料夾
/Model資料夾
…./Entity Model資料夾
……../Entity類別
……../Repository類別
……../Presenter類別
……../Form類別
…./Service資料夾
……../Service類別
…./Operation Model資料夾

Entity Model資料夾

擺放與一種entity相關概念的程式碼。

將一種entity相關的程式碼放在同一個資料夾。

Entity類別

entity是公司在乎的商業領域(domain)中,代表現實世界的一種事物。

常見的entity包含訂單、商品、顧客、禮券、文章。

通常會代表現實生活中的一種事物、需要具備ID。

在ARCA中負責直接繼承Active Record的類別。

這是ARCA架構的重點所在。遵照少數的類別命名、資料表命名慣例(convention),

直接賦予這些entity類別多種能力:

  • 物件property存進資料庫的相關操作(CRUD)
  • entity間的relationship
  • 對資料庫取出的值做適當轉換

而開發者所要做的,只是寫好類別定義與幾個函式而已。

也正是Active Record的多功能,讓entity的建立如此迅速。

公司domain所需的商業行為,與entity相關的動作都是寫在此處。

Repository類別

封裝query logic,提供取得entity(一或多個)的不同方法。

不論是Rails的Active Record還是Laravel的Eloquent,都有提供查詢(query)的功能。

舉例來說,想要拿出新舊排序過的精選文章,可以這樣寫:

但是這幾行程式碼很可能常常用到,會到處重複。

這時就可以用repository封裝這段code:

以這段封裝來講,不但讓controller內的code可讀性提昇,同時還提供取出不同數量的參數功能。

ARCA內的repository都依賴Active Record提供的query實作,

所以建立一個abstract class再讓所有repository都繼承它是一個好主意。

參考這份EloquentRepositoryArticleRepository實作。

Presenter類別

封裝與business logic無關,只與呈現(presentation)相關的logic。

entity相關的名稱、金額、日期,常常在不同地方有不同呈現格式。

將這些寫成entity的function可不是好主意。

這類presentation logic可以獨立成presenter類別。

(或稱View Objects…。注意:軟體名詞在不同社群的用法極度混亂。)

概念上只是將entity塞進presenter,也就是decorator pattern

實作上可以依不同語言、框架的特色發揮創意。

像是這套善用了PHP特性,讓presentation 相關的code明確分離。

Presenter長這樣:

接著可以從entity直接使用presenter實體,呼叫presentation logic。

Form類別

處理使用者從HTTP表單填入的資料,封裝驗證(validation) logic。

web application少不了大量的運用html表單與使用者互動。

針對user input的驗證 logic(例如字串長度、日期、金額大小)可以抽出來成為Form類別。

(在Laravel 5稱為Form Request,在Rails社群稱為Form object

原理上來說,就是將表單傳來的參數傳給Form類別,在裡面驗證過後才決定是否執行下一步驟。

舉例來說,這件事若在controller內進行,看起來就像:

而Form類別的實作則依照語言/框架的不同各自發揮。

舉例:Rails可用VirtusLaravel可應用Validator

Service資料夾

擺放跨domain概念的程式碼。

多個service類別會放在此資料夾。

Service類別

概念上不屬於任何entity的business logic可以獨立成service。

通常是施加在多個entity上(來自不同domain)的複雜行為。

舉例來說,計算訂單的折扣與售價,通常會涉及訂單與禮券,並且運算邏輯較為複雜:

使用時,將entity傳進去即可:

Operation Model資料夾

圍繞某種行為概念的程式碼可以整理起來、放在一起。

當service開始依賴其他service時,代表這項行為開始變得複雜、開始造成理解的困難。

試著看清是哪個概念(這很不容易)、以它命名(也不容易),建立出Operation model。

舉例來說,電子商務公司提供報價會同時涉及「禮券折扣」、「出貨日期」、「總金額」的計算。

也就是QuotationService(報價)會用到DiscountService(計算折扣金額),

DueDateService(計算出貨日期), PriceService(計算總金額)。

這時可以將它們從Service資料夾移出、建立一個Quotation資料夾、再全部丟進去。

丟進去之後可以進行適當的refactoring,增加這幾個類別間的cohesion,降低之後理解的困難。

也可以進一步使用Facade Pattern封裝這些類別,建立一個統一對外的接口,

降低其他地方的程式碼與這個Operation Model的coupling。

以上面報價的例子來說:

結語

討論架構時,通常只討論概念,不將檔案結構列入討論。

我認為那樣的討論讓很多人有看沒有懂,所以將檔案結構一併納入ARCA說明了。

ARCA不是一種理論或是無敵的架構,只是一種用來搭配Active Record,

將常用元素(或說是Design Pattern)組合起來的一種方式而已。

可以將ARCA架構視為一種適合新創公司快速開發的、通用的中型基本架構。

隨著情況不同,做出調整、增減元素(例如好用的Factory類別)即可。

有任何疑問,或是有推薦的好用Design Pattern,覺得適合加進ARCA嗎?

歡迎在下方留言,或是在 Twitter @howtomakeaturn 和我討論。


Q&A

Q1: Service類別的例子怪怪的…明明可以寫進其中一種entity啊!像是這樣就可寫進訂單entity:

何時放在entity,何時獨立成service呢?

如你所說,一項行為究竟是否足夠「複雜」到需要獨立出來,的確屬於開發者的主觀判斷。

但是認定所有行為都不「複雜」的話,entity很容易變得極度肥胖喔。

Q2: 我覺得用Active Record會讓測試很難寫,有解法嗎?

這確實是Active Record的一大缺點:在測試時很難不去碰到database。

使用快速建立測資的套件,似乎是唯一能勉強接受的方法。

Ruby有factory_girl,PHP有Factory Muffin

參考看看吧。

(Photo via SuperCar-RoadTrip.fr, CC licensed)

toptal

關於Toptal的一點後續

我在去年8月加入了Toptal

之後在批踢踢收到幾位網友來信,好奇我在Toptal的後續發展。

我加入之後,並沒有在Toptal上面接案(我跑去一間startup上班了),

所以沒有實際的Toptal工作經驗。

但還是有一點心得跟各位分享。

Toptal上面case多嗎?

上面軟體專案的case挺多的,所以不用擔心加入之後「根本沒案子」。

容易接到case嗎?

我曾經花一個星期在上面找case,總共丟了4個case。

全都沒接到,連進入interview都沒有。

3個case被其他工程師拿走。

1個case得到recruiter答覆「I’m sorry, the client is considering only native English speakers.」

除此之外,從去年9月到現在,半年,我的profile都是保持開啟的,但是沒有case主動找上我。

只能說在上面接案的工程師不少,不是那麼好接。

我的中文能力會是優勢嗎?

目前客戶以歐美地區為主。

打開Join as a Client頁面,你會發現亞洲地區的公司想上去發case都不行。

所以,中文應該對接案沒什麼幫助。

申請加入要花多少時間?

會花不少時間。最後的project interview我花了大約2週,每天6小時開發才做完。

請參考我之前的文章:

TOPTAL申請經驗(上)

TOPTAL申請經驗(下)

加入要簽什麼樣的合約?

全部通過之後,會要求你用browser簽署一份電子合約。

其中關於隱私權(Toptal可以查看你在Toptal的Gmail信件內容)、商業機密的部份比較嚴格。

這有引起一些申請者的不滿,請參考:

My experience joining TopTal

合約上,我的時薪會是多少?

在申請的三次面試過程中會談到。

請參考官網FAQ:

How much does Toptal cost?

光看數字,比在台灣接案好很多。

以上,還有其他問題歡迎再來信詢問。

sharing

不如分享!

學生時代一起研究技術的幾個朋友,最近開始籌組co-writing blog。

他們都是極度有才華的工程師,blog上線之後一定會造福很多人。

寫blog分享的人永遠不嫌多,越多軟體工程師寫blog越好。

我從學生時代就一直這麼認為:不如分享!

讓我從三個角度解釋為什麼:

  • 排名與競爭的錯覺
  • 軟體工程師的本錢
  • 不必畏懼發表洞見

希望你看完之後,也會興起念頭:不如分享!

排名與競爭的錯覺

在職場上競爭,長期累積的個人實力,遠比短期內爭到的排名重要。

學生時代的十多年競爭排名經驗,卻是恰恰與此相反。

大學某年夏天,我見到同學拿著一份共同筆記要去影印。

我:「好厲害,你們幾個人一起做的嗎?可以借我看嗎?」

他一臉錯愕地拒絕:「共同筆記沒有在借的吧,這有公平性的問題。」

同年冬天,一個作業交不出來的朋友,臉色尷尬地問我:「作業該往哪個方向研究?」

我心想:「這傢伙是想跟我借作業吧!這好像有公平性的問題,對我不公平。」

然而,我又想了想:從這間學校離開之後,要面對的是全世界年輕人的競爭。

我今天幫助你學習,根本不害怕你反過來幹掉我,不然今天也不會是你向我請教。

但是你真的幹掉我又如何?那你一定掌握某種學習的訣竅,我到時再請教你就好了,

因為我是你的恩人,屆時你一定會無私報答我。

前者我根本沒吃虧;後者導致我變更強。穩賺不賠。

再說了,今天我排名比你前面畢業又如何?

面對全世界競爭的時候,我是用在校排名跟人競爭,還是用真正的實力跟人競爭?

最終我決定:不如分享!

從此一見到同學面有難色,作業直接遞過去:「拿去參考,要抄就抄。」

(但若被助教抓到害我零分,你就不用再跟我借了。)

更理想的期待是:如果大家都這麼做,那就是整個朋友圈一起變強、

整屆畢業生一起變強、整個國家一起變強。

軟體工程師的本錢

觀察了web programming產業一陣子,我怎麼看都是以「分享」為競爭的主舞台。

  • 若你在Stack Overflow有一萬分,業界怎麼評價你?
  • 若你在Github有一千顆星星,業界怎麼評價你?
  • 若你把洞見放在blog任人檢驗,業界怎麼評價你?

上面三點,不正是全世界軟體工程師奮力較勁的事嗎?

你在2015年,你在美好的產業:你不需要擔心技能被人學走而導致失去競爭力。

因為這行學無止盡、學習曲線沒有邊際效應遞減。

這就是軟體工程師的本錢:你只要擔心自己「分享的不夠用力」就可以了。

想找個與全世界競爭的舞台?不如分享!

不必畏懼發表洞見

不是業界大神,似乎就不應該寫blog?真是這樣嗎?

新手、中手就不應該發表洞見、暢所欲言他們的主張嗎?

國外工程師不都是互相撰文批評,然後讓圍觀的所有人一起學習嗎?

我在看一篇極具爭議的技術文章時,看到網友Zack打了很長一篇他的感想。

在我表達感激之意後,他回答:

Thanks. Writing helps me clarify my understanding.

對他來說,發表洞見不過是整理想法的一種手段。

同篇文章還有其他評論。網友Yannick Majoros留言:

Martin Fowler跟原po都只是毫無根據就愛發出噪音的幾個開發人員而已。

我看了大吃一驚,連忙追問:你哪來的資格批評Martin Fowler?你是認真的?

他回我:

我覺得他毫無學術根據。譬如說他對anemic models的抱怨就是一例。他不過就是有點經驗罷了。然後他試圖把個人意見說得像是事實一樣。如果原po把他的部落格文章寫成一本書,那就很像Martin Fowler那樣。

我根本不知道Yannick Majoros是誰、不知道他的實力、更不知道他的業界地位。

但是他這段話,對我就是極具啟發性。

讓我看完之後,更加覺得:不如分享!

(Photo via clappstar, CC licensed )

codeigniter-logo

CodeIgniter不是OOP好老師

寫完框架不應該有「MODELS」資料夾之後,

收到林先生來信如下:

您好, 我剛拜讀完您的「框架不應該有「models」資料夾」
我對文章的內容有許多地方不理解…不…可以說是混亂
我本身較熟悉的框架只有CI, 平時的撰寫模式就是將使用者的輸入放在controller做驗證, 驗證通過之後才會將之丟進model class(或是您稱呼的 entities)做處理, 丟進model class處理時會有一些除了真正該執行的任務外以外的行為(像是註冊新會員時我會需要檢查帳號是否已被使用或是不是黑名單), 根據model class 的回應結果決定controller該輸出什麼結果或view
然後我看到了「抽出行為邏輯變成Service Objects、抽出表單驗證邏輯變成Form Objects、抽出資料庫查詢邏輯變成Query Objects、抽出呈現邏輯變成View Objects…聽起來真棒,也確實很有幫助,不是嗎?」這一段, 您想表達的意思是否是將各種行為(驗證輸入資料、查詢/寫入資料庫或其他的行為邏輯)細分出來放在model(或像您所的依照專案/公司名稱做分類)底下, 而controller則是扮演操作這些entities角色?

我可以理解你的困惑,我可以理解你的混亂。

我有整整一年使用CodeIgniter開發。

當我第一次看到Reddit上頭大家的討論、當我第一次看到Laravel論壇的原始碼

我也是完全一頭霧水:這些人在用的PHP跟我在用的PHP是同一個嗎?

轉進Laravel社群幾個月之後,我終於知道問題出在哪了。請聽我娓娓道來。

CI不鼓勵你打造Entity

…驗證通過之後才會將之丟進model class(或是您稱呼的 entities)…

這句話不正確。CI的Model不是Entity。

…而controller則是扮演操作這些entities角色?

這句話不正確。service object, view object, form object都不是entity。它們是與entity相關的類別。

CI的Model並沒有代表「現實生活中的一種事物」,

它只是負責「把一張資料表的內容直接丟回去」而已。

以Blog Model舉例,假設它在資料表有title跟content欄位,但是沒有summary欄位。

如果我們需要文章簡介summary(由title加上content前100字組合而成),

在Laravel它會是這樣:

在Model之外用到Entity的時候,會是這樣:

你得到了$blog這個entity,它代表著一篇部落格文章。

這篇文章很樂意告訴你它的summary。

但是在CI呢?

從CI的Model拿到的東西,只代表「跟文章相關的一坨資料」。可以是Array或是stdClass。

並不代表一篇部落格文章,也無法具有「行為」。

CI的Model不是Entity。

我提到的Service Objects、Query Objects、View Objects都是圍繞著Entity打轉,而CI本身只幫你拉資料出來,沒幫你做Entity。也難怪會一團混亂了。

怎麼會這樣?

這裡的Entity說穿了就是將資料庫的資料轉換成物件而已。

可以自己寫Class手動將資料庫的value一個一個轉成物件的property。這麼做又麻煩又緩慢。

常見的作法是直接用ORM,可以是Data Mapper Pattern或是更常見的Active Record Pattern。

許多框架都會提供Active Record Pattern的實作,Laravel, Rails都是。

有Entity可以幹嘛?

可以讓程式碼更優雅。

我就直接拿View Objects、Query Objects、Form Objects做舉例了。

View Objects

這個View Object實作為例,

你可以把User Entity中只與「呈現」相關的logic抽出來成這種類別:

使用的時候這樣即可:

Query Objects

這個Query Object實作為例,

你可以把取得文章的多種不同方式logic獨立出來,成為這樣的class:

在使用的時候,只要這樣即可:

Form Objects

Form Objects倒是跟entity比較無關,但我還是舉例給你看它長相。

這個Form Object實作為例,

你可以把建立Article的表單驗證logic抽出來成這種類別:

在使用的時候,只要這樣即可:

以上,你會發現各式各樣的logic都可以拆分成獨立class,讓思維上比較OOP。

controller裡面的code可讀性也高很多。

這些在CI中比較難做到。CodeIgniter不是OOP好老師。

當然了,有些人很討厭OOP,對它一點興趣也沒有。看著辦吧。


Q&A

Q1: 可是CI有Active Record類別啊?

CI的Active Record類別是整個CI社群最悲慘的誤會之一。

CI的Active Record完全是叫爽的。

那根本沒有實作Active Record Pattern,只是個陽春的Query Builder(幫你打造SQL query的助手)而已。

CodeIgniter’s “Active Record” isn’t what the real active record is all about.

You’re also being lead astray by CI’s rather confusing name ActiveRecord, which actually doesn’t implement the ActiveRecord pattern.

CodeIgniter has a query builder it calls “ActiveRecord”, but which does not implement the Active Record pattern.

CI的狗屁Active Record就是一個對使用者有害、混淆觀念、沒人要點破、

大家不求甚解、為了行銷而存在的垃圾名詞。

業界不像學界嚴謹,大家永遠為了行銷在瞎搞,這種狗屁到處都是。

「MVC」就是其中程度最誇張的例子。

Q2: 我整篇文章都看不太懂,我現在更緊張了。

別急,慢慢來。OOP要寫得優雅,本來就非常不容易。

有空去摸摸看Laravel吧,感受一下,也許會有靈感。

有問題可以到Laravel台灣發問唷。


社群看法(2015-4-6)

PHP台灣