Kimn
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- ###### tags: `Design Pattern` --- # 11/04 ## 命令模式 ### 概述: - 日常生活中,我們出去吃飯都會遇到下面的場景。 ![](https://i.imgur.com/16q9OX4.png) ### 定義: - 將一個請求封裝成一個物件,使發出請求的責任和執行請求的責任分割開。 - 這樣兩者之間通過命令物件進行溝通,這樣方便將命令物件進行存儲、傳遞、調用、增加與管理。 ### 結構 命令模式包含以下主要角色 - 抽象命令類(Command)角色:定義命令的接口,聲明執行方法。 - 具體命令(Concrete Command)角色:具體的命令,實現命令接口;通常會持有接收者,並調用接手者的功能來完成命令要執行的操作。 - 實現者/接收者(Receiver)角色:接收者,真正執行命令的物件。任何類都可能成為一個接收者,只要它能夠實現命令要求實現的相應功能。 - 調用者/請求者(Invoker)角色:要求命令物件執行請求,通常會持有命令物件,可以持有很多的命物物件。這個是客戶端真正觸發命令並要求命令執行對應操作的地方,也就是說相當於使用命令物件的入口。 ### 案例 :::info 將上面的案例用代碼實現,先分配角色 - 服務員:就是調用者角色,由她來發起命令。 - 資深大廚:接手者角色,真正命令執行物件。 - 訂單:命令中包含訂單。 ![](https://i.imgur.com/8csa2HS.png) ::: ```typescript= // 訂單類 class Order { // 餐桌號碼 private _diningTable!: number; // 所下的餐品及份數 private _foodDir: Map<string, number> = new Map<string, number>(); public setFood(name: string, num: number) { this.foodDir.set(name, num); } // get set ... } // 廚師類 class SeniorChef { makeFood(name: string, num: number) { console.log(`${num}份 ${name}`); } } // 抽象命令類 interface Command { execute(): void; } // 具體命令類 class OrderCommand implements Command { // 持有接收者物件 private _receiver: SeniorChef; private _order: Order; constructor(receiver: SeniorChef, order: Order) { this._receiver = receiver; this._order = order; } execute(): void { console.log(`${this._order.diningTable}桌的訂單:`); const foodDir: Map<string, number> = this._order.foodDir; // 遍歷 map 集合 foodDir.forEach((value, key) => { // value 數量,key 菜名 this._receiver.makeFood(key, value); }); console.log(`${this._order.diningTable}桌的飯準備完畢。`); } } // 服務生(屬於請求者角色) class Waiter { // 持有命令物件 private commands: Command[] = new Array<Command>(); setCommand(cmd: Command): void { // 將 cmd 物件存儲到 list 集合中 this.commands.push(cmd); } // 發起命令功能,喊 訂單來了 orderUp(): void { console.log("服務員:大廚,新的訂單來了..."); // 遍歷 this.commands.forEach((item) => { if (item != null) { item.execute(); } }); } } class Client { static main(): void { // 創建第一個訂單物件 const order1 = new Order(); order1.diningTable = 1; order1.setFood("排骨飯", 1); order1.setFood("小杯可樂", 2); // 創建廚師物件 const receiver = new SeniorChef(); // 創建命令物件 const cmd1 = new OrderCommand(receiver, order1); // 創建調用者(服務員物件) const invoke = new Waiter(); invoke.setCommand(cmd1); // 讓服務員發起命令 invoke.orderUp(); } } Client.main(); ``` ### 優缺點、使用場景 - 優點: - 降低系統的耦合度。命令模式能將調用操作的物件與實現該操作的物件解耦。 - 增加或刪除命令非常方便。採用命令模式增加與刪除命令不影響其他類,滿足開閉原則,對擴展比較靈活。 - 可以實現宏命令。命令模式可以與組合模式結合,將多個命令裝配成一個組合命令,即宏命令。 - 方便實現 Undo 和 Redo 操作。命令模式可以與後面介紹的備忘錄模式結合,實現命令的撤銷與恢復。 - 缺點: - 使用命令模式可能導致某些系統有過多的具體命令類。 - 系統結構更加複雜。 - 使用場景 - 系統需要將==請求調用者和接收者解耦==,使得調用者和接收者不直接交互。 - 系統需要在不同的時間指定請求,將請求排隊和執行請求。==排隊效果==(使用 list、forEach) - 系統需要支持命令的撤銷(Undo)操作和恢復(Redo)操作。 ## 責任鏈模式 ### 概述 - 在現實生活中,常常會出現這樣的事例:一個請求有多個對象可以處理,但每個對象的處理條件或權限不同。例如,公司員工請假,可批假的主管有部門負責人、副總經理、總經理等,但是每個主管能批准的天數不同,員工必需根據自己要請假的天數去找不同的主管簽名,也就是說員工必須記住每個主管的姓名、電話和地址等信息,這增加了員工請假的難度。這樣的例子還有很多,如找主管出差報銷、生活中的"擊鼓傳花"遊戲等。 ### 定義 - 又名職責鏈模式,==為了避免請求發送者(想請假的員工)與多個請求處理者(主管)耦合在一起==,將所有請求的處理者通過前一個對象記住其下一個對象的引用而連成一條鏈;當有請求發生時,可將請求沿著這條鏈傳遞,直到有對象處理它為止。(踢皮球?) ### 結構 - 抽象處理者(Handler):定義一個處理請求的接口,包含抽象處理方法和一個後繼連結。 - 具體處理者():實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的後繼者。 - 客戶類(Client):創建處理鏈,並向鏈頭的具體處理者物件提出請求,它不關心處理細節和請求的傳遞過程。(不關心後續) ### 案例 :::info - 現需要開發一個請假流程控制系統。請假一天以下的假只需要小組長同意即可;請假1天到3天的假還需要部門經理同意;請求3天到7天還需要總經理同意才行。 ![](https://i.imgur.com/6SbNyZt.png) :::

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully