iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 16
1

良好程式碼的優點大同小異。
不好的程式碼的糙點卻各有巧妙之處。

-- 台南原地方法院,最棒的古蹟修復案例之一。基本的從外觀的牆面油漆去除,到馬薩式屋頂的木構造修復。建築最美的雙重圓頂與大廳裝飾,都原汁原味的重現在現在的古蹟內。不只是外觀修復得很美,連內部的構造都依原本的構想,聽說是以零件抽離一件修復一件的方式修復,以確保正確性。也是台南唯一開放貓道,可以參觀馬薩式屋頂木構造的古蹟,長達八年的修復已完成,現在是台南司法博物館。

在說了什麼多的「不要這麼做」之後,偶爾也來寫一下「那要怎麼做」比較好。
這次花一點篇幅來介紹 function 怎麼寫,比較好。(好像語法工匠)
在《忍者》[1]第一版中,直接就指出 JavaScript 的 function 有 4 種

  1. 一般的 function
  2. method: 物件中的 function
  3. constructor: 建構物件的 function
  4. recursive: 呼叫自己的 function

(ES6 之後,加上的 arrow function ,請看《忍者2》)

內聚性

今天就來講個和內聚性有關的笑話來談談的內聚性吧

問題

依序回答下面的

  1. 如何把長頸鹿放進冰箱
  2. 如何把大象放進冰箱

想到了嗎?
再想一下








(這沒有在灌水)










答案

用這個例子來說說

如何用一般般的程式碼表達
如何用高品質的程式碼表達

int main
{
    把長頸鹿放進冰箱();
    把大象放進冰箱();
    return 0;
}

如何把長頸鹿放進冰箱

void 把長頸鹿放進冰箱()
{
    把冰箱打開();
    把長頸鹿放進去();
    把冰箱關起來();
}

如何把大象放進冰箱

void 把大象放進冰箱()
{
    把冰箱打開();
    把大象放進去();
    // 忘記把長頸鹿拿出來!
    把冰箱關起來();
}

糙 code 的警報又響起!!!

「糙!誰知道!!!」 (重點是「誰知道」是耦合的警訊)

所以改成

void 把大象放進冰箱()
{
    把冰箱打開();
    把長頸鹿拿出來();
    把大象放進去();
    把冰箱關起來();
}

這樣就結束了嗎?

這樣還是糙!!

因為沒有消除耦合,你只是知道,並沒有消除它。
下一個開發者還是要先看實作細節,才可以了解這個耦合的樣貌

那要怎麼做呢?

高品質函式的做法

int main
{
    把動物放進冰箱(長頸鹿);
    把動物放進冰箱(大象);
    return 0;
}
void 把動物放進冰箱(animal 動物)
{
    把冰箱打開();

    if (!冰箱是否清空())
        清空冰箱();

    放進去冰箱(動物);
    把冰箱關起來();
}

太短的函數,值得提出來嗎

當然要!!

來看看下面這個例子

一個圓柱體的直徑長 8 公分,高為 4 公分,圓柱體
底面積是多少平方公分?
體積是多少立方公分?

bottomArea = 8/2*8/2*3.14;
volume = bottomArea*4

你看得出我用什麼算式在算嗎?
如果你不知道圓柱體的算法,你還看得出來嗎?

const diameter = 8;
const height = 4;
const PI = 3.14;
let radius = diameter / 2;

bottomArea = radius * radius * PI;
volume = bottomArea * height;

有些人就會覺得,「這樣,足矣」。
還是糙!

「如果你不知道圓柱體的算法,你還看得出來嗎?」
「如果你不知道圓柱體的算法,你還看得出來嗎?」
「如果你不知道圓柱體的算法,你還看得出來嗎?」
「如果你不知道圓柱體的算法,你還看得出來嗎?」

function calcCircleArea (radius) {
  const PI = 3.14;
  return radius * radius * PI;
}

function calcCylinderVolume (bottomArea) {
  const height = 4;
  return bottomArea * height
}

const diameter = 8;
const radius = diameter / 2;
const bottomArea = calcCircleArea(radius);
const volume = calcCylinderVolume(bottomArea);

也許,這次並不是要解決一個圓柱體算法,算是要處理一個公司內部的商業邏輯或行政流程
那麼,你可以保證,這個函數不會再長大嗎?
意思是說「內部的商業邏輯」或「行政流程」不會改變嗎?
不能保證的情況之下,請好好的使用 function 將概念封裝,將變數區域化。


上一篇
如何寫高品質 function (輸出+輸入篇)
下一篇
過度依賴前置處理器
系列文
可不可以不要寫糙 code30

1 則留言

0
暐翰
iT邦大師 3 級 ‧ 2018-11-03 14:59:48

這篇太精彩了 /images/emoticon/emoticon32.gif/images/emoticon/emoticon32.gif/images/emoticon/emoticon32.gif

Chris iT邦新手 5 級‧ 2018-11-03 20:28:19 檢舉

感謝你的支持~~/images/emoticon/emoticon12.gif

我要留言

立即登入留言