Interface plays as Placeholder, without any class implement it
Author:Anders小明

有個這個題目是在ApectJ的應用,以及博客園子中一個blog討論什么時候用接口(一個很古老的話題)。
接口作為一種重要的抽象能力,重要意義在于:
模型上看:接口代表做什么,而實現表示怎么做!
在框架上:接口代表穩定,而實現代表多變!
在語言上:接口代表0,而實現代表1,通過對象類型消除if…else…。
(這段話我<<Domain Model:業務流程的進一步分析2>>提過)
既然是應用開發,模型角度看根據現實意義,沒有AspectJ前的開發,都是設計好一個接口,然后至少一個實現類,然后通過factory獲取正確的實現類,后來spring出現了,實現了IoC。然而由于AspecJ橫空出世了,我們又多了一種手段:接口作為占位符, 而沒有實現類(當然有實現)。這是我在看到partech的sunflower的代碼后才想到的!雖然我在<<AOSD:應用AOP實現業務邏輯>>一文中已經想到了一些,然而還是沒有partech來的狠!
下面是一個簡單的例子:
Order類

package ?placeholder;

import ?java.util.Date;

/**
?*?
@author ?Anders.Lin
?*
?
*/

public ? class ?Order? {
?
private ?String?orderCode;
?
private ?Date?commerceDate;
?
private ?Long?userId;
?
?
public ?Order() {??
?}

?
?
public ?Order(String?orderCode,?Date?commerceDate,?Long?userId) {
??
this .orderCode? = ?orderCode;
??
this .commerceDate? = ?commerceDate;
??
this .userId? = ?userId;
?}

?
public ?Date?getCommerceDate()? {
??
return ?commerceDate;
?}

?
public ? void ?setCommerceDate(Date?commerceDate)? {
??
this .commerceDate? = ?commerceDate;
?}

?
public ?String?getOrderCode()? {
??
return ?orderCode;
?}

?
public ? void ?setOrderCode(String?orderCode)? {
??
this .orderCode? = ?orderCode;
?}

?
public ?Long?getUserId()? {
??
return ?userId;
?}

?
public ? void ?setUserId(Long?userId)? {
??
this .userId? = ?userId;
?}
?
}


OrderService類

package ?placeholder;

/**
?*?
@author ?Anders.Lin
?*
?
*/

public ? interface ?OrderService? {
?
public ? void ?ship(Order?order);
}

Main類

package ?placeholder;

import ?java.util.Date;

/**
?*?
@author ?Anders.Lin
?*
?
*/

public ? class ?Main? {
?
?
private ?OrderService?orderService;
?
?
public ? void ?ship(Order?order) {
??orderService.ship(order);
?}

?
/**
??*?
@param ?args
??
*/

?
public ? static ? void ?main(String[]?args)? {
??Order?order?
= ? new ?Order( " Anders007 " ,? new ?Date(),? new ?Long( 1 ));
??Main?main?
= ? new ?Main();
??main.ship(order);
?}


}


OrderServiceAspect

package ?placeholder;

/**
?*?
@author ?Anders.Lin
?*
?
*/

public ?aspect?OrderServiceAspect? {
?pointcut?ship():?call(
void ?OrderService.ship(..));
?
?
void ?around(Order?order)?:?ship()? && ?args(order) {
??System.out.println(
" ship? " + ?order.getOrderCode()? + ? " ?sucess! " );
?}

}

雖然AspectJ的功能如此強大, 接口真正做占位符用的情況,估計還是有很多人提出異議,這樣做我有什么好處,和我寫接口實現類相比?
好處目前,我能想的到的只有兩個
1. 模型上,強迫所有人思考——接口到底做什么,而不是怎么做
2. 語言上,更加動態性,不在依賴接口的完整簽名,只是輸入參數和輸出參數,看上去更接近.Net的Delegate

技術好壞只有自己展控了才知道,AspectJ提供這樣一個選擇,怎么做還是自己琢磨著吧。