首頁 >web前端 >js教程 >掌握建構器模式:建立動態 AI 提示產生器 CLI

掌握建構器模式:建立動態 AI 提示產生器 CLI

Susan Sarandon
Susan Sarandon原創
2024-11-15 05:30:031047瀏覽

您在開發過程中是否遇到需要處理複雜物件的情況?可能是因為它們要么參數太多,甚至可以嵌套,要么需要很多構建步驟和複雜的邏輯來構建。

也許您想設計一個具有簡潔介面的模組,而不必每次都分散或思考複雜物件的創建程式碼!

這就是建構器設計模式的用武之地!

在本教程中,我們將解釋有關構建器設計模式的所有內容,然後我們將構建一個CLI Node.js 應用程序,用於使用構建器設計模式 生成DALL-E 3優化的影像產生提示.

最終程式碼可在此 Github 儲存庫中取得。

概述

問題

Builder 是一種創造設計模式,它是一類設計模式,用於處理使用new 創建物件的本機方式所帶來的不同問題。 關鍵字或運算子。

建構器設計模式專注於解決以下問題:

  1. 提供一個簡單的介面來創建複雜的對象:想像一個深度嵌套的對象,它具有許多必需的初始化步驟。

  2. 將建構程式碼與物件本身分開,允許從同一物件建立多個表示或配置。

解決方案

Builder 設計模式 透過將物件建立的責任委託給稱為 builders 的特殊物件來解決這兩個問題。

建構器物件組合原始對象,並將建立過程分解為多個階段或步驟。

每個步驟都由建構器物件中的一個方法定義,該方法根據某些業務邏輯初始化物件屬性的子集。

class PromptBuilder {
  private prompt: Prompt

  constructor() {
    this.reset()
  }

  reset() {
    this.prompt = new Prompt()
  }

  buildStep1() {
    this.prompt.subject = "A cheese eating a burger"
    //initialization code...
    return this
  }

  buildStep2() {
    //initialization code...
    return this
  }

  buildStep3() {
    //initialization code...
    return this
  }

  build() {
    const result = structuredClone(this.prompt) // deep clone
    this.reset()
    return result
  }
}

客戶端程式碼:我們只需要使用建構器並呼叫各個步驟

const promptBuilder = new PromptBuilder()
const prompt1 = promptBuilder
  .buildStep1() // optional
  .buildStep2() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

const prompt2 = promptBuilder
  .buildStep1() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

典型的建構器設計模式

Mastering the Builder Pattern: Create a Dynamic AI Prompt Generator CLI

典型的建構器設計模式由 4 個主要類別組成:

  1. Builder :建構器介面應該只定義建構方法,而沒有 build() 方法,該方法負責傳回已建立的實體。

  2. 具體建構器類別:每個特定建構器都提供自己的建構器介面方法的實現,以便它可以產生自己的物件變體(產品1產品2)。

  3. 客戶端 :您可以將客戶端視為我們物件的頂級消費者、匯入庫模組的使用者或我們應用程式的入口點。

  4. Director:即使同一個構建器物件也可以產生該物件的許多變體。

class PromptBuilder {
  private prompt: Prompt

  constructor() {
    this.reset()
  }

  reset() {
    this.prompt = new Prompt()
  }

  buildStep1() {
    this.prompt.subject = "A cheese eating a burger"
    //initialization code...
    return this
  }

  buildStep2() {
    //initialization code...
    return this
  }

  buildStep3() {
    //initialization code...
    return this
  }

  build() {
    const result = structuredClone(this.prompt) // deep clone
    this.reset()
    return result
  }
}

從上面的程式碼可以看出,某些實體非常需要負責指導或編排對建構器方法的不同可能的呼叫組合序列,因為每個序列可能會產生不同的結果物件。

那麼我們能否進一步抽象流程,為客戶端程式碼提供更簡單的介面?

這就是

Director 類別 的用武之地。 director 從客戶端承擔更多責任,並允許我們分解所有這些建構器序列呼叫並根據需要重複使用它們。

const promptBuilder = new PromptBuilder()
const prompt1 = promptBuilder
  .buildStep1() // optional
  .buildStep2() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

const prompt2 = promptBuilder
  .buildStep1() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

客戶端程式碼


const promptBuilder = new PromptBuilder()
const prompt1 = promptBuilder.buildStep1().buildStep2().build()

const prompt2 = promptBuilder.buildStep1().buildStep3().build()

從上面的程式碼可以看出,客戶端程式碼不需要知道建立prompt1或prompt2的詳細資料。它只是呼叫主管,設定正確的建構器對象,然後呼叫 makePrompt 方法。

實際場景

為了進一步展示建構器設計模式的實用性,讓我們從頭開始建立一個

快速工程影像產生AI CLI工具

此 CLI 應用程式的原始程式碼可在此處取得。

CLI 工具的工作方式如下:

    CLI 將提示使用者選擇一種提示風格:現實或數位藝術。
  1. 然後它會要求使用者輸入提示主題,例如:起司吃漢堡。
  2. 根據您的選擇(數位藝術或現實),CLI 工具將建立包含許多配置詳細資訊的複雜提示物件。
真實的提示需要建構以下所有配置屬性。

檔案:promps.ts


class Director {
  private builder: PromptBuilder
  constructor() {}

  setBuilder(builder: PromptBuilder) {
    this.builder = builder
  }

  makePrompt1() {
    return this.builder.buildStep1().buildStep2().build()
  }

  makePrompt2() {
    return this.builder.buildStep1().buildStep3().build()
  }
}

檔案:promps.ts


const director = new Director()
const builder = new PromptBuilder()
director.setBuilder(builder)
const prompt1 = director.makePrompt1()
const prompt2 = director.makePrompt2()

如您所見,每種提示類型都需要建立許多複雜的屬性,例如

artStylecolorPalettelightingEffectperspective相機種類

隨意探索所有屬性詳細信息,這些詳細信息在我們項目的

enums.ts 文件中定義。

枚舉.ts


class PromptBuilder {
  private prompt: Prompt

  constructor() {
    this.reset()
  }

  reset() {
    this.prompt = new Prompt()
  }

  buildStep1() {
    this.prompt.subject = "A cheese eating a burger"
    //initialization code...
    return this
  }

  buildStep2() {
    //initialization code...
    return this
  }

  buildStep3() {
    //initialization code...
    return this
  }

  build() {
    const result = structuredClone(this.prompt) // deep clone
    this.reset()
    return result
  }
}

我們的CLI 應用程式的用戶可能不知道所有這些配置;他們可能只想根據特定的主題生成圖像,例如吃起司漢堡和風格(現實或數字藝術)。

複製 Github 儲存庫後,使用以下指令安裝依賴項:

const promptBuilder = new PromptBuilder()
const prompt1 = promptBuilder
  .buildStep1() // optional
  .buildStep2() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

const prompt2 = promptBuilder
  .buildStep1() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

安裝依賴項後,執行以下命令:

const promptBuilder = new PromptBuilder()
const prompt1 = promptBuilder.buildStep1().buildStep2().build()

const prompt2 = promptBuilder.buildStep1().buildStep3().build()

系統將提示您選擇提示類型:現實數位藝術Mastering the Builder Pattern: Create a Dynamic AI Prompt Generator CLI

然後您必須輸入提示的主題。讓我們堅持起司漢堡

根據您的選擇,您將收到以下文字提示:

寫實風格提示 :

class Director {
  private builder: PromptBuilder
  constructor() {}

  setBuilder(builder: PromptBuilder) {
    this.builder = builder
  }

  makePrompt1() {
    return this.builder.buildStep1().buildStep2().build()
  }

  makePrompt2() {
    return this.builder.buildStep1().buildStep3().build()
  }
}

數位藝術風格提示 :

const director = new Director()
const builder = new PromptBuilder()
director.setBuilder(builder)
const prompt1 = director.makePrompt1()
const prompt2 = director.makePrompt2()

複製先前的命令,然後將其貼上到 ChatGPT 中。 ChatGPT 將使用 DALL-E 3 模型來產生影像。

真實影像提示結果

數位藝術影像提示結果

Mastering the Builder Pattern: Create a Dynamic AI Prompt Generator CLI

Mastering the Builder Pattern: Create a Dynamic AI Prompt Generator CLI

記住提示參數的複雜性以及建立每種類型的提示所需的專業知識,更不用說所需的醜陋的建構函式呼叫。

class RealisticPhotoPrompt {
  constructor(
    public subject: string,
    public location: string,
    public timeOfDay: string,
    public weather: string,
    public camera: CameraType,
    public lens: LensType,
    public focalLength: number,
    public aperture: string,
    public iso: number,
    public shutterSpeed: string,
    public lighting: LightingCondition,
    public composition: CompositionRule,
    public perspective: string,
    public foregroundElements: string[],
    public backgroundElements: string[],
    public colorScheme: ColorScheme,
    public resolution: ImageResolution,
    public postProcessing: string[]
  ) {}
}

免責宣告:這個醜陋的建構函式呼叫在 JavaScript 中並不是一個大問題,因為我們可以傳遞一個所有屬性都可為空的配置物件。

