從買蘋果看工程師和設計師的差別?

高中的時候,有個留級的朋友問我,你會不會覺得唸這些東西一點用都沒有。書呆子的我,帶著疑惑問:「為什麼會這樣覺得?」但現在過了 15 年,我真的很想問那時候的我,為什麼不會這樣覺得。

1
2
工程和管理的訓練是解決問題,而設計師受的訓練是發現真正的問題。
--- from 設計的心理學 by Donald A. Norman

聽到「幫我買一顆蘋果」這個問題,工程師會這樣做。

1
2
3
工程師:花一小時,找出一大堆的購物網站,列出各種蘋果的價格和評價,然後請你挑最好的一個。

妹子:我只是想和你見個面聊個天,為什麼我必須要看那麼多資料... 而且還要我上網訂、見不到面,還是放棄治療好了。

聽到「幫我買一顆蘋果」這個問題,設計師會這樣做。(這邊設計師不含 VD)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
情況一:
問:你為什麼要買蘋果?
答: 因為想幫房間增加一點紅色。
問: 為什麼想幫房間增加一點紅色?
答: 因為想把房間變漂亮?
解: 設計師把房間的燈從冷色系換成暖色系。

情況二:
問:你為什麼要買蘋果?
答:因為我肚子餓。
問:可是你不是剛剛才吃完飯?
答:嗯,對喔。(OS: 我只是看你太閒,要給你一點事做。)

情況三:
問:你為什麼要買蘋果?
答:因為要吃。
問:你為什麼要吃?
答:我每天都要吃一顆,今天沒帶。你廢話那麼多要幹麻?(OS: 這個下屬理由很多。)

工程師和管理把問題往下展開。
設計師把問題往上展,如果找到更簡單的問題再往下展。

工程師:直接把問題往下展開:

1
2
優:能最快速找到這個問題的解法。
缺:你解決的可能根本不是重要的問題。

設計師:把問題往後回推,找新問題解

1
2
優:也許能找到真正需要解的問題、花更少的時間就能解決問題。
缺:別人會以為你不想理他在找藉口。老闆會以為你在故意質疑他。如果原來的問題本來就是對的問題,你只是在浪費時間。

理性與感性

1
2
「現階段的實際工作中,設計師們無論是在方案的設計還是方案的表達上,往往都顯得感性有餘、理性不足。」
--- by 汪方進 @ 阿里巴巴 1688用戶體驗部

一個設計師,不光只有同理心、邏輯推理能力、各種知識也很重要。沒有知識不能推理啊… 所以工程師們快和我一樣跳進來吧~~~ 當設計界的理性之光。其實就演算法的角度來看,就是兩種不同的方法,各有各的使用時機、各有各的風險報酬,如果要能解決生活中的問題,這兩個都很重要。所以也別分什麼工程、設計、商業,如果有需要就學吧。大學四年可以學一個專業,但人生有多少個四年啊… 是不是該多學幾個專業 XD

註: 把視覺設計師(VD)和程式設計師特別切出來的原因是:他們的工作都偏向在給定的問題中找解法、做的是實作中一定要做的事。但真正優秀的會去觀察使用者。(工程師的話推薦看:程序員的修煉、駭客與畫家,都有提到這點)

註:上面的對話都是我的想像舉例,別太認真。想知道真正答案的話,或是測試這個人的工程設計傾向,可以請他幫你買顆蘋果看看。

淺談函數式編程和 React

函數是有定義介面的運算單元。

介面有用的地方是抽象化,你只需要知道輸入什麼(Input)、會得到什麼輸出(Output),你不用知道它細節是怎麼做到的。其實有個超能力在背後,也沒關係。當然這是在沒有碰到 bug 和有良好文件、不需要修改它的前提之下。

再強調一次,你只需要理解輸入(input)會對應到什麼輸出(output)就夠了。

問題來了,怎樣的輸入和輸出的對應「介面」會容易讓人理解?

  • 有意義的函數名稱

  • 多寫沒有副作用的純函數

    • 有可預測性:
      每次輸入得到相同的輸出、函數內部不存狀態
    • 沒有副作用:
      運算過程中不會改到外界的變數,像是不改傳進來的參數、不改可以存取的全域變數。
    • 顯式(Explict):
      函數和外界溝通的管道只有,傳進來的參數和回傳值。
  • 簡化參數、對資料結構的 Information Architecture 做良好設計

  • 用函數來定義函數

    • 柯里化(Currying):
      透過不同給參數來產生新的函數
    • 合成(Compose):
      透過 pipeline 串接函數的input和output、隱藏參數,產生新的函數。

函數式編程為什麼強大、有彈性?

  • 把每個函數切得很小,容易更新、維護、平行處理、多人共同開發、被理解

  • 透過合成(Compose)把小函數變成大函數,比用繼承有彈性的多

  • 對集合實做 Functor 介面,讓一般函數都可以對集合操作。(array, matrix, tensor)

  • 把純和不純的函數分開來管理,容易找到問題點。

函數式編程為什麼難寫?

因為函數式編程想要把程式變簡單。但大家都知道「變複雜是簡單的、變簡單是複雜的」。所以這種方式寫程式需要設計、思考,你會是一個程式「設計師」。但如果你現在的專案寫完之後沒人會看、不會再改、不用維護、規模不大,也許函數式編程並不能幫到這個專案多少。

寫 React 就是實踐函數式編程

  • 透過自定義元件,定義畫 View 的抽象化函數樹

  • 透過 JSX 語法把小函數組合成大的函數 (等同於 compose)

  • 鼓勵大家寫 dumb 元件、也就是純函數

  • 用唯讀的 props,限制大家不能改傳進來的參數、減少副作用

  • 透過導入 flux,把純和不純的函數分開來管理

    • 純的 (對資料只做讀的動作):每個元件中的 render function
    • 不純的 (對資料做讀和寫的動作):
      flux中對 action 的 callback、redux 中的 reducer、父元件傳給子元件的 callback
    • glue code:元件中其他的 javascript

從函數式編程的角度看 React 的問題?

  • 沒有什麼高階的集合操作方法:

    • 把 lodash.js 集合操作拉進來用?
    • 用 lenses 的方式來穿透深長不露的 states?
  • 沒有簡單的 currying 語法

    • 像是傳不同參數給 html5 input 元件,生出各式各樣對數字的、email、submit、text的自定義元件。最簡單寫法應該是
    • export function NumberInput(props) { 角括弧input type=“number” {…props} /> }
    • PS: function 一定要有名字不然 debug 會很慘。
  • 雖然集中管理了不純的函數,但還是很難寫:現在透過修改 store 中的 state 來控制元件,這邊 action 觸發的都是不純的函數,如果元件架構一深,還是會很難改。有解嗎?這邊還沒找到什麼 coding guideline…

    • 多個 container smart 元件
    • flux 的多個 store
    • redux 的階層式 reducers

延伸閱讀:
deku: functional alternative to react
how to use classes and sleep at night (in a functional way)

Hey Underscore, You're doing it Wrong! (介紹函數編程)


Curried Function:到拿到所有需要的參數前… 一直回傳新函數的函數。
1
2
3
4
5
6
7
8
9
10
var add = function(x) {
return function(y) {
return x + y;
}
}

var add3 = add(3);
add3(4); //return 7

add(3)(4); //weird thing

autoCurry in Wu.js will save us
1
2
3
4
5
6
7
8
var add = function(x, y) {
return x + y;
}.autoCurry();

var add3 = add(3);
add3(4) //7

add(3,5) //8 => not weird any more!!!

但我們為什麼需要 curry?參考下面這個組成新 function getTheOdds 的例子。 有了currying,我們可以透過給予不同參數來建立新的函數。
1
2
3
4
5
6
7
8
var filter = function(f, xs) {
return xs.filter(f);
}

filter(isOdd, [1,2,3,4,5]) // [1,3,5]

var getTheOdds = filter(isOdd);
getTheOdds([1,2,3,4,5]) //[1,3,5]

再來一個用loadash的酷例子
1
2
3
4
5
6
7
8
9
10
11
12
//沒用currying、不函數化的寫法
var firstTwoLetters = function(words){
return _.map(words, function(word){
return _.first(word, 2);
});
}

//函數化的寫法(如果underscore吃參數的方式是反過來的話)
var firstTwoLetters = _.map(_.first(2));

//更函數化的寫法
_.map(_.first(2), ['jim', 'kate']) //['ji', 'ka']

