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` --- # 10/29 ## 原型模式 : 淺拷貝、深拷貝 - 概述:用一個已經創建的實例作為原型,通過複製該物件來創建一個和原型物件相同的新物件。 - 原型模式包含以下角色 - 抽象原型類:規定了具體原型物件必須實現的 clone() 方法。 - 具體原型類:實現抽象原型類 clone() 方法,它是可被複製的物件。 - 訪問類:使用具體原型類中的 clone() 方法來複製新的物件。 - 看起來像 JS 的 {...物件} ? - 接口類圖如下: ![](https://i.imgur.com/FnCZdHG.png) - 淺複製:創建一個新物件,新物件的屬性和原來物件完全相同,對於非基本類型屬性,扔指向原有屬性所指向的物件記憶體地址, - 深複製:創建一個新物件,屬性中引用的其他物件也會被複製,不再指向原有物件的地址。 ```typescript= class Glass { color: string; length: number; constructor(color: string, length: number) { this.color = color; this.length = length; } } class Sheep { age: number; hair: string; glass: Glass; constructor(age: number = 0, hair: string = "", glass: Glass) { this.age = age; this.hair = hair; this.glass = glass; } canCopy(): void { console.log("可以複製"); } canNotCopy(): void { console.log("不能複製"); } shallowCopy(): Sheep { return new Sheep(this.age, this.hair, this.glass); } deepClone(): Sheep { const serializeStr = JSON.stringify(this); const cloneObj = JSON.parse(serializeStr) as Sheep; cloneObj.canCopy = this.canCopy; return cloneObj; } } ``` ```typescript= class test { static mainShallow(): void { const glass = new Glass("灰", 20); const sheep = new Sheep(3, "", glass); console.log(`原型: ${JSON.stringify(sheep)}`); // 原型: {"age":3,"hair":"","glass":{"color":"灰","length":20}} const sheep_1 = sheep.shallowCopy(); const sheep_2 = sheep.shallowCopy(); const sheep_3 = sheep.shallowCopy(); console.log(`sheep_1 : ${JSON.stringify(sheep)}\n`); // sheep_1 : {"age":3,"hair":"","glass":{"color":"灰","length":20}} sheep.age = 5; sheep.glass.color = "白"; console.log(`原型:${JSON.stringify(sheep)}`); // 原型:{"age":5,"hair":"","glass":{"color":"白","length":20}} console.log(`sheep_1:${JSON.stringify(sheep_1)}`); // sheep_1:{"age":3,"hair":"","glass":{"color":"白","length":20}} console.log(`sheep_2:${JSON.stringify(sheep_2)}`); // sheep_2:{"age":3,"hair":"","glass":{"color":"白","length":20}} const sheep2_2 = sheep_2; console.log(`sheep == sheep3 : ${sheep == sheep_3}`); // sheep == sheep3 : false console.log(`sheep2_2 == sheep_2: ${sheep2_2 == sheep_2}`); // sheep2_2 == sheep_2: true } static mainDeep(): void { const glass = new Glass("灰色", 20); const sheep = new Sheep(3, undefined, glass); console.log(`原型: : ${JSON.stringify(sheep)}`); const sheep_1 = sheep.deepClone(); const sheep_2 = sheep.deepClone(); const sheep_3 = sheep.deepClone(); console.log(`sheep_1 : ${JSON.stringify(sheep_1)}\n`); sheep.age = 5; sheep.glass.color = "白色"; console.log(`原型:: ${JSON.stringify(sheep)}`); // 原型:: {"age":5,"hair":"","glass":{"color":"白色","length":20}} console.log(`sheep_2: ${JSON.stringify(sheep_2)}\n`); // sheep_2: {"age":3,"hair":"","glass":{"color":"灰色","length":20}} sheep_2.canCopy(); // 可以複製 console.log(`${sheep_2.canNotCopy}\n`); // undefined const sheep2_2 = sheep_2; console.log(`sheep == sheep_3: ${sheep == sheep_3}`); console.log(`sheep2_2 == sheep_2: ${sheep2_2 == sheep_2}`); } } test.mainDeep(); ``` ## 建造者模式 : ### 概述 - 將一個複雜物件的構造與表示分離,使同樣的構造過程可以創建不同的表示。 ![](https://i.imgur.com/Fi2wWHs.png) - 分離了部件的構造(由 builder 來負責)和裝飾(由 Director 負責)。從而可以構造出複雜的物件。==這個模式適用於:某個物件的構建過程複雜的情況。== - 由於實現了構建和裝配的解耦。不同的構建器,相同的裝配,也可以做不同的物件;相同的構建器,不同的裝配順序也可以做出不同的物件。 - 也就實現了構建算法、裝配算法的解耦、實現了更好的復用。 - 建造者模式可以將部件和其組裝過程分開,一步步建造一個複雜物件。 - ==用戶只需要指定複雜物件的類型==,就可以得到該物件,而無需知道其內部的具體構造細節。 - 例:用戶買一台電腦,無需關心內部零件與組裝過程 ### 結構 - 抽象建造者類:這個接口規定要實現複雜物件的哪些部分的創建,並不涉及具體的部件的創建。 - 具體創建者類:實現 抽象建造者類 接口,完成複雜產品的各個部件的具體創建方法。在構造過程完成後,提供產品實例。 - 產品類:要創建複雜的物件。 - 指揮者類:調用具體的建造者來創建複雜物件的各個部分,在指揮者中不涉及產品信息,只負責保證物件個部分完整創建或按某種順序創建 ![](https://i.imgur.com/3Wptpu1.png) :::info - 例子:生產自行車 - 生產自行車是一個複雜的過程,它包含了車架、車座等組建的生產。而車架又有碳纖維、鋁合金等材料,車座有橡膠真皮等材質。對於自行車的生產就可以使用建造者模式。 - 這裡 bike 是產品,包含車架、車座等組件;builder 是抽象建造者,MobikeBuilder 和 OfoBuilder 是具體的建造者;Director 是指揮者 ![](https://i.imgur.com/uubnJ8D.png) ::: - 優點: - 建造者模式的封裝性很好 - 客戶端不必要知道產品內部組成的細節,將產品本身與產品創建過程解耦。 - 可以更加精細的控制產品的創建過程。將複雜的產品創建步驟分解在不同的方法中。 - 建造者模式很容易進行擴展。如果有新的需求,通過實現一個新的建造者類就可以完成。 - 缺點: - 造者模式所創建的產品一班具有較多的共同點,其組成部分相似,==如果產品之間的差異性很大,則不適合建造者模式==,因此其使用範圍受到一定的限制。 :::success - 使用場景 - 創建的物件較複雜,由多個組件構成,各組件面臨著複雜的變化,但組建之間的建造順序是穩定的。 - 創建複雜物件的算法獨立於該物件的組成,以及他們的裝配方式,及產品的構建過程和最終的表示是獨立的 ::: - 擴產:使用情境 ```typescript= class Phone { constructor( private _cpu: string, private _screen: string, private _memory: string, private _motherboard: string ) {} } class Client2 { static main(): void { const phone: Phone = new Phone("intel", "三星螢幕", "金士頓", "華碩"); console.log(phone); } } ``` - 傳遞參數過多,可讀性以及使用成本很高。 - p53 跳過 ts 無法在 class 內增加 class ## 建造者模式對比 : ### 工廠方法 vs 建造者模式 - 工廠方法模式注重的事==整體物件==的創建方式;而建造者模式住的是==部件構建==的過程,意在通過一步步地精確構造創建初一個複雜物件。 - 舉個例子:如果要製造一個超人,如果使用工廠方法,直接產生出來的就是一力大無窮、會飛、內褲外穿的超人 - 而如果使建建者模式,則需要組裝手、頭、腳、軀幹等部分,然後再把內褲外穿,於是一個超人就誕生了。 ### 抽象工廠模式 vs 建造者模式 - 抽象工廠模式實現對產品家族的創建,一個產品家族是這樣的一系列產品: 具有不同分類維度的產品組合,採用抽像工廠模式則是不需要關心構建過程,只需要關心產品由什麼工廠生產即可。 - 建造者模式則是要求按照指定的藍圖建構產品,它的主要目的是通過組裝零配件而產生一個新產品。 - 如果將抽象工廠模式看成汽車配件生產工廠,生產一個產品族的產品,那麼建造者模式就是一個汽車組裝工廠,通過對部件的組裝可以返回一輛完整的汽車。

    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