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

有個這個題目是在ApectJ的應(yīng)用,以及博客園子中一個blog討論什么時候用接口(一個很古老的話題)。
接口作為一種重要的抽象能力,重要意義在于:
模型上看:接口代表做什么,而實現(xiàn)表示怎么做!
在框架上:接口代表穩(wěn)定,而實現(xiàn)代表多變!
在語言上:接口代表0,而實現(xiàn)代表1,通過對象類型消除if…else…。
(這段話我<<Domain Model:業(yè)務(wù)流程的進一步分析2>>提過)
既然是應(yīng)用開發(fā),模型角度看根據(jù)現(xiàn)實意義,沒有AspectJ前的開發(fā),都是設(shè)計好一個接口,然后至少一個實現(xiàn)類,然后通過factory獲取正確的實現(xiàn)類,后來spring出現(xiàn)了,實現(xiàn)了IoC。然而由于AspecJ橫空出世了,我們又多了一種手段:接口作為占位符, 而沒有實現(xiàn)類(當(dāng)然有實現(xiàn))。這是我在看到partech的sunflower的代碼后才想到的!雖然我在<<AOSD:應(yīng)用AOP實現(xiàn)業(yè)務(wù)邏輯>>一文中已經(jīng)想到了一些,然而還是沒有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的功能如此強大, 接口真正做占位符用的情況,估計還是有很多人提出異議,這樣做我有什么好處,和我寫接口實現(xiàn)類相比?
好處目前,我能想的到的只有兩個
1. 模型上,強迫所有人思考——接口到底做什么,而不是怎么做
2. 語言上,更加動態(tài)性,不在依賴接口的完整簽名,只是輸入?yún)?shù)和輸出參數(shù),看上去更接近.Net的Delegate

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