ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript プラグイン システムの設計は非常に重要です

JavaScript プラグイン システムの設計は非常に重要です

coldplay.xixi
coldplay.xixi転載
2020-09-02 17:26:372023ブラウズ

JavaScript プラグイン システムの設計は非常に重要です

[関連する学習の推奨事項: JavaScript ビデオ チュートリアル ]

WordPress にはプラグインがあり、jQuery にもプラグインがあり、同様のことが当てはまります。ギャツビー、イレブンティ、ビュー。

プラグインはライブラリとフレームワークの共通機能であり、これには十分な理由があります。プラグインを使用すると、開発者は安全かつ拡張可能な方法で機能を追加できます。これにより、追加のメンテナンス負担を追加することなく、コア プロジェクトの価値が高まり、コミュニティが構築されます。とても良い!

それでは、プラグイン システムを構築するにはどうすればよいでしょうか?この質問に答えるために、JavaScript で独自のプラグインを構築してみましょう。

プラグイン システムを構築しましょう

BetaCalc というサンプル プロジェクトから始めましょう。 BetaCalc は、他の開発者が「ボタン」を追加できる最小限の JavaScript 電卓を目指しています。基本的な入門コードをいくつか示します。

// 计算器const betaCalc = {  currentValue: 0,
  
  setValue(newValue) {    this.currentValue = newValue;    console.log(this.currentValue);
  },
  
  plus(addend) {    this.setValue(this.currentValue + addend);
  },
  
  minus(subtrahend) {    this.setValue(this.currentValue - subtrahend);
  }
};// 使用计算器betaCalc.setValue(3); // => 3betaCalc.plus(3);     // => 6betaCalc.minus(2);    // => 4复制代码

物事をシンプルにするために、電卓を客観的なものとして定義します。電卓は、結果を出力する console.log によって機能します。

現在の機能は確かに非常に制限されています。数値を受け入れて「画面」に表示する setValue メソッドがあります。現在表示されている値に対して演算を実行する加算 (plus) メソッドと減算 (minus) メソッドもあります。

今度は、さらに機能を追加します。まずはプラグインシステムを作成します。

世界最小のプラグイン システム

まず、他の開発者が BetaCalc にプラグインを登録するために使用できる登録 (register) メソッドを作成します。このメソッドの仕事は簡単です: 外部プラグインを取得し、その exec 関数を取得し、それを新しいメソッドとして電卓にアタッチします:

// 计算器const betaCalc = {  // ...其他计算器代码在这里

  register(plugin) {    const { name, exec } = plugin;    this[name] = exec;
  }
};复制代码

これは電卓用のプラグインの例です。 「squared(squared)」ボタンを提供します:

// 定义插件const squaredPlugin = {  name: 'squared',  exec: function() {    this.setValue(this.currentValue * this.currentValue)
  }
};// 注册插件betaCalc.register(squaredPlugin);复制代码

多くのプラグイン システムでは、通常、プラグインは 2 つの部分に分かれています:

    #実行されるコード
  1. メタデータ (例: 名前、説明、バージョン番号、依存関係など)
プラグインの

exec 関数にはコードが含まれています, name はメタデータです。プラグインが登録されると、exec 関数がメソッドとして betaCalc オブジェクトに直接アタッチされ、BetaCalc の this へのアクセスが可能になります。

BetaCalc には、直接呼び出すことができる新しい「四角」ボタンが追加されました:

betaCalc.setValue(3); // => 3betaCalc.plus(2);     // => 5betaCalc.squared();   // => 25betaCalc.squared();   // => 625复制代码
このシステムには多くの利点があります。プラグインは、関数に渡すことができる単純なオブジェクト リテラルです。これは、プラグインを npm 経由でダウンロードし、ES6 モジュールとしてインポートできることを意味します。配布のしやすさは超重要!

しかし、私たちのシステムにはいくつかの欠陥があります。

プラグイン

this に BetaCalc へのアクセス権を与えることで、プラグインは BetaCalc のすべてのコードへの読み取り/書き込みアクセス権を持つことができます。これは currentValue の取得と設定には便利ですが、危険な場合もあります。プラグインが内部関数 (setValue など) を再定義すると、BetaCalc や他のプラグインに予期しない結果が生じる可能性があります。これは、ソフトウェア エンティティは拡張にはオープンであるが、変更にはクローズされるべきであるというオープンクローズの原則に違反します。

また、「squared」関数は副作用を引き起こすことによって機能します。これは JavaScript では珍しいことではありませんが、特に他のプラグインが同じ内部状態にある場合には、気分の良いものではありません。より実践的なアプローチは、システムをより安全で予測可能にするのに大いに役立ちます。

より良いプラグイン アーキテクチャ

より良いプラグイン アーキテクチャを見てみましょう。次の例では、電卓とそのプラグイン API の両方を変更します。

// 计算器const betaCalc = {  currentValue: 0,
  
  setValue(value) {    this.currentValue = value;    console.log(this.currentValue);
  }, 
  core: {    'plus': (currentVal, addend) => currentVal + addend,    'minus': (currentVal, subtrahend) => currentVal - subtrahend
  },  plugins: {},    

  press(buttonName, newVal) {    const func = this.core[buttonName] || this.plugins[buttonName];    this.setValue(func(this.currentValue, newVal));
  },

  register(plugin) {    const { name, exec } = plugin;    this.plugins[name] = exec;
  }
};  
// 我们得插件,平方插件const squaredPlugin = { 
  name: 'squared',  exec: function(currentValue) {    return currentValue * currentValue;
  }
};

