拡張可能なWebアプリケーションを作成する方法は?


8

拡張可能なWebアプリケーションをどのように実装しますか?私が考えているのは、プラグインサポートを提供するJenkinsやHudsonに似たWebアプリケーションです。プラグインを見つけてロードする方法は明らかですが、プラグインをアーキテクチャ全体に統合する方法はわかりません。特に以下の点については不確かです。

プラグインはどのようにビューを変更することができますか、例えばフォームに入力要素を追加しますか?

私の最初のアイデアは、プラグインが特定のフォームのパーシャル/フラグメントを登録できるということです。

例:ユーザー登録ビューに表示される典型的なニュースレターチェックボックスフラグメントを登録するニュースレタープラグイン。

プラグインは着信要求にどのように反応しますか?

この場合も、直接的なアプローチは、特定の要求またはアクション(/ userへのPOST要求など)のリスナーを提供することです。

プラグインはどのようにしてデータを保持できますか?

これは、NoSQLデータストレージソリューションがリレーショナルデータベースよりも優れている状況であると想定しています。

拡張可能なWebアプリケーションに関して、コメント、アイデア、経験(デザインパターンもあるかもしれません)があれば幸いです。

回答:


3

あなたの質問にはほとんどすべての答えが含まれています。あなたはまさにその場にいます。すべてのプラグインとそのコンテキストを設定して、必要なことを実行させるための拡張ポイントです。プラグインシステムを設計する方法はいくつかあります。手始めに:

http://people.clarkson.edu/~dhou/courses/EE564-s07/plugin.pdf

http://blogs.atlassian.com/developer/2011/03/plugin_architecture_episode_i.html

基本的なプラグイン対応システムがどのように機能するかを示す簡単な例を次に示します。

public interface Plugin {

  void setEntityManager(EntityManager manager); // this is very course grained and liberal! A plugin would have access to whatever Entity Manager the container gives it. A plugin would then have a carte blanche to do whatever it needs: create, drop, insert, select, delete.

  View renderView(ViewContext context); // a plugin would render or return a view (whatever it is, could be a string in the simplest case) based on the context that the container passed to the plugin

  Action readEvent(Event event); // a plugin performs some Action based on an event as notified by a container

}


public class PluginContainer {

  private List<Plugin> plugins = new ArrayList<Plugin>();

  public void registerPlugins() {
    // loop through plugin descriptors obtained by your preferred mechanism
    // like introspecting libraries (JARs) in a configurable location

    // for each descriptor, load a Plugin dynamically and "register" it with a container
    Plugin p = ClassLoader.getSystemClassLoader().loadClass("com.my.PluginA").newInstance(); 
    p.setEntityManager(entityManager);
    plugins.add(p);
  }

  public void readEvent(AppEvent appEvent) {
    Event e = this.constructPluginSpecificEventFromAppEvent(); // optional
    for (Plugin p : this.plugins) {
      p.readEvent(e); // disregarding Action here
    }
  }
}

public class Application {

  private PluginContainer pContainer;

  private void buttonClicked(AppEvent appEvent) {
    this.showCoolDialog("Thank you for clicking a button!");
    // now let my plugins handle this
    // they can do whatever they want for this event
    // since they have access to EntityManager, they can work with a persistence storage as well
    this.pcContainer.readEvent(appEvent);
  }

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.