検索
ホームページウェブフロントエンドjsチュートリアルプロトタイプ設計パターンをマスターする: 包括的なガイド

ライブラリからオブジェクトをインポートしてクローンを作成しようとしたが、クローン作成にはライブラリの内部構造に関する広範な知識が必要なので失敗したという経験はありますか?

あるいは、長期間プロジェクトに取り組んだ後、休憩を取ってコードをリファクタリングし、コードベースのさまざまな部分で多くの複雑なオブジェクトを再複製していることに気づいたのではないでしょうか?

プロトタイプのデザイン パターンで問題は解決しました!

この記事では、完全に機能するジャーナリング テンプレート Node.js CLI アプリケーションを構築しながら、プロトタイプの設計パターンを検討します。

早速、詳しく見ていきましょう!

概要

プロトタイプ創造的なデザイン パターン であり、新しいオブジェクトを使用してオブジェクトを作成するネイティブな方法に伴うさまざまな問題に対処するデザイン パターンのカテゴリです。 キーワードまたは演算子。

問題

ファクトリ デザイン パターンは、次の作成上の問題を解決します。

  1. 具象クラスに依存せずにアプリケーション内の既存のオブジェクトをコピーするにはどうすればよいですか?

  2. 一部の複雑なオブジェクトは、ユーザーが知らない特定のビジネス ロジックを必要とするフィールドが多数あるか、外部からアクセスできないプライベート フィールドが多数あるため、複製が困難です。オブジェクト。

socket.io ライブラリ からインポートされた socket オブジェクトを例に挙げてみましょう。イメージングではそれを自分で複製する必要がありますか?

ライブラリ内のコードを調べて、ソケットがどのように機能するかを理解する必要があります。オブジェクトには、クローンを作成するために自分で対処する必要がある循環依存関係さえあります。

それに加えて、コードはソケット クラスまたはインターフェイスと、それを作成するための対応するビジネス ロジックに依存することになります。これは確実な依存関係逆転の原則に違反し、コードの変更に対する堅牢性が低くなります。

解決

プロトタイプ設計パターンは、オブジェクトをコピーする責任をオブジェクト自体に委任し、すべてのオブジェクトのクラスでcloneメソッドを宣言することでこれらの問題を解決します。クローン可能です。

class Socket {
  // code........

  clone(): Socket {
    // business logic to instantiate the socket.
    return new Socket(/*...Params*/)
  }
}


const socket1 = new Socket()
const socket2 = socket1.clone()

構造

プロトタイプ デザイン パターンを実装するには、複製可能なオブジェクト内に clone メソッドを直接含めることができます。

または、すべての複製可能なオブジェクトで実装できる共通インターフェイス プロトタイプ を作成します。 Mastering the Prototype Design Pattern: A Comprehensive Guide

共通のインターフェースを持つ利点の 1 つは、すべてのプロトタイプを共通の登録サービス クラスに登録できることです。このクラスは、頻繁に使用されるプロトタイプをキャッシュしてユーザーに返す役割を果たします。 clone メソッドが呼び出されるたびにオブジェクトのクローンを作成する必要がなくなります。

これは、特に複雑なオブジェクトのクローンを作成する場合に非常に便利です。

Mastering the Prototype Design Pattern: A Comprehensive Guide

実践的なシナリオ

このセクションでは、ミニジャーナリング テンプレート Nodejs CLI アプリケーションを構築して、この設計パターンをデモします。

前に見たように、プロトタイプ設計パターンは、オブジェクトのクローンをオブジェクト自体に複製する責任を委任します。

しかし、なぜそれがプロトタイプと呼ばれているのについて疑問に思ったことはありますか?つまり、それがクローン作成と何の関係があるのですか?

この実践的な例を通じてその答えを示しますので、読み続けて楽しみにしていてください。
最終的なコードはこのリポジトリにあります。クローンを作成して、次のコマンドを実行するだけです。

プロトタイプの作成: ジャーナリング テンプレート クラス

まず、次の属性を持つ JournalTemplate を作成しましょう:

  1. name : テンプレートを識別するために必要になります。
  2. セクション : セクションは、感謝、課題、明日の目標など、特定のテーマまたはトピック用に予約されているジャーナリング テンプレートの一部です。

各セクションは次の属性で構成されます:

  • タイトル このセクションのトピックまたはテーマ: 感謝、課題、明日の目標...
  • プロンプト ユーザーがセクション ジャーナリング テキストを書こうとするときに表示されるメッセージ。

JournalTemplate.ts

class Socket {
  // code........

  clone(): Socket {
    // business logic to instantiate the socket.
    return new Socket(/*...Params*/)
  }
}


