在物件導向設計中,「一個類只做一件事」 是基本準則。當涉及用戶介面程式碼時,這項原則更顯關鍵,因為 UI 很容易將「做什麼」(商業邏輯)與「怎麼顯示」(介面邏輯)纏繞在一起。這種耦合不僅阻礙程式碼重用,更讓測試與維護變得困難。透過將商業邏輯與 UI 邏輯分離,我們不僅能輕鬆重用核心運算邏輯,甚至能在不同介面(Swing、JavaFX、Web、行動裝置)間切換 UI 而不動到底層核心。
進階做法是引入動作物件,構建多層次系統。動作物件封裝具體操作規則,允許新事件修改即時生效,且不受特定顯示模式綁定。同一組動作物件可服務於桌面應用、Web 服務或批次處理程式,真正實現「邏輯一次編寫,到處執行」。
以下範例展示如何將計算邏輯封裝於 BusinessLogic 類別,而 Separation Applet 僅負責介面互動:
//: Separation.java
// Separating GUI logic and business objects
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class BusinessLogic {
private int modifier;
BusinessLogic(int mod) { modifier = mod; }
public void setModifier(int mod) { modifier = mod; }
public int getModifier() { return modifier; }
// 商業運算方法
public int calculation1(int arg) { return arg * modifier; }
public int calculation2(int arg) { return arg + modifier; }
}
public class Separation extends Applet {
TextField t = new TextField(20), mod = new TextField(20);
BusinessLogic bl = new BusinessLogic(2);
Button calc1 = new Button("Calculation 1"), calc2 = new Button("Calculation 2");
public void init() {
add(t);
calc1.addActionListener(new Calc1L());
calc2.addActionListener(new Calc2L());
add(calc1);
add(calc2);
mod.addTextListener(new ModL());
add(new Label("Modifier:"));
add(mod);
}
static int getValue(TextField tf) {
try { return Integer.parseInt(tf.getText()); }
catch(NumberFormatException e) { return 0; }
}
class Calc1L implements ActionListener {
public void actionPerformed(ActionEvent e) {
t.setText(Integer.toString(bl.calculation1(getValue(t))));
}
}
class Calc2L implements ActionListener {
public void actionPerformed(ActionEvent e) {
t.setText(Integer.toString(bl.calculation2(getValue(t))));
}
}
class ModL implements TextListener {
public void textValueChanged(TextEvent e) {
bl.setModifier(getValue(mod));
}
}
public static void main(String[] args) {
Separation applet = new Separation();
Frame aFrame = new Frame("Separation");
aFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) { System.exit(0); }
});
aFrame.add(applet, BorderLayout.CENTER);
aFrame.setSize(200,200);
applet.init();
applet.start();
aFrame.setVisible(true);
}
} ///:~
BusinessLogic 專注於計算,不含任何 AWT/Swing 相依。雖然範例使用 Java 1.1 AWT,但核心概念在現代開發中依然適用:
掌握「分離關注點」是從寫能跑的程式、進化為寫好維護、好擴充、好測試的專業開發者的關鍵一步。