當客戶端呼叫服務提供者方法前後,需執行日誌記錄、效能計數、存取控制等橫切關注點時,若直接寫在服務類別內,會違反「單一職責原則」,導致程式碼耦合、難以維護。計數代理模式將這些附加功能封裝於獨立的代理物件,讓服務提供者專注核心業務邏輯。
public interface OrderIF {
public Vector getAllOrders();
}
public class Order implements OrderIF {
public Vector getAllOrders() {
FileUtil fileUtil = new FileUtil();
return fileUtil.fileToVector("orders.txt");
}
}
public class OrderProxy implements OrderIF {
private int counter = 0;
public Vector getAllOrders() {
Order order = new Order();
counter++;
long t1 = System.currentTimeMillis();
Vector v = order.getAllOrders();
long t2 = System.currentTimeMillis();
long timeDiff = t2 - t1;
String msg = "Iteration=" + counter + "::Time=" + timeDiff + "ms";
// 記錄日誌
FileUtil fileUtil = new FileUtil();
fileUtil.writeToFile("log.txt", msg, true, true);
return v;
}
}
public class MainApp {
public static void main(String[] args) {
OrderIF order = new OrderProxy();
Vector v = order.getAllOrders(); // 第 1 次
v = order.getAllOrders(); // 第 2 次
v = order.getAllOrders(); // 第 3 次
v = order.getAllOrders(); // 第 4 次
}
}
Java 反射機制 (java.lang.reflect.Proxy) 可在執行期動態產生代理類別,進一步解耦,適用於 AOP 框架(如 Spring AOP)的底層實作。
計數代理模式是「代理模式」的典型應用,展現「組合優於繼承」的設計智慧。