const socket1 = new Socket()
const socket2 = socket1.clone()

JournalTemplate クラスには、さまざまな属性を設定するためのユーティリティ メソッドが多数あります。

display メソッドは、色付きの整形式の出力を端末に表示するために後で使用されます。

チョーク パッケージは、出力された端末テキストに色を付けるために使用されます。

JournalTemplate オブジェクトは、名前が示すとおり、他のテンプレートまたはジャーナリング ファイル エントリを作成するためのテンプレートまたはプロトタイプとして使用することを目的としています。

そのため、clone メソッドを JournalTemplate クラスに追加しました。

クローン作成ビジネス ロジックを処理する責任を、使用するコードではなく JournalTemplate オブジェクト自体に与えるために追加しました。

ジャーナリング テンプレート レジストリの宣言

次に、JournalTemplate クラスのプロトタイプ インスタンスの保存を担当する TemplateRegistry クラスを作成しましょう。これらのインスタンスを操作するためのメソッドを提供しながら。

TemplateRegistry.ts

class Socket {
  // code........

  clone(): Socket {
    // business logic to instantiate the socket.
    return new Socket(/*...Params*/)
  }
}


const socket1 = new Socket()
const socket2 = socket1.clone()

レジストリは、名前で高速に取得できるように、これらのクラスを Map オブジェクトに格納し、テンプレート インスタンスを追加または削除するための多くのユーティリティ メソッドを公開します。

ジャーナリング テンプレート レジストリのインスタンス化

次に、テンプレート レジストリをインスタンス化し、いくつかの初期テンプレートをシードしましょう。

registry.ts

import chalk from "chalk"

import { TemplateSection } from "./types"

export interface TemplateSection {
  title: string
  prompt: string
}

export class JournalTemplate {
  constructor(
    public name: string,
    public sections: TemplateSection[]
  ) {}
  clone(): JournalTemplate {
    return new JournalTemplate(
      this.name,
      this.sections.map((s) => ({ ...s }))
    )
  }

  display(): void {
    console.log(chalk.cyan(`\nTemplate: ${this.name}`))
    this.sections.forEach((section, index) => {
      console.log(chalk.yellow(`${index + 1}. ${section.title}`))
      console.log(chalk.gray(` Prompt: ${section.prompt}`))
    })
  }

  addSection(section: TemplateSection): void {
    this.sections.push(section)
  }

  removeSection(index: number): void {
    if (index >= 0 && index = 0 && index 



<h3>
  
  
  テンプレートのアクションメソッドの定義
</h3>

<p>このセクションでは、次のようなさまざまなアクションを実行するために、アプリケーション メニューで使用される一連の関数を定義します。</p>

<ol>
<li>ユーザーにテンプレートの名前を入力するよう求め、その後、必要な数のセクションを作成するよう再帰的に求めます。</li>
<li>既存または作成されたテンプレートをすべて表示します。</li>
<li>テンプレートを使用してジャーナリング ファイル エントリを作成します。</li>
<li>既存のテンプレートから新しいテンプレートを作成する: ユーザーは既存のテンプレートを選択するよう求められ、それを直接使用するか、その名前とセクションをオーバーライドすることができます。</li>
</ol>

<p>新しく作成したテンプレートを使用して、新しいジャーナリング エントリを作成できます (1)。</p>

<p><strong>テンプレートを作成します</strong> :</p>

<blockquote>
<p>TemplateActions.ts > createTemplate<br>
</p>
</blockquote>

<pre class="brush:php;toolbar:false">import { JournalTemplate } from "./JournalTemplate"

export class TemplateRegistry {
  private templates: Map<string journaltemplate> = new Map()

  addTemplate(name: string, template: JournalTemplate): void {
    this.templates.set(name, template)
  }

  getTemplate(name: string): JournalTemplate | undefined {
    const template = this.templates.get(name)
    return template ? template.clone() : undefined
  }

  getTemplateNames(): string[] {
    return Array.from(this.templates.keys())
  }
}

</string>
  • テンプレートを作成するには、まずユーザーにテンプレート名の入力を求めます。
  • 次に、セクションの名前と空の配列を使用して、新しいテンプレート オブジェクトをインスタンス化します。
  • その後、ユーザーにセクションの詳細を入力するように求めます。すべてのセクションの情報を入力した後、ユーザーは停止するか、さらにセクションを入力するかを選択できます。

utils.ts >プロンプトセクション詳細

import { JournalTemplate } from "./JournalTemplate"
import { TemplateRegistry } from "./TemplateRegistry"

export const registry = new TemplateRegistry()

registry.addTemplate(
  "Daily Reflection",
  new JournalTemplate("Daily Reflection", [
    {
      title: "Gratitude",
      prompt: "List three things you're grateful for today.",
    },
    { title: "Accomplishments", prompt: "What did you accomplish today?" },
    {
      title: "Challenges",
      prompt: "What challenges did you face and how did you overcome them?",
    },
    {
      title: "Tomorrow's Goals",
      prompt: "What are your top 3 priorities for tomorrow?",
    },
  ])
)

registry.addTemplate(
  "Weekly Review",
  new JournalTemplate("Weekly Review", [
    { title: "Highlights", prompt: "What were the highlights of your week?" },
    {
      title: "Lessons Learned",
      prompt: "What important lessons did you learn this week?",
    },
    {
      title: "Progress on Goals",
      prompt: "How did you progress towards your goals this week?",
    },
    {
      title: "Next Week's Focus",
      prompt: "What's your main focus for next week?",
    },
  ])
)

promptForSectionDetails 関数は、inquirer パッケージを使用してタイトルを尋ね、ユーザーから順番にプロンプ​​トを表示します。

テンプレートを表示 :

TemplateActions.ts >ビューテンプレート

import chalk from "chalk"
import inquirer from "inquirer"

import { JournalTemplate } from "./JournalTemplate"
import { registry } from "./registry"
import { editTemplateSections } from "./templateSectionsActions"
import { promptForSectionDetails } from "./utils"

export async function createTemplate(): Promise<void> {
  const { name } = await inquirer.prompt([
    {
      type: "input",
      name: "name",
      message: "Enter a name for the new template:",
    },
  ])

  const newTemplate = new JournalTemplate(name, [])
  let addMore = true
  while (addMore) {
    const newSection = await promptForSectionDetails()
    newTemplate.addSection(newSection)
    const { more } = await inquirer.prompt([
      {
        type: "confirm",
        name: "more",
        message: "Add another section?",
        default: false,
      },
    ])
    addMore = more
  }

  registry.addTemplate(name, newTemplate)
  console.log(chalk.green(`Template "${name}" created successfully!`))
}

</void>

viewTemplates 関数は次のように動作します:

  1. 最初に registry からすべてのテンプレートを取得し、次に返されたテンプレート配列をループして、JournalTemplate で前に定義した display メソッドを使用します。 クラス。

テンプレートを使用して日記エントリを作成します : 日記テンプレートを作成する理由は、さまざまな種類の日記を書くときに作業を楽にするためです。空のページに直面するのではなく、連続したセクションのタイトルやプロンプトが大量に表示された場合は、日記を記入してください。

useTemplate 関数を詳しく見てみましょう:

  1. まず、レジストリからテンプレート名を取得した後、既存のテンプレートの中からテンプレートを 1 つ選択します。
  2. テンプレート内のすべてのセクションについて、ユーザーは好みのエディタを開いて日記セクションのテキストを入力するように求められます。

TemplateActions.ts > useTemplate

class Socket {
  // code........

  clone(): Socket {
    // business logic to instantiate the socket.
    return new Socket(/*...Params*/)
  }
}


const socket1 = new Socket()
const socket2 = socket1.clone()

既存のテンプレートからテンプレートを作成する :

最後に、プロトタイプのデザインパターンが実際に動作している様子を見ていきます。

既存のテンプレートをオーバーライドして、新しいタイプのテンプレートを動的に作成する方法を見てみましょう。

  1. まず、既存のテンプレートから上書きするテンプレートを選択するようユーザーに求めます。
  2. 次に、新しく作成したテンプレートの名前を入力するよう再度求められます。
  3. レジストリを使用して、ユーザーが選択したテンプレート名を指定してテンプレートを取得します。
  4. clone メソッドを使用して、選択したテンプレートに一致するクローン オブジェクトを取得します。

以下のコードからわかるように、JournalTemplate クラスの詳細を知る必要も、インポートしてコードを汚染する必要もありません。

TemplateActions.ts >既存のテンプレートから作成

  1. 最後に、ユーザーが指定したテンプレート名を新しく作成したオブジェクトに設定し、editTemplateSections メソッドを使用して既存のテンプレート セクションに対して不要な操作を実行するようユーザーに求めます。コードブロックの直後に以下で説明します。
import chalk from "chalk"

import { TemplateSection } from "./types"

export interface TemplateSection {
  title: string
  prompt: string
}

export class JournalTemplate {
  constructor(
    public name: string,
    public sections: TemplateSection[]
  ) {}
  clone(): JournalTemplate {
    return new JournalTemplate(
      this.name,
      this.sections.map((s) => ({ ...s }))
    )
  }

  display(): void {
    console.log(chalk.cyan(`\nTemplate: ${this.name}`))
    this.sections.forEach((section, index) => {
      console.log(chalk.yellow(`${index + 1}. ${section.title}`))
      console.log(chalk.gray(` Prompt: ${section.prompt}`))
    })
  }

  addSection(section: TemplateSection): void {
    this.sections.push(section)
  }

  removeSection(index: number): void {
    if (index >= 0 && index = 0 && index 



<blockquote>
<p>templateSectionsAction > editTemplateSections<br>
</p>
</blockquote>

<pre class="brush:php;toolbar:false">import { JournalTemplate } from "./JournalTemplate"

export class TemplateRegistry {
  private templates: Map<string journaltemplate> = new Map()

  addTemplate(name: string, template: JournalTemplate): void {
    this.templates.set(name, template)
  }

  getTemplate(name: string): JournalTemplate | undefined {
    const template = this.templates.get(name)
    return template ? template.clone() : undefined
  }

  getTemplateNames(): string[] {
    return Array.from(this.templates.keys())
  }
}

</string>

以下に定義されている editTemplateSections は基本的にメニューを表示し、次のようなさまざまな操作を提供することで、必要に応じて既存のセクションをオーバーライドするようユーザーに求めます。

  • セクションを追加
  • セクションを削除
  • セクションを編集

アプリケーションメニュー

最後に、index.ts ファイル内の前述の関数をすべて利用して、CLI アプリをブートストラップし、さまざまなテンプレート操作オプションを含むメニューを表示します。

  • テンプレートを作成します。
  • 既存のテンプレートからテンプレートを作成します。
  • テンプレートを表示します。
  • テンプレートを使用して日記エントリを作成します。
  • プログラムを終了します。

index.ts

class Socket {
  // code........

  clone(): Socket {
    // business logic to instantiate the socket.
    return new Socket(/*...Params*/)
  }
}


const socket1 = new Socket()
const socket2 = socket1.clone()

結論

プロトタイプ デザイン パターンは、既存のオブジェクトをクローンして新しいオブジェクトを作成する強力な方法を提供します。ジャーナリング テンプレート アプリケーションでは、このパターンを使用して既存のテンプレートに基づいて新しいテンプレートを作成できることを確認し、プロトタイプ パターンの柔軟性と効率性を実証しました。

このパターンを使用することで、拡張と変更が簡単なシステムを作成し、現実世界のアプリケーションにおけるオブジェクト指向設計パターンの真の力を実証しました。

接触

ご質問がある場合、またはさらに話し合いたい場合は、お気軽にここからご連絡ください。

コーディングを楽しんでください!

以上がプロトタイプ設計パターンをマスターする: 包括的なガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptフレームワーク:最新のWeb開発のパワーJavaScriptフレームワーク:最新のWeb開発のパワーMay 02, 2025 am 12:04 AM

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

JavaScript、C、およびブラウザの関係JavaScript、C、およびブラウザの関係May 01, 2025 am 12:06 AM

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか

node.jsは、型を使用してストリーミングしますnode.jsは、型を使用してストリーミングしますApr 30, 2025 am 08:22 AM

node.jsは、主にストリームのおかげで、効率的なI/Oで優れています。 ストリームはデータを段階的に処理し、メモリの過負荷を回避します。大きなファイル、ネットワークタスク、リアルタイムアプリケーションの場合。ストリームとTypeScriptのタイプの安全性を組み合わせることで、パワーが作成されます

Python vs. JavaScript:パフォーマンスと効率の考慮事項Python vs. JavaScript:パフォーマンスと効率の考慮事項Apr 30, 2025 am 12:08 AM

PythonとJavaScriptのパフォーマンスと効率の違いは、主に以下に反映されています。1)解釈された言語として、Pythonはゆっくりと実行されますが、開発効率が高く、迅速なプロトタイプ開発に適しています。 2)JavaScriptはブラウザ内の単一のスレッドに限定されていますが、マルチスレッドおよび非同期I/Oを使用してnode.jsのパフォーマンスを改善でき、両方とも実際のプロジェクトで利点があります。

JavaScriptの起源:その実装言語の調査JavaScriptの起源:その実装言語の調査Apr 29, 2025 am 12:51 AM

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

舞台裏:JavaScriptをパワーする言語は何ですか?舞台裏:JavaScriptをパワーする言語は何ですか?Apr 28, 2025 am 12:01 AM

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの未来:傾向と予測PythonとJavaScriptの未来:傾向と予測Apr 27, 2025 am 12:21 AM

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

Python vs. JavaScript:開発環境とツールPython vs. JavaScript:開発環境とツールApr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール