2017-07-06 54 views
0

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

在我的主类我不能实现PropertyChangeListener并使用translationModel.addChangeListener(this),因为我在一个静态的上下文,所以“这个”不能工作。

什么是正确的方式能够从我的主类中的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

你可以有一个观察者本身t静态变量,如果你真的想要这样做,那么可以针对变化进行轮询,但这会违反使用事件驱动的观察者模式的原则。

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

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

HTH

+0

谢谢你的回答,这是有帮助的。 – Laurent