抽象構建提示的過程,並使我們的程式碼開​​放擴展並關閉修改(O in SOLID),並讓我們的圖書館客戶無縫或更輕鬆地使用我們的提示生成庫,我們將選擇實作建構器設計模式

讓我們先聲明通用提示產生器介面

介面宣告了一堆方法:

  1. buildBasePropertiesbuildTechnicalDetailsbuildArtisticElements 是構建 RealisticDigital Art 提示的步驟。
  2. setSubject 是我們所有提示建構器之間的共用方法;它是不言自明的,將用於設定提示主題。

builders.ts

class PromptBuilder {
  private prompt: Prompt

  constructor() {
    this.reset()
  }

  reset() {
    this.prompt = new Prompt()
  }

  buildStep1() {
    this.prompt.subject = "A cheese eating a burger"
    //initialization code...
    return this
  }

  buildStep2() {
    //initialization code...
    return this
  }

  buildStep3() {
    //initialization code...
    return this
  }

  build() {
    const result = structuredClone(this.prompt) // deep clone
    this.reset()
    return result
  }
}

builders.ts

const promptBuilder = new PromptBuilder()
const prompt1 = promptBuilder
  .buildStep1() // optional
  .buildStep2() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

const prompt2 = promptBuilder
  .buildStep1() // optional
  .buildStep3() // optional
  .build() // we've got a prompt

從上面的實作中可以看到,每個建構器都選擇建立自己類型的提示(最終的提示形狀不同),同時堅持 PromptBuilder 合約定義的相同建置步驟!

現在,讓我們繼續我們的 Director 類別定義。

導演.ts

const promptBuilder = new PromptBuilder()
const prompt1 = promptBuilder.buildStep1().buildStep2().build()

const prompt2 = promptBuilder.buildStep1().buildStep3().build()

Director 類別包裝了PromptBuilder 並允許我們建立一個提示配置,其中包括呼叫從setSubject 的所有建構器方法Element 🎜>.

這將簡化

index.ts 文件中的客戶端程式碼,我們將在下一節中看到。

序列化器.ts


class Director {
  private builder: PromptBuilder
  constructor() {}

  setBuilder(builder: PromptBuilder) {
    this.builder = builder
  }

  makePrompt1() {
    return this.builder.buildStep1().buildStep2().build()
  }

  makePrompt2() {
    return this.builder.buildStep1().buildStep3().build()
  }
}

為了將最終提示文字列印到終端控制台,我實作了一些實用程式序列化函數。

現在我們的提示庫產生程式碼已經準備好了。讓我們在

index.ts 檔案中使用它。

index.ts


const director = new Director()
const builder = new PromptBuilder()
director.setBuilder(builder)
const prompt1 = director.makePrompt1()
const prompt2 = director.makePrompt2()

上面的程式碼執行以下操作:

    使用詢問器包提示使用者選擇提示樣式和主題:
  1. getUserInput.
  2. 從使用者取得主題和藝術風格後,客戶端程式碼僅使用我們庫中的兩個元件:
  3. PromptBuilderDirector
  4. 我們先實例化
  5. Director
  6. 然後,根據選擇的提示樣式,我們實例化對應的建構器,並將其設定為
  7. Director類別。
  8. 最後,我們以所選主題作為參數呼叫
  9. director.makePrompt 方法,從 builder 取得提示,並將序列化的提示列印到終端控制台。
請記住:不可能從導演那裡獲得提示,因為每種建構器類型產生的提示形狀不同。

結論

Builder 設計模式已被證明是創建具有多種配置的複雜物件的出色解決方案,如我們的 AI 影像提示生成 CLI 應用程式所示。這就是為什麼 Builder 模式在這種情況下很有用:

  1. 簡化物件建立:此模式可讓我們建立複雜的 RealisticPhotoPrompt 和 DigitalArtPrompt 對象,而無需將其複雜的建構流程暴露給客戶端程式碼。

  2. 靈活性:透過為每種提示類型使用單獨的建構器類,我們可以輕鬆添加新的提示類型或修改現有的提示類型,而無需更改客戶端程式碼。

  3. 程式碼組織:此模式有助於將建構邏輯與表示分離,使程式碼更加模組化且更易於維護。

  4. 可重用性:PromptDirector 類別允許我們為不同類型的提示重用相同的建構過程,增強程式碼的可重用性。

  5. 抽象 :index.ts 中的客戶端程式碼保持簡單並專注於高階邏輯,而提示建構的複雜性在建構器類別中被抽象化。

接觸

如果您有任何疑問或想進一步討論,請隨時與我聯絡。

編碼愉快!

以上是掌握建構器模式:建立動態 AI 提示產生器 CLI的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn