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/27 ## 依賴倒轉原則 - 開閉原則的具體實現 - 高層模塊不應該依賴低層模塊,兩者都應該==依賴其抽象==;抽象不應該依賴細節,細節應該依賴抽象。 - 簡單來說就是要求對抽象進行編程,不要對實現進行編程,這樣就降低了客戶與實現模塊的耦合。 :::info - 例子:組裝電腦,需要 cpu 硬碟 記憶體。只有在這些配件都存在的時候,電腦才能正常運作。 - 配件有多種選擇,cpu 有 intel、amd,硬碟有 WD、Seagate、Toshiba,記憶體有金士頓、海盜船等。 ::: ![](https://i.imgur.com/qRJhlye.png) :::danger 問題:computer 類中包含 intelCpu KingstonMemory 等品牌屬性, 想要客製化就必須反覆修改,也違背了開閉原則。 ::: :::success 根據依賴倒轉原則進行改進,修改 Computer 類,讓其依賴抽象(個配件的介面), 而不是依賴於各個組件的具體實現類 ::: ![](https://i.imgur.com/IGI90tK.png) ## 介面隔離原則 - 客戶端不應該被迫依賴於它不使用的方法;一個類對另一個類的依賴應該建立在最小的接口上。 :::info - 安全門案例:我們需要創建一個 apple 品牌的安全門,該安全門具有防火 防水 防盜的功能。 - 可以將 防火 防水 防盜 的功能提取到一個接口,形成一套規範,類圖如下 ::: ![](https://i.imgur.com/HLmu9bS.png) :::danger 問題:apple 品牌的安全門具有 防火 防水 防盜的功能, 現在如果我們還需要創建一個 google 品牌的安全門,而該安全門只具有 防盜 防水功能呢? 很顯然如果實現 SafetyDoor 介面,就被迫依賴於防火方法(不使用),違背了接口隔離原則 ::: ![](https://i.imgur.com/ECd4xip.png) ```java= // 實現可以多個 ? public class AppleSafetyDoor implements AntiTheft,FireProof,WaterProof { @Override public void antiTheft() { System.out.println("防盜"); } @Override public void fireProof() { System.out.println("防火"); } @Override public void waterProof() { System.out.println("防水"); } } ``` ## 迪米特法則 - 又稱作最少知識原則:只和你的直接朋友交談,不跟==陌生人==說話。 - 其含義是:如果兩個軟體無需直接通信,那麼就不應該發生直接相互調用,可以通過第三方轉發該調用。(MVC ?) - 其目的是降低類之間的耦合度,提高模塊的相互獨立性。 - 朋友是指:當前物件本身、當前物件的成員物件、當前物件所創建的物件、當前物件的方法參數等,這些物件同當前物件存在關聯、聚合或組合關係,可以直接訪問這些物件的方法。 :::info 例子:明星與經紀人的關係 明星由於全身心投入藝術,所以許多日常事務由經紀人負責處理,如粉絲見面會,媒體公司業務洽談等。這裡的經紀人是明星的朋友,而粉絲和媒體公司是陌生人,所以適合迪米特法則 ::: ![](https://i.imgur.com/W0Ad2dT.png) - 目的是降低明星和 粉絲與經紀公司的耦合度 ## 合成復用原則 - 指的是:盡量先使用組合或者聚合等關係來實現,其次才考慮繼承關係來實現。 - 通常類的復用分為 繼承復用 合成復用 兩種。 #### 繼承復用 - 優點:簡單、容易實現 - 缺點: 1. 繼承復用破壞了類的封裝性。因為繼承會將父類的實現細節暴露給子類,父類對子類是透明的,所以這種復用又稱為==白箱復用==。 2. 子類與父類的耦合度高。父類的實現==任何改變==都會導致子類的實現發生變化,這不利於類的擴展與維護。 3. 它限制了復用的靈活性。從父類繼承而來的實現是靜態的,在編譯時已經定義,所以在運行是不可能發生變化。 #### 組合或聚合復用 - 可以將已有物件納入新物件中,使之成為新物件的一部分,新物件可以調用已有物件的功能。 - 優點: 1. 他維持了類的封裝性,因為成分物件的內部細節新物件是看不到的,又稱==黑箱復用==。 2. 物件間的耦合度低,可以在類的成員位置聲明抽象。 3. 復用靈活性高。這種復用可以在運行時動態進行,新物件可以動態的引用與成分物件類型相同的物件。 :::info 汽車按照動力源可以分為 汽油汽車、電動汽車,按顏色可以分為白色汽車、黑色汽車等。 如果同時考慮這兩種分類,其組合就很多,類圖如下 ::: ![](https://i.imgur.com/mxop55y.png) - 從上面類圖我們可以看出使用繼承復用產生很多子類,如果現在又有新的動力源或者顏色的話,就需要再定義新的類。 - 我們嘗試著改為聚合復用看一下。 ![](https://i.imgur.com/w9kQJzL.png) ## 創建者模式 :::warning 創建型模式的住要關注點是"如何創建物件",它的主要特點是”將物件的創建與使用分離“。 這樣可以降低系統的耦合度,使用者不需要關注物件的創建細節。 可以分為:單例模式、工廠方法模式、抽象工程模式、原型模式、建造者模式。 ::: ## 單例模式 - java 最簡單的設計模式之一,提供了一種創建物件的最佳方式。 - 這種模式涉及到一個單一的類,該類負責創建自己的物件,同時確保只有==單個物件==被創建。 - 這個類提供了一種==訪問其唯一的物件的方式==,可以直接訪問,不需要實例化該類的物件 - 結構 - 主要有以下角色:單例類,只能創建一個實例的類。訪問類,使用單例類。 - 實現: - 餓漢式:類加載就會導致該單例物件被創建。 - 懶漢式:加載時不會創建,而是首次使用才會被創建。 :::info - 懶漢式會有多線程的問題 :使用 synchronized 可以保護線程安全 ::: ```java= // 對外提供獲取該類物件的方法 public static synchronized Singleton getInstance() { // 判斷 instance 是否為 nll ,說明還沒有創建 Singleton 類的物件 // 如果沒有,創建一個並返回,如果有,直接返回。 if (instance == null) { // 線程1等待,線程2獲取到cpu的執行權,也會進去到該判斷裡面。 // 使用 synchronized 可以保護線程安全 instance = new Singleton(); } return instance; } ``` - 由於 getInstance() 只有第一次會進行創建寫入,之後都只有讀(return instance;) - 每次都鎖線程會造成性能問題 - 使用雙重檢查鎖 ```java= // 對外提供獲取該類物件的方法 public static Singleton getInstance() { // 第一次判斷 if (instance == null) { synchronized (Singleton.class) { // 第二次判斷 if (instance == null) { instance = new Singleton(); } } } return instance; } ``` - 雙重檢查模式是一種非常好的單例實現模式,解決了單例、性能、線程安全問題,上面的雙重檢測看上去完美無缺,但還是存在問題,在多線程的情況下,可能會出現空指針問題,出現原因是 JVM 在實例化物件的時候會進行優化和指令重排序操作。 - 要解決雙重檢查鎖帶來空指針異常問題,只需要使用 volatile 關鍵字,volatile 可以保證其可見性和有序性。 - 方法4(靜態內部類) ```java= // 懶漢式: 靜態內部類 public class Singleton { // 私有構造方法 private Singleton() { } // 定義一個靜態內部類 private static class SingletonHolder { // 在內部類中聲明並初始化外部類的物件 private static final Singleton INSTANCE = new Singleton(); } // 對外提供獲取該類物件的方法 public static Singleton getInstance() { return SingletonHolder.INSTANCE; } } ``` - 第一次加載 Singleton 類時不會去初始化 INSTANCE,只有第一次調用 getInstance,虛擬機加載 SingletonHolder 並初始化 INSTANCE,這樣不僅能確保線程安全,也能保證 Singleton 類的唯一性。 - ==優秀的單例模式,開源項目常見。== - ==枚舉方式:極力推薦使用==實現單例模式,因為枚舉類型是線程安全的,並且只會裝載一次,設計者充分利用了枚舉這個特性來實現單例模式,寫法簡單,而且是所用單例實現中唯一不會被破壞的單例實現模式。 - 破壞 反射破解單例模式(29~33 聽不懂跳過) - java 中 ==Runtime (執行環境)== 是單例模式(惡漢式)

    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