この記事では、JavaScriptの構造設計パターンの1つであるリンカーを分解します。ソフトウェアエンジニアリングでは、リンカーを使用すると、オブジェクトのグループを個別のオブジェクトであるかのように参照できます。これにより、これらのオブジェクトの全体的な構造とそれらの組み合わせが一貫していることが保証されます。
リンカーの主なタスクは、多くのオブジェクトを1つのツリー構造に結合することです。このツリー構造は、特定のものから全体まで構造化された階層を表します。 リンカーがどのように機能するかをよりよく理解するには、特定の階層から全体の階層がどのように機能し、どのように視覚化できるかを理解する必要があります。
特定から全体への階層では、コレクション内の各オブジェクトは全体的な構成の一部です。この一般的な構成は、順番に、そのパーツのコレクションです。特定の階層から全体の階層は、ツリーのような構造として構築されます。個々の「リーフ」または「ノード」は、ツリーの他のリーフまたはノードと同じように認識および処理されます。したがって、オブジェクトのグループまたはコレクション(シート/ノードのサブツリー)もリーフまたはノードです。
視覚的には、次のように表すことができます。
プライベートと全体の関係をより明確に理解できたので、リンカーという用語に戻りましょう。..。リンカーの使用は、この原則に従って、言及されたオブジェクト(リーフ/ノード)をツリーに結合することを目的としていると判断しました。
したがって、コレクションの各要素に他のコレクションを含めることができる設計パターンが得られます。これにより、深くネストされた構造を構築できます。
内部構造
ツリー内の各ノードは、オブジェクトのコレクションと同じ方法で個々のオブジェクトを維持および操作できるようにする、プロパティとメソッドの共通セットを共有します。このインターフェイスは、複合コレクション内のすべてのオブジェクトを反復処理する再帰的アルゴリズムの構築を前提としています。
このパターンはどこに適用されますか?
オペレーティングシステムでは、このパターンにより、ディレクトリ内にディレクトリを作成するなど、多くの可能性があります。
ファイル(便宜上、ディレクトリ内のすべてのオブジェクトは「要素」と見なすことができます)は、コンポジット(ディレクトリ)全体内のリーフ/ノード(パーツ)です。ディレクトリに作成されたサブディレクトリは、同様に、ビデオ、画像などの他の要素を含むリーフまたはノードです。同時に、ディレクトリとサブディレクトリも、個別のパーツ(オブジェクト、ファイルなど)のコレクションであるため、複合です。等。)。
ReactやVueなどの人気のあるライブラリは、このパターンを広範囲に使用して、信頼性が高く再利用可能なインターフェイスを構築します。表示されるWebページのすべての要素は、コンポーネントとして表されます。Webページの各コンポーネントはツリーの葉であり、それ自体が多くのコンポーネントを組み合わせることができます(この場合、コンポジットが形成されますが、それでもツリーの葉です)。これは、ライブラリユーザーの開発を大幅に簡素化する強力なツールです。さらに、複数のオブジェクトを含むスケーラブルなアプリケーションを作成できます。
このテンプレートが興味深いのはなぜですか?
要するに:それは非常に強力です。
リンカーは、すべてのオブジェクトに共通のインターフェイスを使用してオブジェクトをコンポジットとして扱うことができるため、非常に強力な設計パターンです。
これは、他のオブジェクトとの潜在的な非互換性を恐れることなく、オブジェクトを再利用できることを意味します。
アプリケーションを開発するとき、ツリー構造を持つオブジェクトを操作する必要がある場合があります。その場合、このパターンを使用すると非常に効果的です。
の例
医師がヘルスケアサービスをリモートで提供するプラットフォームの認定を受けるのに役立つ会社向けのアプリを開発しているとしましょう。このプロセスには、法定文書の署名の収集が含まれます。デフォルト値がfalseのプロパティを持つ
クラスを操作します。医師が文書に署名すると、署名値が彼の署名に変更されます。また、この関数を実装するために、このクラスにメソッドを定義します。 これはどのように見えるかです:
Document
signature
sign
Document
class Document {
constructor(title) {
this.title = title
this.signature = null
}
sign(signature) {
this.signature = signature
}
}
ここで、リンカーを使用して、で定義されているものと同様のメソッドのサポートを提供し
Document
ます。
class DocumentComposite {
constructor(title) {
this.items = []
if (title) {
this.items.push(new Document(title))
}
}
add(item) {
this.items.push(item)
}
sign(signature) {
this.items.forEach((doc) => {
doc.sign(signature)
})
}
}
これで、テンプレートの優雅さが明らかになります。最後の2つのコードスニペットに注意してください。テンプレートを視覚的に見てみましょう
。順調に進んでいるようです。私たちが得たものは、上記のスキームに対応しています。
したがって、ツリー構造には2つのリーフ/ノード-
Document
とが含まれますDocumentComposite
。これらは両方とも同じインターフェイスを共有するため、単一の複合ツリーの「パーツ」として機能します。
葉/ツリーノードことに留意する必要があるではない(コンポジット
Document
)でないオブジェクトのコレクションまたはグループ、したがって、さらに出て分岐しません。ただし、リーフ/ノードはコンポジット、パーツのコレクションが含まれています(この場合はですitems
)。また、Document
両方DocumentComposite
が共通のインターフェイスを共有しているため、signメソッドを共有していることにも注意してください。
では、このアプローチの有効性は何ですか?DocumentCompositeは、Documentのような署名方法を使用するため、単一のインターフェイスを使用しますが、最終的な目標を達成しながら、より効率的なアプローチを採用します。
したがって、このような構造の代わりに:
const pr2Form = new Document(
'Primary Treating Physicians Progress Report (PR2)',
)
const w2Form = new Document(' (W2)')
const forms = []
forms.push(pr2Form)
forms.push(w2Form)
forms.forEach((form) => {
form.sign('Bobby Lopez')
})
リンカーを利用することで、コードを変更してより効率的にすることができます。
const forms = new DocumentComposite()
const pr2Form = new Document(
' (PR2)',
)
const w2Form = new Document(' (W2)')
forms.add(pr2Form)
forms.add(w2Form)
forms.sign(' ')
console.log(forms)
このアプローチでは、必要なすべてのドキュメントを追加した後、署名を1回実行するだけで済み、この関数はすべてのドキュメントに署名します。
これは、関数の出力を確認することで確認できます
console.log(forms)
。
前の例では、手動でドキュメントを配列に追加してから、各ドキュメントを個別に繰り返し、関数
sign
を実行して署名する必要がありました。
また、
DocumentComposite
ドキュメントのコレクションが含まれている場合があることを忘れないでください。
だから私たちがこれをしたとき:
forms.add(pr2Form) //
forms.add(w2Form) //
私たちのスキームは次の形式を取り
ました。2つの形式を追加しましたが、このスキームは元のスキームとほぼ完全に同じです。
それにもかかわらず、最後の葉が2枚の葉しか形成していないため、ツリーの成長が停止します。これは、最後のスクリーンショットの図とは完全には一致していません。代わりに、ここに示すように、w2formをコンポジットにした場合:
const forms = new DocumentComposite()
const pr2Form = new Document(
' (PR2)',
)
const w2Form = new DocumentComposite(' (W2)')
forms.add(pr2Form)
forms.add(w2Form)
forms.sign(' ')
console.log(forms)
その後、私たちの木は成長し続けることができます:
最終的には、同じ目標を達成することになります。すべてのドキュメントに署名が必要です。
これがリンカーの出番です。
結論
それは今のところすべてです!この情報がお役に立てば幸いです。さらにもっと!ミディアムで
私を見つけてください