目次
装饰模式
Composite(组合)
ホームページ ウェブフロントエンド jsチュートリアル 知っておくべき 5 つの TypeScript デザイン パターン

知っておくべき 5 つの TypeScript デザイン パターン

Nov 20, 2020 pm 05:36 PM
javascript typescript デザインパターン

この記事では、5 つの TypeScript デザイン パターンを紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

知っておくべき 5 つの TypeScript デザイン パターン

# デザイン パターンは、開発者が問題を解決するのに役立つテンプレートです。この本ではあまりにも多くのパターンが取り上げられており、多くの場合、異なるニーズを対象としています。ただし、これらは 3 つの異なるグループに分類できます。 <p></p>
  • 構造パターン さまざまなコンポーネント (またはクラス) 間の関係を扱い、新しい機能を提供する新しい構造を形成します。構造パターンの例には、CompositeAdapter、および Decorator があります。
  • 動作パターンコンポーネント間の共通の動作を独立したエンティティに抽象化します。行動パターンの例としては、コマンド、戦略、そして私の個人的なお気に入りである Observer Pattern があります。
  • 作成モードはクラスのインスタンス化に焦点を当てており、新しいエンティティの作成が容易になります。ファクトリ メソッド、シングルトン、抽象ファクトリについて話しています。

シングルトン パターン

シングルトン パターンは、おそらく最も有名なデザイン パターンの 1 つです。これは、クラスのインスタンス化を何度試みても、使用できるインスタンスは 1 つだけであることが保証されるため、作成パターンです。 <p></p>データベース接続の処理などはシングルトン モードで実行できます。これは、ユーザー要求ごとに再接続することなく、一度に 1 つだけ処理したいためです。 <p></p>
class MyDBConn {
  protected static instance: MyDBConn | null = null
  private id:number = 0

  constructor() {
    this.id = Math.random()
  }

  public getID():number {
    return this.id
  }

  public static getInstance():MyDBConn {
    if (!MyDBConn.instance) {
      MyDBConn.instance = new MyDBConn()
    }
    return MyDBConn.instance
  }
}

const connections = [
  MyDBConn.getInstance(),
  MyDBConn.getInstance(),
  MyDBConn.getInstance(),
  MyDBConn.getInstance(),
  MyDBConn.getInstance()
]

connections.forEach( c => {
    console.log(c.getID())
})
ログイン後にコピー
クラスを直接インスタンス化することはできませんが、

getInstance メソッドを使用すると、複数のインスタンスが存在しないようにできます。上の例では、データベース接続をラップする疑似クラスがこのパターンからどのように恩恵を受けるかがわかります。

この例は、

getInstance メソッドを何度呼び出しても、接続は常に同じであることを示しています。

上記の実行結果: <p></p>
0.4047087250990713
0.4047087250990713
0.4047087250990713
0.4047087250990713
0.4047087250990713
ログイン後にコピー

ファクトリー モード

##ファクトリー モード

は、Single と同様の作成モードです。ケースモード 同じです。ただし、このパターンは対象のオブジェクトに直接作用するのではなく、オブジェクトの作成を管理するだけです。 説明: 移動する乗り物をシミュレートするコードを作成するとします。車、自転車、飛行機など、さまざまな種類の乗り物があります。モバイル コードは、各

vehicle

クラスにカプセル化する必要があります。ただし、呼び出し中の move メソッドのコードは汎用的なものにすることができます。 ここでの質問は、オブジェクトの作成をどのように処理するかということです? 3 つのメソッドを持つ単一の

creator

クラス、またはパラメーターを取るメソッドが存在する可能性があります。いずれの場合も、より多くの vehices の作成をサポートするためにそのロジックを拡張するには、同じクラスを継続的に成長させる必要があります。 ただし、ファクトリ メソッド パターンを使用することにした場合は、次の操作を行うことができます。

<p></p>

知っておくべき 5 つの TypeScript デザイン パターン次に、新しいメソッドを作成します。 object required コードは、車両タイプごとに 1 つずつ、新しいクラスにカプセル化されます。これにより、将来車両を追加する必要がある場合、既存のクラスを変更することなく、新しいクラスを追加するだけで済みます。

これを

TypeScript

