2011年4月2日 星期六

Problem Solving 的技巧 (2):別把解法當作問題定義

《真正的問題是什麼?你想通了嗎?》裡提到一點重要的觀念,別把別人的解法當作問題。最近累積了不少實例,比較能清楚地表達這個想法。

「把解法當作問題」的意思以及它帶來的負面影響

在分配工作時,為了減少溝通成本,常會隱藏一些訊息,只告訴合作同伴他「應該」知道的事,而省略了原始的動機和考量。問題在於,實際執行的人通常比對方清楚細節,很多問題在執行後才會浮現。但分配到工作的人不清楚前因後果,即使查覺不對勁,也無法 (或不願) 做出進一步修正。

好一點的情況,在分工前會先進行討論。然而,討論常會陷入各執一詞的局面,討論雙方作法優缺點後,會發覺找不到共識。實際上這只是眾多解法的兩個提案而已,若深入討論雙方作法背後的動機,各自預先假定的前提,會發覺尋找共識並不困難,畢竟,雙方是在解同一個問題。

在需求一樣,假設一致的情況下,兩個頭腦清楚願意討論的人,沒道理找不到共識,只是我們習慣省略前提,也沒先釐清需求,直接討論解法,才會覺得有個看不見的牆擋在中間,對話難以有交集,我不認同你認同的點,你也不認同我認同的點。

當我開始不預設立場後,看清楚很多事,我第一件事不是評斷大家作法的好壞,而是先問這樣做的考量為何?從考量的點會問出需求,從需求和考量的點會發覺矛盾,從而發現隱藏的假設。接著就能討論假設是否成立,或是不成立又會如何?很可能所有的點會重新洗牌,然後聚焦出更清楚的需求。

按部就班從需求討論各種作法,尋找大家認同的假設,接著在假設下收斂可能的作法,或是列出有影響但還不確定的點,然後評估何時由誰來釐清不確定的點,再來做更細的決定。這樣做下來,通常會有大家都滿意的成果,互動的過程中也會相處愉快。

以開發網站為例

舉例來說,A、B 要合寫一個網站,A 想用 PHP 直接寫,因為他覺得大家都會寫 PHP,寫起來也快;B 想用 Python + Django,因為他覺得日後比較好維護。

A 和 B 的想法都沒錯,但是一討論就陷入死結,這是很吊詭的事,兩個人想法都對,也在做同一件事,為什麼不會有共識?

這表示上述的論點一定有其中一點是錯的,仔細思考會發覺,其實 A 和 B 「沒有在討論同一個問題」,也沒有在同樣的立足點 (假設) 上討論。

  • A 可能假設時程很趕,沒有時間慢慢從頭學 Django,若他不會 Python,還得多學 Python,而且他可能不想學新東西,覺得 PHP 用起來沒什麼問題,為什麼要自找麻煩用別的作法?
  • B 可能假設學習 Python + Django 很簡單,即使時程很趕也還好,或是時程可以再談,沒有人說一定要什麼時候出來,在 B 認為可以來得及做完的前提下,B 認為要認真考量維護的事。

從 A 和 B 隱藏的假設可看出一些衝突:學習新東西花的時間成本、對於時程的認知、是否需要重視維護。而這些假設大概和 A、B 各自過去的經驗有關,比方說 B 收拾過用 PHP 開發的爛攤子,A 沒有和多人共同開發過稍具規模的專案。若 A、B 能和對方說明自己的前提,就有機會順著前提再討論為何有這樣的前提,彼此較能接受對方的看法。

然後再對照目前的需求,會發覺有些前提不再成立,或是更為重要。像是 A 當初收拾的爛攤子是別的因素造成的,可能是時程太趕或開發者習慣不好,主因不是 PHP。

將這些事都攤出來討論後,會發覺幾個立基不牢靠的推論:

  • 為了方便維護,要用 Python + Django。
  • 為了快速開發,要用 PHP。

這是將需求和解法綁在一起討論,但是實際的情況是,方便維護的作法不只有 Python + Django,快速開發的作法也不只有 PHP。視開發人員的經驗,將兩者反過來陳述也可能成立。

所以,真正考量的點應該是:

  • 先確定時程和功能需求,才能判斷開發速度要多快。
  • 確定日後是否需要擴充,擴充的程度和時程,從而判斷維護的成本。

然後列出相關選項,需注意的是,要依現有人員的能力列,而不是「一般」的認知。若時程不是太緊,可以先排時間評估各種方案,像是 Python 不只有 Django 一家 framework,也許可以考慮 Flasky 或 Pyramid;PHP 也不是沒 framework,若願意犠牲多一點執行速度,可以研究 PHP 的 framework;或是另找別的路,用 Ruby on Rails 或用 Java 體系的解法。

要注意的是,過猶不及,當考量的點過於發散時,不確定的點太多,沒有心力一一確認,討論會流於空泛。這時要列好需求,依現有人員的能力做些假設,先達成局部共識再繼續討論,比較容易聚焦。像是因為內部人員最熟 PHP 和 Python,用這兩者風險較低,所以只考慮這兩個體系的解法。

結語

類似的例子很常發生在日常生活的討論裡,不限於技術方面。隱藏的前提不見得都是技術議題,人性是很複雜的。關鍵在於別把別人提的解法當問題,自己也別預設立場著重在說明解法,而沒說明問題需求和自己的假設 (前提)。

在討論過於發散時,要先取得共識排除一些考量。即使共識的原因只是「不為什麼,我們都覺得不重要」,也是不錯的作法。可以先聚焦往後討論,待討論到後面有更明確的想法,或是再和第三個人討論時,可能會查覺原本的前提有問題,這時再回頭修正它們,重新沙盤推演一遍,得到更確實的解法。有了紮實的共識,清楚各項決策的前因後果後,之後遇到各種變動,都能迅速明確地處理。