[Guideline] AVOID PREMATURE INHERITANCE
____________________
AVOID PREMATURE INHERITANCE
Inheritance needs time to evolve.
﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉
※ 節錄自 Prefactoring 第 63 頁
沒事不要繼承,繼承需要很長的時間才會演化。 (此為不負責任翻譯......)
在設計 Applet 的時候,為了切割圖形、控制、模組會採用 MVC Pattern
這邊的 MVC Pattern 是單純指圖形類別、控制類別、模組類別。
我下面所要描述的重點在控制類別,有很多人會把控制器寫成下面這個樣子:
if (第一個按鈕被按下) {
做第一種事情();
} else if (第二個按鈕被按下) {
做第二種事情();
} /* ... */ else if (第 n 個按鈕被按下) {
做第 n 種事情();
}
如果有 n 個按鈕,就有 n 個 if-else 要寫。
更慘的是,如果有新的按鈕或是新的事件要加入這段程式碼又要被改寫一次
這完全違背開閉原則 (Open-Close Principle)!
一個類別設計完之後,除了繼承它或是使用它之外
不應該再度修改它內部的程式碼!
當程式設計師發現一大串的 if-else 或是 switch-case
就應該聯想到 Class Inheritance
利用類別的多型來取代難以閱讀的 if-else 或 switch-case
可以讓原來的程式碼不會被修改的情況下,新增按鈕或是事件到一個新的類別
開發需求所述的新功能!
舉例而言 (JAVA):
public class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent actionEvent) {
final String command = actionEvent.getActionCommand();
if ("Load Image".equals(command)) {
this.loadImage();
} else if ("Histogram Equalization".equals(command)){
this.histogramEqualization();
} else if ("Mean Filter".equals(command)) {
this.meanFilter();
}
}
}
這三個 if-else 區塊分別處理三種不同的按鈕事件
分別是讀影像、做直方圖等化、以及做平均過濾。
還好只有三個 if-else 區塊,一開始還沒什麼大不了的
但是隨著需求的改變,按鈕愈來愈多,程式碼會開始大量地成長
public class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent actionEvent) {
final String command = actionEvent.getActionCommand();
if ("Load Image".equals(command)) {
this.loadImage();
} else if ("Histogram Equalization".equals(command)){
this.histogramEqualization();
} else if ("Mean Filter".equals(command)) {
this.meanFilter();
} /* 想像這邊以後有一大串 if-else 區塊 */
}
}
這可不是開玩笑的,每次加一個按鈕就要修改原來的程式碼並不是一個好現象!
倒不如切割整個類別為多個小類別,實作同一個介面 ActionListener
public class LoadImageHandler implements ActionListener {
// ......
}
public class HistogramEqualization implements ActionListener {
// ......
}
public class MeanFilter implements ActionListener {
// ......
}
這樣的話,每次要新增一個按鈕或事件處理,就只要新增一個類別實作 ActionListener
不需要再修改原來的程式碼了!符合開閉原則 (Open-Close Principle)
有人會問:「那原來的 if-else 到哪裡去了?消失了嗎?」
我會回答:「可以說它消失,也可以說它還存在。
if-else 確實不見了,它原本的功能散落在不同的 ActionListener 子類別
裡。判斷的機制仍然存在,只是現在改由設定按鈕的控制器實體,而不再由
控制器自己判斷要做哪一種動作了!」
有人續問:「判斷的機制仍然存在?那有比較好嗎?」
我會回答:「加入新按鈕的時候,設定新按鈕的控制器為新的控制器,
我們加入全新的類別不會更動原類別的任何程式碼,
在物件設計的角度來看是比較好的。」
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.116.247.13
※ 編輯: H45 來自: 140.116.247.13 (12/04 19:56)
※ 編輯: H45 來自: 140.116.247.13 (12/04 19:56)
推
12/04 20:44, , 1F
12/04 20:44, 1F
推
12/04 21:11, , 2F
12/04 21:11, 2F
推
12/04 22:21, , 3F
12/04 22:21, 3F
推
12/04 22:22, , 4F
12/04 22:22, 4F
→
12/05 00:28, , 5F
12/05 00:28, 5F
→
12/05 00:29, , 6F
12/05 00:29, 6F
推
12/05 07:53, , 7F
12/05 07:53, 7F
推
12/05 07:54, , 8F
12/05 07:54, 8F
→
12/05 16:32, , 9F
12/05 16:32, 9F
→
12/05 16:33, , 10F
12/05 16:33, 10F
推
12/05 16:35, , 11F
12/05 16:35, 11F
推
12/05 16:37, , 12F
12/05 16:37, 12F
OOAD 近期熱門文章
PTT數位生活區 即時熱門文章
-4
30