49

無効な機能を有効にするプラグインを介して高度に拡張可能でカスタマイズ可能な Web アプリケーション (できれば NodeJS/MongoDB、以前は PHP と Python を使用していました) の開発を学ぼうとしています。

考えられるオプションの 1 つは、フックするプラグインとウィジェット用のフックを備えた Wordpress を使用することですが、ビューとロジック コードの適切な分離が欠けています。それは、学ぶべき 1 つのオプションであり続けます。他のオプションはありますか?

学習できるコード スニペットやサンプル アプリケーションはありますか? 言語やフレームワークはそれほど重要ではありません。おそらく、大まかな概念は理解できるでしょう。

4

4 に答える 4

91

優れたプラグイン アーキテクチャをゼロから作成するのは困難ですが、独自のメリットがあります。複雑さをローカライズすることで、ソフトウェアを柔軟かつ保守しやすくします。必要な最も重要なスキルは、疎結合コードを作成する能力です。これには、ポリモーフィズム、デメテルの法則、および関連するハリウッドの原理をしっかりと把握する必要があります。

最初にそれらに精通し、次に次の設計パターンに慣れることをお勧めします。これにより、困難が大幅に軽減されます。

  • コマンド パターン: プラグイン モジュールに一貫したエントリ ポイントを提供し、簡単にスワップ インおよびスワップ アウトできるようにします ( IBM の Web ベースの例)
  • Memento : カプセル化に違反することなく状態をキャプチャ、保持、および外部化することで、コンテナーによるプラグインの構成が可能になります。
  • Call Back : プラグイン モジュールがコンテナー/環境から「サービス」にアクセスできるようにします。
  • 依存性注入: 環境からプラグイン モジュールの結合を緩める方法。
  • Abstract Factory パターン: 環境にプラグインをインストールしてインスタンス化します。
  • Builder パターン: プラグイン モジュールが相互に依存している重要なプラグイン アーキテクチャに必要です。

それらを把握したら、既存のプラグイン フレームワークの実装とアーキテクチャのいくつかを調べて、それらがどのように使用されているかを確認してください。Apache には、 StrutsGeronimo カスタム サーバー アセンブリ、およびTomcat JNDI リソースがいくつかあります。また、Eclipse プラグイン フレームワーク.

于 2012-06-06T12:06:50.707 に答える
6

プラグイン アーキテクチャ自体はありませんが、クライアント コードを疎結合に保つ方法を説明します。アイデアが得られるかもしれません。

asp.netを使用しています。最初にメディエーターの JavaScript ファイルを含む main.aspx ページを配信します。これは、グローバル オブジェクト (メディエーターと呼びます) を定義します。これは、私たちが定義する唯一のグローバル オブジェクトです。

メディエーターは、パブリッシュ メッセージとサブスクライブ メッセージを含む単純なインターフェイスを公開します。

mediator.subscribe(messageName, callback);
mediator.publish(messageName);

mediator.js ファイルの後に、メイン ページには他の多数の javaScript ファイルが含まれます。各ファイルは、その機能をメディエーターに登録する即時関数で構成されます。このパターンの詳細については、こちらを参照するか、以前の質問を参照してください

同様のアプローチに従うこともできます - プラグインが機能を登録するためのインターフェースを提供する単一のグローバル オブジェクト (たとえば、pluginFramework) を定義します。クライアントに配信する html ページを作成するときは、最初に pluginFramework ファイルをインクルードしてから、目的の JavaScript プラグイン ファイルを動的にインクルードします。これは、ユーザーまたはデバイスに依存する可能性があります (たとえば、デバイスがタッチ対応の場合は別のプラグインですか?)。これらのプラグイン ファイルは、即時関数を使用して pluginFramework に機能を追加します。

プラグインが UI のメニューに機能を追加できるようにする方法の例を次に示します。

pluginFramework.js:

var pluginFramework = (function() {
    var menuItems = [];
    function addMenuItemPrivate(itemName, callback) {
        // e.g. add itemName and callback to menuItems
    }
    return {
        addMenuItem: addMenuItemPrivate;
    }
})());

photoPlugin.js:

(function() {
    function addPhoto() {
        //...
    }
    pluginFramework.addMenuItem('add photo', addPhoto)
})());

これが何らかの形で役立つことを願っています!

于 2012-06-05T20:45:01.547 に答える
5

あなたのコメントは、あなたが構築しているのはマルチテナント アーキテクチャであることを示唆しています。

これは複雑な要件であり、通常、後付けするのは非常に困難です。どこから始めているかによって大きく異なります。

まず、適切にファクタリングされた Web アプリケーションが最初に必要です。MVC フレームワークを使用している場合は、出発点があります。

次に、拡張機能をサポートする場所を決定する必要があります。たとえば、クライアントは UI 用に完全に別個のスキンを持つことができますか? もしそうなら、スキニングフレームワークが必要です。クライアントはすべてを変更できますか、それとも重要なポイント (カスタム決済プロバイダーやカスタム認証スキームなど) でさまざまなコンポーネントをプラグインするだけですか? 何でも拡張できるフレームワークを設計するよりも、限られた拡張ポイントのセットをサポートする方がはるかに簡単です。

次に、データ戦略です。MSDN にマルチ テナンシーに関する優れた記事があります。これはリレーショナル データベースを対象としていますが、Mongo に適用できるアイデアを提供します。

最後に、必要な拡張ポイントをサポートするコンポーネント アーキテクチャを考え出す必要があります。Web アプリケーションを扱っているので、Model、View、Controller、および永続性を変更できる必要があります。最善の解決策は、MVC フレームワークが機能する方法を使用し、"テナント x の場合は y を実行し、テナント z の場合は w を実行する" ロジックをコントローラー レイヤーに配置することです。これで遊んで、必要ないくつかのケースで機能するようにしてから、何が問題なのかを調べて修正してください。

于 2012-06-07T12:13:59.167 に答える
1

あなた自身がクライアントのカスタマイズを行っている場合、Django はこれに最適です。必要なすべての基本機能を処理するコア アプリケーションを作成します。次に、論理的に分離された必要があることごとに、設定でそのアプリをインストール済みのアプリに追加するだけで、メインのアプリにプラグインできる新しいアプリを作成/プラグインします。

これにより、スキニング (新しい base_site.html テンプレートを作成するだけで、他のすべてのテンプレートがそれから継承されます)、複数のデータベースのサポート、プラグインが処理され、新しいプラグイン/機能を非常に迅速に開発および展開することができます。

内部システムのより一般的な例については、メレンゲまたはピナックスを参照してください。

于 2012-06-08T15:21:20.963 に答える