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 を確認し、そのパラメーターからの結果を使用します。ただし、上記の 2 つの例 (NetworkUtilListener1およびNetworkUtilListener2) では、JSON、画像、さらにはカスタム タイプなど、さらに多くのものが登場したときに将来使用する問題を検討しているresultTypeため、私のチームはそれを簡単に使用できます。

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

4

3 に答える 3

2

タイプと結果を受け取る代わりに、ポリモーフィズムを利用します。

public interface Result { ... }

public class XmlResult implements Result { ... }

将来的には、必要な数だけ追加することができます。

public class JSonResult implements Result { ... }

最後に、このインターフェイスがあります

interface NetworkUtilListener1
    public onNetworkFail();
    public onNetworkSuccess(URL, result);
于 2012-10-31T02:01:02.000 に答える
0

これは、古典的な訪問者パターンの解決策のように思えます。

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);
}

このパターンはメソッドのオーバーロードに大きく依存しているため、Result オブジェクトを受け取るキャッチオール メソッドを追加できます。これにより、Result の新しい実装が作成された場合でも、さらにオーバーロードを追加しなければ、それらのデフォルトの処理を取得できます。メソッド。

于 2012-10-31T02:35:45.360 に答える
0

NetworkUtil がフォーマット タイプを気にする必要はないと思います。NetworkListener 自体を NetworkUtil に登録し、NetworkUtil に成功時にリスナーに通知させるだけです。結果を処理するのは NetworkListener のみであるため、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); }
   }
}

新しいリスナーがそれらを利用できるように、いくつかのデフォルトのパーサーを手元に置いておきたい場合があることに注意してください。

于 2012-10-31T02:14:20.587 に答える