betaCalc.register(squaredPlugin);// 使用计算器betaCalc.setValue(3);      // => 3betaCalc.press('plus', 2); // => 5betaCalc.press('squared'); // => 25betaCalc.press('squared'); // => 625复制代码
ここでは、いくつかの注目すべき変更を加えました。

まず、プラグインを独自のプラグイン オブジェクトに入れることで、「コア」計算メソッド (プラスやマイナスなど) からプラグインを分離します。プラグインを

plugins オブジェクトに保存すると、システムの安全性が高まります。現在、このプラグインにアクセスするプラグインには BetaCalc プロパティは表示されず、betaCalc.plugins のプロパティのみが表示されます。

2 番目に、ボタンの機能を名前で検索して呼び出す

press メソッドを実装しました。ここで、プラグインの exec 関数を呼び出すと、現在の計算機の値 (currentValue) を関数に渡し、関数が新しい計算機の値を返すことを期待します。

本質的に、この新しい

press メソッドは、すべての電卓ボタンを純粋な関数に変換します。これらは値を取得し、操作を実行して、結果を返します。これには多くの利点があります:

  • これにより API が簡素化されます。
  • これにより、テストが容易になります (BetaCalc とプラグイン自体の場合)。
  • これにより、システムの依存関係が軽減され、より疎結合になります。

この新しいアーキテクチャは、最初の例よりも制限されていますが、うまく機能します。私たちは基本的にプラグイン作成者に対してガードレールを設け、私たちが望む変更のみを行うよう制限しています。

実際には厳しすぎるかもしれません。現時点では、計算プラグインは currentValue でのみ動作できます。プラグイン作成者が高度な機能 (「記憶」ボタンや履歴を追跡する方法など) を追加したい場合、できることはあまりありません。

これはいいかもしれません。プラグイン作成者に与える権限は、微妙なバランスで決まります。あまりにも多くの権限を与えすぎると、プロジェクトの安定性に影響を与える可能性があります。しかし、彼らに与える電力が少なすぎると、彼ら自身の問題を解決することが難しくなります。その場合は、プラグインしないほうがよいでしょう。

他に何ができるでしょうか?

システムを改善するためにやるべきことはまだたくさんあります。

プラグイン作成者が名前または戻り値の定義を忘れた場合に通知するエラー処理を追加できます。 QA 開発者のように考えて、システムがどのように壊れるのかを想像して、こうした状況に積極的に対処できるようにすることは良いことです。

プラグインの機能範囲を拡張できます。現在、BetaCalc プラグインはボタンを追加できます。しかし、特定のライフサイクル イベント (電卓が値を表示しようとしているときなど) のコールバックも登録できたらどうなるでしょうか?あるいは、複数のインタラクションにわたる状態の一部を保存するための専用の場所があった場合はどうなるでしょうか?これにより、新たな使用例が生まれるでしょうか?

プラグインの登録機能も拡張できます。プラグインを初期設定で登録できたらどうなるでしょうか?これによりプラグインの柔軟性が向上しますか?プラグイン作成者が、「BetaCalc Stats Package」など、単一のボタンではなくボタンのセット全体を登録したい場合はどうすればよいでしょうか?これをサポートするにはどのような変更を加える必要がありますか?

プラグイン システム

BetaCalc とそのプラグイン システムは非常にシンプルです。プロジェクトが大規模な場合は、他のプラグイン アーキテクチャを検討することもできます。

成功したプラグイン システムの例として、既存のプロジェクトを調べることが良い出発点となります。 JavaScript の場合、これは jQuery、Gatsby、D3、CKEditor などを意味します。また、さまざまな JavaScript 設計パターンに慣れることもできます。それぞれのパターンで異なるインターフェイスと結合度が提供され、プラグイン アーキテクチャの優れた選択肢が数多く提供されます。これらのオプションを理解すると、プロジェクトを使用するすべてのユーザーのニーズのバランスをより適切に保つことができます。

パターン自体に加えて、そのような決定を下すために利用できる優れたソフトウェア開発原則が数多くあります。すでにいくつかのアプローチ (オープンクローズ原則や疎結合など) について説明しましたが、その他の関連するアプローチには、デメテルの法則や依存性注入などがあります。

大げさに聞こえるかもしれませんが、よく調べてください。プラグインのアーキテクチャを変更する必要があるため、全員がプラグインを書き直すことほど面倒なことはありません。これは信頼を失い、将来の貢献に対する人々の自信を失わせる手っ取り早い方法です。

概要

優れたプラグイン アーキテクチャを最初から作成するのは困難です。すべての人のニーズを満たすシステムを構築するには、多くの考慮事項のバランスを取る必要があります。十分にシンプルですか?機能が強力になる可能性はありますか?長期的には機能しますか?

しかし、それだけの価値はあります。優れたプラグイン システムを持つことはすべての人を助け、開発者は自由に問題を解決できるのです。エンドユーザーが選択できるオプション機能が多数あります。プロジェクトの周囲にエコシステムとコミュニティを構築できます。それは双方にとって有利な状況です。

以上がJavaScript プラグイン システムの設計は非常に重要ですの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。