=> Underscore.js的參數排列法讓currying變得不可能 總結currying的優點有下面四個:
* 一般化函數、要傳的變數名消失了
* 透過給不同參數就可以生成不同的函數
* 更簡潔的定義
* 讓函式的組合/合成 (composition) 變的可能

組合/合成 (composition):用多個函數來組成新函數 簡單的例子,用 first() 和 reverse() 來合成 last 函數
1
2
3
4
5
6
7
8
var last = function(xs) {
var sx = reverse(xs);
return first(sx);
}

var last = compose(first, reverse);

last([1,2,3]) //3

另一個例子,chain backwardly
1
2
3
4
5
6
7
var wordCount = function(str){
var words = split(' ', str);
return length(words);
}

var wordCount = compose(length, split(' '));
wordCount("There is a way to save the world") //8

Category Theory: 多個函數組合(compose),作用域互相對應的理論。Connecting the dot. 總結組合:
* 能從其他函數組成新函數
* 組合過程中把參數藏起來
* 極為高階的寫程式
* 有數學理論在後面支持

Functors map 打開了後面的 object 然後做一些事、再放回 object

1
2
3
4
5
var plus1 = function(x){ return x + 1 }

plus1([3]) //wrong!!

map(plus1, [3]) //4

剛剛舉的例子,map 只能操作 array object、但下面試圖用 map 操作所有 object

1
2
3
4
5
6
7
8
9
map(plus1, MyObject(3)) //MyObject(4)

MyObject = function(val) {
this.val = val;
}

MyObject.prototype.map = function(f) {
return MyObject(f(this.val));
}

如果對 object 定義了 map function,它就變成 functor null check的例子、Dynamic Safety:

1
2
3
4
5
6
7
8
9
10
11
map(plus1, Maybe(3)) //=> Maybe(4)

map(plus1, Maybe(null)) //=> Maybe(null)

Maybe = function(val) {
this.val = val;
}

Maybe.prototype.map = function(f){
return this.val ? Maybe(f(this.val)) : Maybe(null);
}

把 ES6 promise 變 functor 的例子

1
2
3
4
5
6
7
8
9
map(populateTable, $.ajax.get('/posts');

Promise.prototype.map = function(f) {
var promise = new Promise();
this.then(function(response){
promise.resolve(f(response));
});
return promise;
}

再來一個和 html 合作的例子:對有和沒有 user_login 的情況下,更新歡迎頁面。

1
2
3
4
5
6
7
8
$div = $("#myDiv");

//dot 會把 user.name 拿出來
var getGreeting = compose(concat('Welcome '), dot('name'));

var updateGreetingHtml = compose($div.html, getGreeting);

map(updateGreetingHtml, Maybe(App.current_user));

underscore 不讓人 extend map 總結 functor 能:

  • 改變函數的行為卻不用變動 open/closed principle
  • 不光只有 map, 還有 reduce & compose *
    直覺且非私人的 api
  • free formulas
  • 動態型別安全/檢查

總結:underscore 能變得更加 functional。希望有更 functional 的 library

什麼是設計?

 [Design Q&A by Charles Eames](http://www.scielo.cl/pdf/arq/n49/art11.pdf) 中譯 Q: 你對設計的定義是什麼? A: 人們可以將設計描述為安排元素來達到特定目的(purpose)的計畫。 Q: 設計是一種藝術的表現嗎? A: 我寧願說是一種目的的表現。它可以... 如果它足夠好,之後會被判斷為藝術。 Q: 設計是一種為了工業目的的工藝嗎? A: 不是,但是設計也許是某些工業問題的解。 Q: 設計的限界是什麼? A: 問題的限界是什麼,設計的限界就是什麼。 Q: 設計是只關注一部份環境(environment)的學科嗎? A: 不。 Q: 它是一種通用表達的方法嗎?(Is it a method of general expression?) A: 不,他是行動的方法。 Q: 它是一個人的創造物嗎? A:  不,事實上每個人都會受到前人的影響。 Q: 設計是團體的產物嗎? A: 通常是。 Q: 有設計倫理嗎? A: 設計總是有限制,通常也包含倫理這項。 Q: 設計意味著產品是有用處 (necessarily useful) 的嗎? A: 是的,即使用處可能很微小。 Q: 人們可以光為了樂趣的作品合作嗎? A: 誰會說樂趣是無用的? Q: 設計的過程中要承認限制嗎? A: 設計和限制有很大的關係。 Q: 什麼是限制? A: 設計問題的有效關鍵:設計師能辨識出越多限制越好、他的對於這些限制一起工作的意願和熱情。限制像是金錢、大小、強度、平衡、表面材料、時間。每個問題都有它自己限制的列表。 Q: 設計是短暫的嗎? A: 有些需求是短暫的。大部份設計是短暫的。 Q: 該朝向短暫還是永恆的設計前進? A: 如果是一般性、通用的需求和設計,會朝向永久。 Q: 設計是為了誰? A: 需求。 Q: 你曾經被迫接受妥協嗎? A: 我從未被迫妥協,但我樂意接受限制。 Q: 練習設計的首要條件是? A: 辨認需求。(Recognition of the needs.) 看完影片大概知道,設計和目的、需求、問題、限制是息息相關的。 --- 接下來看維基百科上對  Design 的定義。定義來自這篇 paper - [A Proposal for a Formal Definition of the Design Concept](http://paulralph.name/files/2011/01/Ralph-and-Wand-A-Proposal-for-a-Formal-Definition-of-the-Design-Concept.pdf) by Paul Ralph et. al.  他提出來的定義如下
Design (noun) a specification of an object, manifested by an agent, intended to accomplish goals, in a particular environment, using a set of primitive components, satisfying a set of requirements, subject to constraints; (verb, transitive) to create a design, in an environment (where the de- signer operates) 
看了應該不知道想表達什麼,所以他畫了張圖,這樣就清楚多了。
[![](https://1.bp.blogspot.com/-K0vsaB6GQhA/VoVUNkNudHI/AAAAAAAA3-M/vXrBqNi2RSk/s640/Screen%2BShot%2B2016-01-01%2Bat%2B12.12.58%2BAM.jpg)](http://1.bp.blogspot.com/-K0vsaB6GQhA/VoVUNkNudHI/AAAAAAAA3-M/vXrBqNi2RSk/s1600/Screen%2BShot%2B2016-01-01%2Bat%2B12.12.58%2BAM.jpg)
Agent 是設計的人。 產出(Output):對某個物件的規範/規格 然後這個 Output,要完成某些目的 (Goals)、受到某些限制、滿足一些條件、產出在某個環境、由一些元素所組成。 舉例來說: 平面設計:指的是設計的的產出位在的環境是 2D 平面。 服務設計、字型設計、介面設計、使用者體驗設計、服裝設計:指的是它們的產出 (Specification of Object) 是什麼。 物件導向程式設計:指的是 primitive components 是物件、產出是程式。 使用者導向設計 (UCD):指的是設計的產出的目的 (Goal) 和使用者有關。 作者進一步用動詞來看設計,畫了這個圖,清楚地標明什麼是設計這個動作的輸入 (Input) 和輸出 (Output)
[![](https://3.bp.blogspot.com/-mTegFAuq6xU/VoVWkm1N2pI/AAAAAAAA3-c/Djps-IbKZ2g/s640/Screen%2BShot%2B2016-01-01%2Bat%2B12.22.32%2BAM.jpg)](http://3.bp.blogspot.com/-mTegFAuq6xU/VoVWkm1N2pI/AAAAAAAA3-c/Djps-IbKZ2g/s1600/Screen%2BShot%2B2016-01-01%2Bat%2B12.22.32%2BAM.jpg)
最後他又把這個圖改寫成設計的新定義
design activity as a process executed by an agent for the purpose of generating a specification of an object based on:  > the environment in which the object will exist,  > the goals ascribed to the object,  > the desired structural and behavioral properties of the object (requirements),  > a given set of component types (primitives),  > and constraints that limit the acceptable solutions.  有沒有很複雜?簡單說 「設計活動就是在某些限制下,生出某個東西來達成某個目的的過程。」 好像在說廢話有沒有~~~ XD

台大不一樣思考社:設計思考工作坊 Day 2

組合虛擬人物 (CC)

第二天一早 Recap 的方式就是,從前一天的三個人物中合成一個叫 Jessica 的虛擬的人物 ( Composite Character ),這部分是很主觀的,先基於從現有列出來的 needs 和 insight 選出覺得有發展性的點。最後再藉由腦補內容、畫使用者畫像,像是 Persona 一樣把虛擬人物立體出來,因為花了一整天生出來的人,大家其實對他很熟悉 ( 比隨意的 Persona 熟的多 )。

腦力激盪  (Brain Storming )

CC有幾個 insight,最後選的 insight 是現代人會 Do something 來填補早餐的空白時間、像是滑手機,所以腦力激盪的目標變成就是想出一個「讓早餐時間不是空白時間」的方法。之後就是「不批評」「不打斷的」「不離題」的 Brain Storming 了。因為有了 Jessica,這個每個人都熟悉立體人物,**溝通**的時候變得方便很多,就像是有了使用者的原型一樣。Brain Storming 就是爽爽的啊,不過這次特別強調了「要延伸」他人想法、「要畫圖」要有「Title」等重點。

發想的差不多後,用「強迫聯想」的方式做 Brain Storming,這部分也是蠻新奇的,先列出「教室」和「辦公室」裡的不相干用品,然後強迫生出可以滿足人物 insight 的想法,這邊會先卡住,然後只要有人開始分享,就會變得很多神奇的想法出來。最後再把所有的想法大概有 100 個吧,一人數票投票列出幾個、然後在二次投票,二次投票的時候才想起 Jessica,想哪一個想法比較可能滿足她。最後選擇用動的食物吸引注意力的迴轉壽司早餐。(好像是小隊輔提出來的… XD) 還有設定要驗證的幾個小想法,像是少量食物、多樣組合 blah 的

製作原型 (Prototyping)

快樂的 30分鐘 maker 時間,高級的扮家家酒和演戲,多次試驗。大家都玩開了~ 我只能說大家的手做能力很強大。

請使用者測試 ( Testing )

這步真的讓我看到 Prototype 的威力所在,第一個使用者就發現這個原型對使用者的感覺,雖來一進來就盯著移動中的食物,但跟我們思考的不一樣。因為迴轉壽司早餐比較像是有空閒時間才會去的地方,對想省時間的使用者。另外還有會發覺原型的問題,像是輸送列應該一開始就要有早餐在上面、最好加上文字說明。除了輸送列的早餐外,還要有菜單、送茶水的服務生不用帶位,特別強調是週末,悠閒的週六早上十點之類的情境。修一修加上演戲,原型多少有解到空白時間的問題,在第一個 iteration 應該算是不錯吧。

各小隊火力展示 ( Demo )

很意外的是其他六隊都做 App,而且有試著嘗試去解我認為早就被解完的問題:「有效率地得到早餐。」本來以為台灣早餐店林立、便利商店林立,早餐不用跑很遠、更不用自己做,還會剩下什麼需求沒被滿足嗎?結果是「熱騰騰好吃的早餐店要排隊」,於是就寫個注重體驗的訂餐、捷運門口取餐的App,然後第一次實體看到 App 的 Prototype長什麼樣子,點點點、換頁之類的,想到我做網頁、寫 App 錢真的也該先做好 Prototype 找個使用者來用用啊~~~

結語
這個工作坊是個團隊討論、體驗設計思考流程的好地方。本來以為價位有點高 ( 和我以前辦其他社團活動比 )。不過看到一組請三個陌生人使用者來受測、中午吃的還不錯、設計 conference 都很貴、1:2 的教練學員比,總總因素來說是 C/P 還不錯的。列一下 pros and cons:

pros:

  • 可以深入的練習觀察技巧

  • 思考使用者的需求和需求背後的原因

  • 快樂的團隊思考、討論體驗

  • 大量便利貼的利用技巧

  • 得到一種完整的設計流程體驗

  • 真實的和使用者接觸

  • 小隊輔們還蠻用心的

  • 可以碰到許多願意用溝通、用設計改變世界的人

  • 小遊戲很好玩

  • 一直放舞曲很High
    cons:

  • 和現實真的有一段距離 (感覺 TA 是學生)

  • 像「人本機構」的只鼓勵、不批評的環境讓「擁抱失敗」變成口號。

  • 建立「需求」、「insight」、「CC」,的過程中用了大量的假設,推論一錯就 GG

  • 完全不做現有解法的比較與調查 (像是摩斯訂餐 App)

  • 不介紹失敗的例子

  • 過度強調人本,但除了人的需求。技術和商業的重要性都不說明,一個好的偵探除了觀察和推理能力,對事物的知識也是很重要的。

  • 只有練習三個人以上的團體技巧。

    有點小進步,不過感覺和 Design Researcher 的路還有好遠好遠。
    最後有點太專心討論和解題,好像沒有好好認識其他人啊,有點可惜~

心理系的小隊輔一江、設計感的 Jarah、到處出現的 Boy、強大的設計師 美辰、很有主見的獸醫系 元皓、講話有趣的東璋、眼鏡很帥的財金系 軒凱、討厭心智圖但會組織演講的柏儒,這次有點忘記一期一會的決心…

記得感到痛苦和累的時候,稱讚一下自己吧「你努力離開舒適圈了喔 :p」

台大不一樣思考社:設計思考工作坊 Day 1

和藝術不同,設計是一門客觀的學問。重視觀察、基於觀察做出像偵探一樣的推論、做出像科學家一樣的假設,用同理心而不是同情心去理解這一個人的行為和需求、從使用者的角度去看這個世界。

問題是和需求是不同的:

從8層樓高優雅的降落到地表不受傷是一個問題。但大多數人這輩子都不會有這樣的需求。

需求要用動詞來描述而不是名詞: 需求:「吃到好吃的早餐」 => 人自動會把行動連接成
  1. 怎麼 「吃到好吃的早餐?」
  2. 為什麼要 「吃到好吃的早餐,原因是什麼?」需求「好吃的早餐」 => 推理就的莫名其妙的卡住,加上 5W1H 都很不順!

今天請大家解的題目是「如何提升吃早餐的經驗」。

流程:
   1. 先用便利貼討論要訪談使用者的問題、把相近的問題Group後,針對每一類問題畫正字投票.

   2. 街訪:會有一個主訪、副訪和紀錄。大概十分鐘,主訪負責掌握進度、副訪負責見縫插針。

   3. 把數個人紀錄的資訊口述下載,每個人寫下事實 (Fact) 到便利貼上 & 分類。

==== 以下開始小組討論、瘋狂的 blocking I/O 超花時間,為什麼不繼續平行計算啊 ====
   4. 試著從事實 (Fact) 中,推出這個人的需求 (need)
   5. 從這個人的需求 (need),找出洞察  (insight)

[來到了 long long complain section]
一人一票決定街訪問題,真是不太好,就是一種讓人膚淺思考的快速解決方式吧、然後想問題的時候,好像沒有一個比較好的想法,怎麼問會得到提升早餐經驗的資訊,不過強調 empathize 那這次就不預設立場試試吧

從列需求就一直卡,用動詞描述真的很重要 ( 回家才看文章才懂 ),然後訪的幾個學生都不是很愛吃早餐,他們的簡單需求早就在這個台灣早餐文化發達、便利商店充斥的環境滿足了。還說「提升早餐體驗」是簡單題目,結果需求列完,洞察完全列不出來。需求出來就解啊,為何要落在為做「設計思考」強說洞察的陷阱裡,Inception 一定要下到第幾層嗎?不過別組有些很順利的,希望明天報告的時候能搞清楚,我們和別人不同在哪?做錯了哪一步?

另外一個是「提升早餐體驗」的題目定下來了,我們不知道客戶是誰、沒有辦法詢問客戶,沒法想問題背後的問題 / 找到真正要解的問題。然後一開始也沒決定是要生產品還是服務,也沒有定好 TA。最後我們這組 TA 好像是學生,但如果要解這個問題,自身的經驗、非訪談的觀察就不能使用。

然後很討厭,台上報告有事沒事後面工作人員就很 high 的附和之類的,做設計一定要這樣搞嗎?不過開始前玩小遊戲提神真的還不錯。

現在的想法就只有,使用者都想跟朋友一起吃早餐,那就請宿舍早餐店提出兩人同行,第二人早餐六折的優惠,這樣所有人的體驗都會好,早餐店也會比較賺錢。


現在只能安慰自己,花了 1,600 元兩天就發覺 Design Thinking 沒啥用,也是不錯的收穫,反正還有一堆其他的設計流程。 UX 這條路 QQ 回家重看了設計的心理學的 Design Thinking 一章,特別強調不要用訪談耶…Orz

Don’t try to be original, just try to be good.
I don’t want to be interesting, I want to be good.
( 不一樣思考又怎樣啊… 解問題為什麼不先 google / survey? )

明天就是嘴砲的 brain storming~ to be continued.

延伸閱讀:
像福爾摩沙一樣解決社會問題 (同情心、同理心、觀察力)
Problems Are Not Equal to Needs
Don’t try to be original, try to be good.

Firebase:前端工程師的神兵利器

Firebase.com 像其他的「後端即服務」( Baas, backend as a service ) 一樣,不過他的 Tutorial 超簡單,你只要會用 node 的 npm 大概就夠了。

Firebase官方超簡短教學,看了這個我就被吸引住了。

React 讓人解決 MVC 中的 View。Firebase 讓人不用建 server、遠端登入,只需要用 web user  interface 就建出以 Json 為格式的即時資料庫、Rest Web API、One command deploy ( firebase deploy )、社交帳號的管理 ( Oauth 介面的 Facebook、Google、Twitter blah blah 的登入管理) ,還有靜態 CDN 資料發佈、Custom domain mapping ( 這個要花一點時間等 DNS Propagate )。

Firebase.com 去年被 Google 買走、Parse.com 前年被 Facebook 買走、Apple 也推出了自家的 CloudKit,這些「後端即服務」的公司,讓你 **不用再管 Server & 資料庫**。你只需要有整理資料的能力 ( Structure Data ) 和前端設計的能力,就能當全端工程師了 :)

各家都有基本的免費流量,一個月 100 GB ~ 2TB 都有,但一旦升級之後就會變很貴喔 要小心。簡單說,以後 Hackathon 不用找後端工程師了,也不要再傻傻的去 github 找看都看不懂的 Hackathon Starter Kit。


真心覺得,Startup 剛開始用 Baas 就好,省 Server 和後端工程師的錢。

React UI 心得文之一

這週在忙著刻一個大元件,中間有包兩三個中元件、然後中元件下面又會有小元件。要記得React 是負責 UI 的啊,千萬個不該在小元件裡面存 state。存了改了兩天還是會有問題,小元件如果存了狀態,常會有那大元件重 render 的時候,設 property 卻無法更新小元件,因為小元件的 state 不一樣了。兩天之後把大中小元件全部改成 dumb component 真的快樂的不得了,程式碼變少了、邏輯也清楚了。


刻 React 元件的方法:

  1. 盡量刻 Dumb Component,把它當成 function 去想要提供什麼參數

  2. parent component 要對 child componet 命名和設 handler(childId, value)

  3. 事件發生時就呼叫 parent 傳來的 handler,說你是哪個 child和發生了什麼

    就這樣遞迴做下去,最上層的 App component 就可以知道,哪第三個child component 的第四個 child component 發生了什麼事,然後做一些處理。


    客制化 React 元件外觀的方法:

  4. 幫元件的各種 property 類別放置對應的className

  5. 用 webpack 的 css loader 幫元件建立 local 的 css scope,然後用一個 scss 檔去管理一個元件,這樣一切都會輕鬆的多。( 參考 React Toolbox )

    其他刻外觀小心得:

  6. 多用 em, rem

  7. 用 css 幫背景上色的方式,快速看物件是否對齊

  8. 用 Mac 的放大鏡 ( ctrl + 雙指滑動 trackpad )

  9. 用 css trick cursor 去引導 behavior

  10. 用 font-weight 和 color 的 alpha channel 去做細部微調

    學各種 React 相關 Library的方法:一定要**從看完官方的 Tutorial/Guide 開始**,網路上的介紹文章通常都挑簡單的地方說,十篇有九篇都講一樣的東西,還不如看官方的 Tutorial/Guide 把重要的東西有系統的一次學會。很重要所以特別粗體一下…

    使用者經驗部分:

    碰到客戶想要重新客製化系統的時候

  11. 照他們舊有的行為,模擬跑自己刻的新系統幾次,很快就可以知道缺了什麼、哪裡會生出問題,這樣的方法比在那邊天馬行空的猜測會方便的很多。例子: 新報表系統拿舊系統的許多報表重新打一次。

  12. 用心智圖的方式窮舉可能的行為,不然光是用腦袋想一定會漏掉很多細節。


    和他人合作的部分

一定要定時 Sync 進度,時常 commit。不要隱匿進度落後、缺失、維護 local state,想說這樣可以加班追回來。因為很多事從他人的角度來看會清楚的很多,也方便別人調整。不要裝弱、裝強,快放棄那沒用的自尊心吧。

聊預測自己未來的能力

比起預測下一期大樂透號碼的能力,這邊說的「預測未來的能力」跟「對未來的想像力」比較相關,是更日常生活相關的能力,。

這個故事是我最近一個月經常發生的事,剛剛又發生了。我經常會有沒洗澡就睡覺,隔天要出門去咖啡館寫程式的情況,這時就想還是洗一下澡好了、但為了時間還是不要洗頭好。但進入浴室在熱騰騰的蒸氣中間,就會想熱水洗頭會很舒服,然後就洗頭,舒服的回到房間,吹個頭舒服的弄很久才出門。然後隔天出門時又做了一樣的規劃,嗯 洗澡但不洗頭。

這故事跟個人工作能力無關,但卻大大了影響了我工作的計畫和效率。我缺乏的是清楚地理解自己在不同環境中,會受到怎樣的環境影響,就簡單地做出計畫。

如果我清楚地想像就算「現在做了決定不洗頭,等下還是會洗頭」,那在趕時間時,我就會決定不洗澡就出門。如果我清楚地想像到「現在在浴室中洗了頭,會舒服到等下在房間吹頭髮、花半小時東摸摸、西摸摸」,那我可能就會忍住不洗頭。

在這個小故事中影響不大。但在現實工作中,一樣會有這樣的情況。像是被問「這東西下個禮拜做得出來嗎?」腦袋中的想像是每天加班,努力工作,然後下週準時交差。但現實是,加班個兩天,發生了一些問題、或是加班三天後沒心情工作,這些都和你寫程式的能力無關,但卻會在你承諾的時間交不出東西,拖累整個團隊。

對自己能力過於樂觀的估計是大忌!!! 會拖累他人進度。

對自己能力過於悲觀的估計是大忌!!! 會拖累自己成長步調、不敢嘗試。

這種想像力、對過去歷史的記憶力、也許是可以訓練的。再不然只對自己一定能預測正確的情況做預測,其他情況就清楚明白的放在「不知道」這個類別。

俗話說得好「人貴自知,知己者明」。
努力認識自己吧~ 培養自知之明。

參考:《老子》第三十三章:「知人者智,自知者明;勝人者有力,自勝者強」

BTW, 這個能力是很容易被觀察的,只要看一個人有沒有準時完成他的承諾就知道了。

程式設計法與人生 (Programming Paradigm and Life)

解決問題流行的方式有兩種。
  1. 想出第一步要做什麼,然後開始做、做完再想下一個。
  2. 是把大問題切成數個小問題一直切到夠小,然後再一個一個做。
    第一個 叫做命令式程式設計、第二個 叫做宣告式程式設計。
    第一個 想要回答「怎麼做」、第二個 想要回答「做什麼」。
    第一個 是工程師做的事、第二個是設計師做的事。
    第一個 叫做敏捷式開發流程、第二個 叫做瀑布式開發流程。
    第一個 叫做 connecting the dots、第二個叫做 設計研究。
    第一個 叫貪婪演算法、第二個叫分治演算法。
    第一個 叫活在當下、第二個叫有遠見。
    第一個 把問題序列化、第二個把問題 心智圖化。

    用第一種的人想出了外掛 - 設計模式 (design pattern)
    用第二種的人想出了外掛 - 狀態機和不變資料 (state machine + immutable data)

    還記得大二演算法排序的作業,標準解法是先做第二個 (qsort)、然後問題變小了就接第一個 (shell sort)

    各有各的使用時機,冷靜分析後我從函數式編程的信仰者回到無神論者了。
    第一個適合許多未知、經常變動的問題。
    第二個適合有固定答案、行為可預測的問題。
    嗯嗯 不過當然用 react 還是比其他好 XD --- 目標努力 iterative 的 functional programming~  => 每次用第一個方法切一小塊問題,用第二個方法解。