9

独自のフレームワーク用のプラグイン アーキテクチャを作成する方法を考えようとしています。私は数多くのトピックを読み、ここや他のサイトに投稿しました。そして基本的に、PHPで唯一の適切なオプションと思われる次のソリューションにたどり着きました(現在)。

アイデアは、すべてのクラスがある種のオブザーバーのようなクラスを拡張するということです。そのため、Template クラス、BaseController などは常に Plugin クラスを拡張します。

class BaseController extends Plugin
{
    public function __construct()
    {
        // Plugin check, notify all loaded plugins
        $this->checkForEarlyHooks();

        // Init some standard stuff
        $this->view = new Template();
        $this->baseLayout = 'layout.html';

        $this->something = new Something();

        // Plugin check, notify all loaded plugins
        $this->checkForLateHooks();
    }
}

つまり、ここで基本的に起こることは、indexController が baseController を拡張するときにプラグイン チェックが行われるということです。この場合、コンストラクターの場合。これは、アクション メソッドが実際に呼び出される前に、プラグインで何らかのログイン チェックを行いたい場合に便利です。

Plugin クラスは、呼び出されたクラスから解決でき、ロードされたプラグインで検索する関数を認識します。

また、ロードされたプラグイン リストを 2 回チェックすることにも注意してください。1 つはコンストラクターで何かがロードされる前 (早い段階) で、もう 1 つはすべての変数がロードされるとき (遅い段階) です。

「checkForLateHooks()」関数に変数を追加することもできます。そのため、「baseLayout」変数のように、フック関数もそれらを操作できます。

フック関数は次のようになります。

public function hookConstruct ( &$baseLayout )
{
    $baseLayout = 'login.html';
}

基本的に私の質問は、このアプローチは良いですか? おそらく他にも多くの方法があることを私は知っています。しかし、私は主に、後で設計上の問題に遭遇したくありません。今は良いアイデアのように思えますが、後でどうなるかはわかりません...

(私が読んだすべての投稿から)それを正しく覚えていれば、これはWordPress(および他のフレームワーク)が行うようなものです。

4

2 に答える 2

7

更新: 回答に最新のリンクとより適切な説明が反映されるようになりました。

確かに、プラグイン システムを設計するにはさまざまな方法があり、おそらくhttps://softwareengineering.stackexchange.com/で尋ねると、より多くのアイデアが得られるでしょうが、私のアイデアと経験を共有することで助けようとします.

一連の独自のフレームワークを通じて学んだ、私自身の経験のいくつかを共有します。現在、アジャイル UIアジャイル データは両方とも、拡張される多くのワシをサポートしていますが、「コンポーネント」に焦点を当てます。

フック

既存のオブジェクトにコードを挿入する場合、フックは標準的な方法です。これは、確立された構造でアプリケーションまたはフローを拡張するための最良のオプションです。

フレームワークをリファクタリングする際に、フックの実装を別の特性に分離し、ここに文書化しました: http://agile-core.readthedocs.io/en/develop/hook.html

ホスト アプリケーション:

... some code here ..
$this->hook('beforeInit');
$this->init();
$this->hook('afterInit');
... code goes on ..

プラグイン:

$host_app->addHook('beforeInit', function($object) {
    echo "About to execute init of $object";
});

UI コンポーネント

コンポーネントは、ユーザー インターフェイスに適した異なるデザイン パターンを提示します。ページ/アプリのレイアウトから始めて、メニュー、ヘッダー、フッター、コンテンツに分割します。

コンポーネントは、レイアウトまたは他のコンポーネントに関連付けることができるオブジェクトです。各コンポーネントは、追加の HTML/JS をレンダリングしてその親に渡すことができます。ほとんどのコンポーネントは対話型オブジェクトでもあります。

このアプローチは「レンダー ツリー」と呼ばれ、アプリケーションの実行は「レンダー ツリーの初期化」と「レンダリング」の 2 つの段階を経ます。

ホスト アプリケーション:

$layout->menu = new \atk4\ui\Menu();
$layout->add($layout->menu, 'TopMenu');

上記のコードは、新しいコンポーネント (メニュー) を初期化して に挿入する方法を示してい$layouます。さらに、$menu の HTML 出力は、レイアウトの HTML テンプレートで定義されている {$TopMenu} タグに送られます。

プラグインは、次の方法でレンダー ツリーとやり取りできます。

  • ツリー内の任意の場所にコンポーネントを追加する
  • 既存のコンポーネントへの影響 (例: 新しいメニュー項目の追加)
  • 既存のコンポーネントの破棄

これらのアプローチを組み合わせると、次のようなものを使用できます。

$app->addHook('afterInitLayout', function($app) {

    $app->layout->menu->destroy(); // remove default menu
    $app->layout->menu = new \plugin\SuperMenu();
    $app->layout->add($app->layout->menu);
});

これを使用して、標準メニューをアドオンのより強力な実装に置き換えることができます。

私のコンポーネントの実装はここに文書化されています:

http://agile-ui.readthedocs.io/en/latest/view.html#initializing-render-tree

UI / データの分離

質問に対する答えはそれほど多くないかもしれませんが、拡張するためのもう 1 つの強力な方法は、関心の分離です。Agile UIのすべての UI コンポーネントは、データの処理方法を知りません。

多くの UI ジェネレーターでは、開発者が手動でビルドしてデータとリンクする必要がありますが、私は次のように「モデル」オブジェクトを挿入しています。

$form->setModel(new User($db)); // populates name, surname and gender fields

デモ: http://ui.agiletoolkit.org/demos/form2.php (2 番目のフォーム)

このアプローチでは、オブジェクトUserには、フォームがそのフィールドに入力するのに十分なメタデータが含まれ、キャプションは検証を実行し、データの保存/読み込みも行います。

「ユーザー」クラスはアドオンでも宣言できるため、新しいデータ エンティティのサポートを追加することで、既存の機能を拡張する非常に強力な方法になります。

その他のアプローチ

アドオンで拡張する他のアプローチには、次のものがあります。

工場:

文字列として指定されたクラスを名前空間/ファイルに解決する機能:

$api->add('MyClass');

アドオンが標準クラスを再ルーティングする機能を提供しますが、IDE の型ヒントにはあまり適していません。

新しいタイプ / 特性:

アドオンは、永続性、テーブル列、フォーム フィールド、アクションなどを追加する新しいクラスを提供できます。

結論

アドオンの設計は、要約すると次のようになると思います。

  • インストールと使用のシンプルさ
  • アドオンはすぐに使用できる必要がありますか?
  • アドオン間の競合の回避
  • さまざまなアドオン タイプの定義 - 認証、UI、動作
  • アドオンは別のアドオンを拡張できます
  • アドオンはアプリケーションの設計、データ、およびアーキテクチャに適合しますか?
  • パフォーマンスを犠牲にすることなくアドオンに多くのパワーを与える
于 2012-04-08T11:04:43.387 に答える
1

https://github.com/gheevel/PHPPluginで PHPPlugin をご覧ください。Eclipse および Jira プラグイン アーキテクチャに触発されたシンプルな PHP プラグイン フレームワーク。基本的に、アプリケーションは拡張ポイントを定義でき、プラグイン インスタンスはそれらの拡張ポイントに登録して追加機能を提供できます。composer や symfony と組み合わせてうまく動作します。

于 2016-09-18T12:29:16.063 に答える