2009-05-20 78 views
0

我有這個問題,在下面的示例中的最佳做法:接口聲明與摘要方法與參數

interface Request; 
interface Service { 
    void process(Request request) 
} 

class MyService implements Service; 
class YourService implements Service; 

class MyRequest implements Request; 
class YourRequest implements Request; 

但如何確保MyService總會收到MyRequestYourService將得到只,而不是相反辦法?在MyService.process(...)中顯而易見的回答「if-instance-of-check」看起來很難看,並且在某種程度上違反了SOLID原則。也許有更好的方法?

也許泛型會是很好的解決方案嗎? (但是,那麼,如何在必須運行在Java 1.4下的代碼中使用它們呢?)

回答

3

如果合同的設計是每個服務可以處理任何類型的請求,那麼你的MyService的實現,只需要MyRequest(如果其他休息時間種類的請求被傳入),是錯誤的。

如果合同的設計是服務和請求子類相互映射,例如MyService可以(也應該)只有處理MyRequest,那麼您將需要更改服務的接口。否則,在問題中編寫的當前界面不會執行問題描述的操作。解決方法之一是參數化服務接口:

interface Service<R> { 
    void process(R request); 
} 

那麼你的具體的MyService將

public class MyService implements Service<MyRequest> { 
    public void process (MyRequest r) {/*blah*/} 
} 

你可以看到在JDK行動這樣的一個例子 - Comparator接口正是這樣做的,原因完全一樣。http://java.sun.com/javase/6/docs/api/java/util/Comparator.html

我不能明白爲什麼你會的,但如果你仍然想限制MyRequest的層次結構是一個要求,那麼你就可以Service<R extends Request>

編輯交換Service<R>:這顯然犯規在1.4上運行,所以做同樣的事情[1],你將需要使用訪客模式。它的醜陋,但1.4是醜陋=)

interface Service { 
    void process(Request visitor); 
} 
interface RequestVisitor { 
    void visitMyRequest(MyService service); 
    void visitYourRequest(YourService service); 
    void visitTheOtherRequest(TheOtherService service); 
} 
interface Request extends RequestVisitor { /* and any extra methods required for request*/ } 
public class MyService implements Service { 
    public process(Request r) {r.visitMyRequest(this);} 
    public void doSpecialMyProcessing(MyRequest request) { /* your code using MyRequest*/ } 
} 
public class YourService implements Service { 
    public process(Request r) {r.visitYourRequest(this);} 
    public void doSpecialYourProcessing(YourRequest request) { /* your code using YourRequest */ } 
} 
public class MyRequest implements Request { 
    void visitMyRequest(MyService service) { 
     service.doSpecialMyProcessing(this); 
    } 
    void visitYourRequest(YourService service) { 
     throw new UnsupportedOperation("Cannot call visitYourRequest in MyRequest!"); 
    } 
    void visitTheOtherRequest(TheOtherService service) { 
     throw new UnsupportedOperation("Cannot call visitTheOtherRequest in MyRequest!"); 
    } 
} 
public class YourRequest implements Request { 
    void visitMyRequest(MyService service) { 
     throw new UnsupportedOperation("Cannot call visitMyRequest in YourRequest !"); 
    } 
    void visitYourRequest(YourService service) { 
     service. doSpecialYourProcessing(this); 
    } 
    void visitTheOtherRequest(TheOtherService service) { 
     throw new UnsupportedOperation("Cannot call visitTheOtherRequest in YourRequest !"); 
    } 
} 

[1] 實際上它的不一樣,因爲現在你將需要編寫爲每個請求型的方法。在1.4中,你將不得不施放instanceof等,以達到1.5對泛型的作用。

+0

實際上你的第二個代碼(使用`RequestVisitor`爲1.4)根據`YourService`生成`MyService`,反之亦然。因爲`MyService`使用`MyRequest`來實現`Request`,它擴展了`RequestVisitor`,直接取決於所有的服務。不酷。 – Jakub 2009-05-20 14:35:37

6

簡而言之,你正在建立一個你不想堅持的接口,所以它不是一個真正理想的設計。

我的意思是,如果MyService實現Service,那麼它必須能夠接受任何類型的請求。否則,它不符合定義的合同。

我會質疑爲什麼你在這個實例中有服務接口,如果你確實需要它(對於其他方法),如果子進程沒有進行,是否適合進程(請求請求)方法在那裏兌現它。

+0

我的設計背後的邏輯是我有兩種服務通用的許多代碼。我想在每個服務中重用此代碼 - 最值得一提的是: class LoadBalancer implements Service void process(Request r){r.doSomeCommonStuff(); getNextService()。process(r); } } 無論如何感謝您的評論,我會重新考慮設計。 – Jakub 2009-05-20 12:58:07

0

實現Service的任何東西都應該期望按原樣實現其方法。如果MyService和YourService需要不同的方法原型,那麼它們是不同的接口。

從另一個方向思考它。在不知道Service接口背後的實現的情況下,任何調用者都應該能夠使用Request的任何實現調用Service.process(request),並期望收到有效的響應。

2

在我看來,仿製藥在這裏更適合。您的接口假定服務可以處理任何類型的請求。但實際上,每個實現似乎都緊密結合在一起。

0

嘗試引入間接的另一個層面:

interface Module { 
    Service createService(); 
    Request createRequest(); 
} 

class MyModule implements Module { 
    Service createService() { return new MyService(); } 
    Request createRequest() { return new MyRequest(); } 
} 

class YourModule implements Module { 
    Service createService() { return new YourService(); } 
    Request createRequest() { return new YourRequest(); } 
} 
+1

這沒有幫助,因爲客戶端代碼可能將YourRequest實例傳遞到MyService實例中。原始設計在覈心上被打破,無論有多少工廠被創建,都無法修復。 – Chii 2009-05-20 12:19:52