2012-10-31 109 views
1

我試圖設計「網絡連接」,以便於使用從服務器檢索數據。但是,我面臨着設計問題。面向對象的結構設計

NetworkUtil類,我將使用被設計爲

class NetworkUtil 
    public NetworkUtil(URL, resultType); // resultType might be XML or RAW 
    public setListener(listener); // listener will notice when result has arrive 
    public addPostData(key, value); 
    public connect(); // connect start new thread, so result will shown in listener 

interface NetworkUtilListener1 
    public onNetworkFail(); 
    public onNetworkSuccess(URL, resultType, xml, raw); 

interface NetworkUtilListener2 
    public onNetworkFail(); 
    public onNetworkSuccessRAW(URL, resultType, raw); 
    public onNetworkSuccessXML(URL, resultType, xml); 

一旦到達結果,我會檢查與resultType並從參數中使用的結果。然而,在上面的兩個示例(NetworkUtilListener1NetworkUtilListener2)中,當更多resultType即將推出時(例如JSON,圖像甚至我的自定義類型),我會考慮將來使用該問題,因此我的團隊可以輕鬆使用它。

NetworkUtilListener1將有長期未使用的參數一樣

onNetworkSuccess(URL, resultType, raw, xml, json, image); 

這不是一個好的設計,因爲我以爲。

NetworkUtilListener2將強制使用它的具體類有很多空方法,因爲大多數時候我們只在每個項目上只使用1或2類結果。

onNetworkSuccessRAW(URL, resultType, raw); 
onNetworkSuccessXML(URL, resultType, xml); 
onNetworkSuccessJSON(URL, resultType, json); 
onNetworkSuccessImage(URL, resultType, image); 

任何人都可以給我一些幫助,重新設計這個類的結構或向我推薦我需要關注的設計模式。所以我可以有更好的NetworkListener

回答

0

這聽起來像古典visitor pattern的解決方案:

讓我們通過重載NetworkListener方法入手:

interface NetworkListener { 
    void onSuccess(XMLResult xml); 
    void onSuccess(JSONResult json); 
} 

然後,作爲建議,讓我們幾個實施效果的。他們中的每個人都可以通過調用適當的重載方法來通知監聽器。

interface Result { 
    void notify(NetworkListener listener); 
} 

class XMLResult implements Result { 

    @Override 
    public void notify(NetworkListener listener) { 
     listener.onSuccess(this); 
    } 

} 

class JSONResult implements Result { 

    @Override 
    public void notify(NetworkListener listener) { 
     listener.onSuccess(this); 
    } 
} 

現在,讓我們來看看樣本網絡監聽器實現會是什麼樣子:

class SampleListner implements NetworkListener{ 

    @Override 
    public void onSuccess(XMLResult xml) { 
     // handle here 
    } 

    @Override 
    public void onSuccess(JSONResult json) { 
     // handle here 

    } 
} 

和通知代碼看起來有點像:由於模式在很大程度上依賴於

Result result = null; 
for(NetworkListener listener: listeners){ 
    result.notify(listener); 
} 

方法重載,你可以添加一個catch-all方法來接收一個Result對象,這將保證如果任何Result的新實現被創建,你仍然會得到一個默認的處理方式如果你不添加更多的重載方法。

+0

感謝您的回答,但我認爲您的解決方案與NetworkUtilListener2出現同樣的問題 - 具體類(您的情況爲SampleListener)需要實現大量空方法。但是,從你的代碼中,我想出了一個想法。如果我使用類而不是接口來監聽器真正的concreate類不需要從接口獲得所有的功能。但我仍然不確定這是個好主意。 – Chetchaiyan

+0

@Chetchaiyan訪客模式有許多優點,您應該考慮。關於需要通過設計來實現許多方法,因爲您的代碼是關於分別處理每種類型的結果的。但是,您可以定義一個含有所有方法的空白實現的抽象類(即NetworkUtilsAdapter)(類似於某些Java Swing偵聽器中使用的策略[即WindowAdapter])。然後,您的實際監聽器實現可以簡單地擴展此抽象適配器並實現您感興趣的特定方法。 –

2

不是接收類型和結果,利用多態:

public interface Result { ... } 

public class XmlResult implements Result { ... } 

,並在未來,你可以添加你需要儘可能多的。

public class JSonResult implements Result { ... } 

最後,你都會有這樣的接口

interface NetworkUtilListener1 
    public onNetworkFail(); 
    public onNetworkSuccess(URL, result); 
0

我不認爲NetworkUtil應該擔心格式類型。只需讓NetworkListener註冊到NetworkUtil,並讓NetworkUtil通知監聽器成功。讓NetworkListener擔心類型,因爲它們是處理結果的唯一方法。應該像

class NetworUtil{ 
    registerListener(listener){ mylisteners.push(listener); } 
    notifyListener(){ for(listener: mylisteners){ listener.onSuccess(myresult); } 
} 

class Listener1{ 
    Listener1(){ registerWithNetworkUtil(); } 
    void onSuccess(myresult){ 
     if(myresult.isXML){ parseXML(myresult); } 
     else if(myresult.isJSON()){ parseJSON(myresult); } 
     else if(myresult.isXXYYZZ()){ parseXXYYZZ(myresult); } 
    } 
} 

注意您可能希望有一些默認的解析器得心應手所以新的聽衆可以利用它們。

+0

你的代碼中的'myresult'類型是什麼? –

+0

最有可能的字符串,雖然上面是僞代碼,或者可能是原始結果的包裝 – dchhetri

+0

字符串沒有像isJSON()或isXML()這樣的方法。 –