使用观察者模式在 Main class 中获取数据

Get data in Main class using Observer pattern

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

中获取这些数据

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

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

主要class

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

            }
            });

        }

}

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

也许有一些特定的原因为什么你希望在主要 class 中提供这些信息,但我更倾向于将任何处理卸载到观察者身上,就像你已经(干净地)完成的那样,添加新的实现作为你需要他们。

如果您只想让您的 main class 可用的信息(不一定在静态上下文中),让您的 Main class 实现 PropertyChangeListener 并在您的 WorldTranslation 中注册一个新的 Main()与您对 WorldTranslationObserver 所做的方式相同。

HTH