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 个示例(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的。

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

我不认为 N​​etworkUtil 应该担心格式类型。只需让 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); }
   }
}

请注意,您可能需要一些方便的默认解析器,以便新的侦听器可以使用它们。

于 2012-10-31T02:14:20.587 回答
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 回答