使用Observer模式在Main类中获取数据

时间:2017-07-06 19:55:34

标签: java json callback observer-pattern

我从远程API获取JSON数据。为此,我使用观察者模式。我创建了一个名为WordTranslationObserver的Observer,它从回调方法中获取JSON数据。问题是我不知道如何在Main类中获取这些数据......

在我的Main类中,我无法实现PropertyChangeListener并使用translationModel.addChangeListener(this),因为我在静态上下文中,所以"这个"无法工作。

能否从我的Main类中的translation.getText()获取数据的正确方法是什么?

主要课程

public class Main    {
    public static void main(String[] args) throws IOException {

        WordTranslation wordTranslation = new WordTranslation();
        WordTranslationObserver myObserver = new WordTranslationObserver(wordTranslation);
        wordTranslation.translate("sắt", "vie", "eng");     

    }
}

观察

public class WordTranslationObserver implements PropertyChangeListener {
    public WordTranslationObserver(WordTranslation translationModel) {
        translationModel.addChangeListener(this);
    }

    @Override
    public void propertyChange(PropertyChangeEvent event) {
        System.out.println("Changed property: " + event.getPropertyName());
        ArrayList<Translation> translations = (ArrayList<Translation>) event.getNewValue();

        // Print recieved data from JSON to the console 
        // I want to be able to get translation.getText() in my Main class
        for (Translation translation : translations) {
            System.out.println(translation.getText());
        }
    }
}

数据

public class WordTranslation {
    public static final String TRANSLATIONS = "translations";
    private static final String BASE_URL = "http://deu.hablaa.com/hs/translation/";
    private List<PropertyChangeListener> listener = new ArrayList<PropertyChangeListener>();
    ArrayList<Translation> translations;    

     public void addChangeListener(PropertyChangeListener newListener) {
            listener.add(newListener);
     }


     public void notifyListeners(String property, Translation[] translationArray) {
            translations = new ArrayList<>();
            // TODO Auto-generated method stub
            for (Translation t : translationArray) {
                translations.add(t);
            }
            for (PropertyChangeListener name : listener) {
                name.propertyChange(new PropertyChangeEvent(this, "translations", null, translations));
        }
    } 

     public void translate(String word, String from, String to) {
            final Translation[][] translations = new Translation[1][1];

            String url = String.format("%s%s/%s-%s",BASE_URL, word, from, to);//  args) "http://xxx";
        System.out.println(url);
        final Gson gson = new Gson();

        // should be a singleton
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                             .url(url)
                             .build();


        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response);
                }

                translations[0] = gson.fromJson(response.body().charStream(),Translation[].class);  
                notifyListeners(TRANSLATIONS,translations[0]);

            }
            });

        }

}

1 个答案:

答案 0 :(得分:1)

你可以让一个观察者设置静态变量,如果你真的想要,可以轮询更改,但这会破坏使用事件驱动的观察者模式的原则。

也许有一些特定的原因可以解释为什么你希望在主类中提供这些信息,但我更倾向于将任何处理卸载到观察者上,因为你已经(干净地)完成了,在你需要的时候添加了新的实现。

如果您只想获得主类可用的信息(不一定是在静态上下文中),请让您的Main类实现PropertyChangeListener并使用WorldTranslation注册一个新的Main(),方法与使用WorldTranslationObserver相同。

HTH