を使用してどのように実現できるかを見てみましょう: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">interface Vehicle {     move(): void } class Car implements Vehicle {     public move(): void {         console.log(&quot;Moving the car!&quot;)     } } class Bicycle implements Vehicle {     public move(): void {         console.log(&quot;Moving the bicycle!&quot;)     } } class Plane implements Vehicle {     public move(): void {         console.log(&quot;Flying the plane!&quot;)     } } // VehicleHandler 是“抽象的”,因为没有人会实例化它instantiate it // 我们要扩展它并实现抽象方法 abstract class VehicleHandler {     // 这是真正的处理程序需要实现的方法     public abstract createVehicle(): Vehicle      public moveVehicle(): void {         const myVehicle = this.createVehicle()         myVehicle.move()     } }  class PlaneHandler extends VehicleHandler{     public createVehicle(): Vehicle {         return new Plane()     } } class CarHandler  extends VehicleHandler{     public createVehicle(): Vehicle {         return new Car()     } } class BicycleHandler  extends VehicleHandler{     public createVehicle(): Vehicle {         return new Bicycle()     } } /// User code... const planes = new PlaneHandler() const cars = new CarHandler() planes.moveVehicle() cars.moveVehicle()</pre><div class="contentsignin">ログイン後にコピー</div></div>上記は大量のコードですが、上の図を使用して理解できます。基本的に最終的に重要なのはカスタム ハンドラーです。ここでは作成者ではなくハンドラーと呼びます。これは、オブジェクトを作成するだけでなく、オブジェクトを使用するロジック (moveVehicle メソッド) も備えているためです。

このパターンの利点は、新しい

vehicle

タイプを追加する場合、その vehicle クラスとそのハンドラー プログラム クラスを追加するだけで済むことです。他のクラスの LOC を増加させることなく。

Observer Pattern

すべてのパターンの中で、私のお気に入りは

Observer Pattern

です。これは、実装できる型の動作のためです。 どのように機能するのでしょうか? 基本的に、このパターンは、観察されるエンティティの状態の変化に反応する一連のオブザーバー オブジェクトがあることを示します。これを達成するために、観察される側で変更が受信されると、そのメソッドの 1 つを呼び出して観察者に通知する責任があります。

実際には、このパターンの実装は比較的簡単です。コードをざっと見てから確認してみましょう。

type InternalState = {
  event: String
}

abstract class Observer {
  abstract update(state:InternalState): void
}

abstract class Observable {
  protected observers: Observer[] = []
  protected state:InternalState = { event: ""}

  public addObserver(o: Observer):void {
    this.observers.push(o)
  }

  protected notify () {
    this.observers.forEach(o => o.update(this.state))
  }
}


class ConsoleLogger extends Observer  {

    public update(newState: InternalState) {
        console.log("New internal state update: ", newState)
    }
}

class InputElement extends Observable {

    public click():void {
        this.state = { event: "click" }
        this.notify()
    }

}

const input = new InputElement()
input.addObserver(new ConsoleLogger())

input.click()
ログイン後にコピー

ご覧のとおり、2 つの抽象クラスを使用して # を定義できます。 ##Observer

Observable エンティティの変更に反応するオブジェクトを表します。上記の例では、クリックされた InputElement エンティティ (フロントエンドに HTML 入力フィールドがある場合と同様) と、コンソールにログを記録する ConsoleLogger があると想定しています。起こったことすべて。 このパターンの利点は、内部コードをいじらずに Observable

の内部状態を理解し、それに反応できることです。他のアクションを実行するオブザーバー (特定のイベントに反応するオブザーバーも含む) を引き続き追加し、各通知に対して何を行うかをコードに決定させることができます。 <p></p>

装饰模式

装饰模式试图在运行时向现有对象添加行为。 从某种意义上说,我们可以将其视为动态继承,因为即使没有创建新类来添加行为,我们也正在创建具有扩展功能的新对象。

这样考虑:假设我们拥有一个带有move方法的Dog类,现在您想扩展其行为,因为我们想要一只超级狗和一只可以游泳的狗。

通常,我们需要在 Dog 类中添加move 行为,然后以两种方式扩展该类,即SuperDogSwimmingDog类。 但是,如果我们想将两者混合在一起,则必须再次创建一个新类来扩展它们的行为,但是,有更好的方法。

组合让我们可以将自定义行为封装在不同的类中,然后使用该模式通过将原始对象传递给它们的构造函数来创建这些类的新实例。 让我们看一下代码:

abstract class Animal {

    abstract move(): void
}

abstract class SuperDecorator extends Animal {
    protected comp: Animal
    
    constructor(decoratedAnimal: Animal) {
        super()
        this.comp = decoratedAnimal
    }
    
    abstract move(): void
}

class Dog extends Animal {

    public move():void {
        console.log("Moving the dog...")
    }
}

class SuperAnimal extends SuperDecorator {

    public move():void {
        console.log("Starts flying...")
        this.comp.move()
        console.log("Landing...")
    }
}

class SwimmingAnimal extends SuperDecorator {

    public move():void {
        console.log("Jumps into the water...")
        this.comp.move()
    }
}


const dog = new Dog()

console.log("--- Non-decorated attempt: ")
dog.move()

console.log("--- Flying decorator --- ")
const superDog =  new SuperAnimal(dog)
superDog.move()

console.log("--- Now let's go swimming --- ")
const swimmingDog =  new SwimmingAnimal(dog)
swimmingDog.move()
ログイン後にコピー

注意几个细节:

  • 实际上,SuperDecorator类扩展了Animal类,与Dog类扩展了相同的类。 这是因为装饰器需要提供与其尝试装饰的类相同的公共接口。
  • SuperDecorator类是abstract ,这意味着并没有使用它,只是使用它来定义构造函数,该构造函数会将原始对象的副本保留在受保护的属性中。 公共接口的覆盖是在自定义装饰器内部完成的。
  • SuperAnimalSwimmingAnimal是实际的装饰器,它们是添加额外行为的装饰器。

进行此设置的好处是,由于所有装饰器也间接扩展了Animal类,因此如果你要将两种行为混合在一起,则可以执行以下操作:

const superSwimmingDog =  new SwimmingAnimal(superDog)

superSwimmingDog.move()
ログイン後にコピー

Composite(组合)

关于Composite模式,其实就是组合模式,又叫部分整体模式,这个模式在我们的生活中也经常使用。

比如编写过前端的页面,肯定使用过<p></p>等标签定义一些格式,然后格式之间互相组合,通过一种递归的方式组织成相应的结构,这种方式其实就是组合,将部分的组件镶嵌到整体之中。

关于此模式的有趣之处在于,它不是一个简单的对象组,它可以包含实体或实体组,每个组可以同时包含更多组,这就是我们所说的树。

看一个例子:

interface IProduct {
  getName(): string
  getPrice(): number
}

class Product implements IProduct {
  private price:number
  private name:string

  constructor(name:string, price:number) {
    this.name = name
    this.price = price
  }

  public getPrice():number {
    return this.price
  }

  public getName(): string {
    return this.name
  }
}

class Box implements IProduct {

    private products: IProduct[] = []
    
    contructor() {
        this.products = []
    }
    
    public getName(): string {
        return "A box with " + this.products.length + " products"
    } 
    
    add(p: IProduct):void {
        console.log("Adding a ", p.getName(), "to the box")
        this.products.push(p)
    }

    getPrice(): number {
        return this.products.reduce( (curr: number, b: IProduct) => (curr + b.getPrice()),  0)
    }
}

//Using the code...
const box1 = new Box()
box1.add(new Product("Bubble gum", 0.5))
box1.add(new Product("Samsung Note 20", 1005))

const box2 = new Box()
box2.add( new Product("Samsung TV 20in", 300))
box2.add( new Product("Samsung TV 50in", 800))

box1.add(box2)

console.log("Total price: ", box1.getPrice())
ログイン後にコピー

在上面的示例中,我们可以将product 放入Box中,也可以将Box放入其他Box中,这是组合的经典示例。因为我们要实现的是获得完整的交付价格,因此需要在大box里添加每个元素的价格(包括每个小box的价格)。

上面运行的结果:

Adding a  Bubble gum to the box
Adding a  Samsung Note 20 to the box
Adding a  Samsung TV 20in to the box
Adding a  Samsung TV 50in to the box
Adding a  A box with 2 products to the box
Total price:  2105.5
ログイン後にコピー

因此,在处理遵循同一接口的多个对象时,请考虑使用此模式。 通过将复杂性隐藏在单个实体(组合本身)中,您会发现它有助于简化与小组的互动方式。

今天的分享就到这里了,感谢大家的观看,我们下期再见。

原文地址:https://blog.bitsrc.io/design-patterns-in-typescript-e9f84de40449

作者:Fernando Doglio

译文地址:https://segmentfault.com/a/1190000025184682

更多编程相关知识,请访问:编程课程!!

以上が知っておくべき 5 つの TypeScript デザイン パターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Java フレームワークにおけるデザイン パターンとアーキテクチャ パターンの違い Java フレームワークにおけるデザイン パターンとアーキテクチャ パターンの違い Jun 02, 2024 pm 12:59 PM

Java フレームワークにおけるデザイン パターンとアーキテクチャ パターンの違いは、デザイン パターンがソフトウェア設計における一般的な問題に対する抽象的な解決策を定義し、ファクトリ パターンなどのクラスとオブジェクト間の相互作用に焦点を当てていることです。アーキテクチャ パターンは、階層化アーキテクチャなどのシステム コンポーネントの編成と相互作用に焦点を当てて、システム構造とモジュールの間の関係を定義します。

開かれた意図:ERC-7683は、イーサリアムチェーン間の相乗効果の意図で「ウォルマート」スーパーマーケットになることができますか? 開かれた意図:ERC-7683は、イーサリアムチェーン間の相乗効果の意図で「ウォルマート」スーパーマーケットになることができますか? Mar 04, 2025 pm 06:24 PM

YBBCAPITAL Researcherac-Coreによって書かれた:Ethereum Fragmentationの問題とオープンインテンツフレームワーク:ERC-7683の画期的な方法ソース: @Ethereumfndnl2とDefiの活況を呈している開発により、イーサリアムの流動性の断片化が増加しました。資産の流動性はL1と多くのL2に散らばっており、孤立した「小さなプール」など、さまざまなプラットフォーム間の効果的な相互接続が不足しており、イーサリアムの全体的な効率を妨げています。 2024年、イーサリアムは100を超える新しいチェーンを追加しました。これは、幅広い製品を備えた大きなショッピングモールのようなものですが、異なる通貨での決済が必要です。この問題を解決するために、Ethereum Foundationは2月20日にOpenIntentsFをリリースしました

PHP デザイン パターン: テスト駆動開発の実践 PHP デザイン パターン: テスト駆動開発の実践 Jun 03, 2024 pm 02:14 PM

TDD は、高品質の PHP コードを作成するために使用されます。その手順には、テスト ケースを作成し、期待される機能を記述し、テスト ケースを失敗させることが含まれます。過度な最適化や詳細な設計を行わずに、テスト ケースのみが通過するようにコードを記述します。テスト ケースが合格したら、コードを最適化およびリファクタリングして、可読性、保守性、およびスケーラビリティを向上させます。

Java フレームワークでデザイン パターンを使用する利点と欠点は何ですか? Java フレームワークでデザイン パターンを使用する利点と欠点は何ですか? Jun 01, 2024 pm 02:13 PM

Java フレームワークでデザイン パターンを使用する利点には、コードの可読性、保守性、拡張性の向上が含まれます。欠点としては、複雑さ、パフォーマンスのオーバーヘッド、使いすぎによる学習曲線の急上昇などが挙げられます。実際のケース: プロキシ モードはオブジェクトの遅延読み込みに使用されます。デザイン パターンを賢く使用して、その利点を活用し、欠点を最小限に抑えます。

Guice フレームワークでのデザイン パターンの適用 Guice フレームワークでのデザイン パターンの適用 Jun 02, 2024 pm 10:49 PM

Guice フレームワークは、次のような多くの設計パターンを適用します。 シングルトン パターン: @Singleton アノテーションによってクラスのインスタンスが 1 つだけであることを保証します。ファクトリ メソッド パターン: @Provides アノテーションを使用してファクトリ メソッドを作成し、依存関係の注入中にオブジェクト インスタンスを取得します。戦略モード: アルゴリズムをさまざまな戦略クラスにカプセル化し、@Named アノテーションを通じて特定の戦略を指定します。

Spring MVCフレームワークでのデザインパターンの適用 Spring MVCフレームワークでのデザインパターンの適用 Jun 02, 2024 am 10:35 AM

SpringMVC フレームワークは次の設計パターンを使用します: 1. シングルトン モード: Spring コンテナーを管理します。 2. ファサード モード: コントローラー、ビュー、およびモデルの対話を調整します。 3. ストラテジ モード: リクエストに基づいてリクエスト ハンドラーを選択します。 : アプリケーション イベントを公開し、リッスンします。これらの設計パターンは SpringMVC の機能と柔軟性を強化し、開発者が効率的で保守可能なアプリケーションを作成できるようにします。

PHP デザイン パターン: 特定のソフトウェアの問題を解決するために使用されるパターン PHP デザイン パターン: 特定のソフトウェアの問題を解決するために使用されるパターン Jun 01, 2024 am 11:07 AM

PHP 設計パターンは、ソフトウェア開発における一般的な問題に対する既知の解決策を提供します。一般的なパターン タイプには、創造的 (ファクトリ メソッド パターンなど)、構造的 (デコレーター パターンなど)、および動作的 (オブザーバー パターンなど) が含まれます。デザイン パターンは、繰り返し発生する問題の解決、保守性の向上、チームワークの促進に特に役立ちます。電子商取引システムでは、オブザーバー パターンにより、ショッピング カートと注文ステータスの間の自動更新を実現できます。全体として、PHP デザイン パターンは、堅牢でスケーラブルで保守可能なアプリケーションを作成するための重要なツールです。

TypeScriptインターフェイスは、SQLiteのDateTimeタイプをどのように正確に表していますか? TypeScriptインターフェイスは、SQLiteのDateTimeタイプをどのように正確に表していますか? Apr 04, 2025 pm 05:15 PM

TypeScript定義インターフェイスを使用してSQLiteデータベースのDateTimeタイプをマッピングするときに、TypeScriptインターフェイスでSQLiteを表すDateTimeタイプ、適切なクラスを選択してください...

See all articles