創建型設計模式(上)

来源:https://www.cnblogs.com/lemonyam/archive/2019/10/02/11617344.html
-Advertisement-
Play Games

單例模式: 1、定義:單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例,這個類稱為單例類 2、實現過程要點: (1)單例類的構造函數為私有 (2)提供一個自身的靜態私有成員變數 (3)提供一個公有的靜態工廠方法 3、優點: (1)提供了對唯一實例的受控訪問 (2)由於在系統內 ...


單例模式:

  1、定義:單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例,這個類稱為單例類

  2、實現過程要點:

    (1)單例類的構造函數為私有

    (2)提供一個自身的靜態私有成員變數

    (3)提供一個公有的靜態工廠方法

註:單例模式由類提供實例對象,所以需要使用 static 來定義方法和屬性,使我們可通過類名來調用函數獲取對象,

  靜態域載入是在解析階段,而實例化是在初始化階段,所以靜態方法不能調用普通函數和屬性

  3、優點:

    (1)提供了對唯一實例的受控訪問

    (2)由於在系統記憶體中只存在一個對象,因此可以節約系統資源

    (3)允許可變數目的實例。我們可以基於單例模式進行擴展,使用與單例控制相似的方法來獲得指定個數的對象實例

  4、缺點:

    (1)單例模式中沒有抽象層,因此單例類的擴展有很大的困難

    (2)單例類的職責過重,在一定程度上違背了“單一職責原則”

    (3)濫用單例將帶來一些負面問題;如採用垃圾自動回收機制的語言,實例化的對象若長期未被使用,

      則會被清除掉,下次要再使用該類則需重新實例化,而導致原來的狀態沒有了

  5、適用環境:

    (1)系統只需要一個實例對象

    (2)客戶調用類的單個實例只允許使用一個公共訪問點,除了該公共訪問點,不能通過其他途徑訪問該實例

class Singleton1 {
  private static instance: Singleton1 = new Singleton1();  // 靜態私有成員變數
  private constructor() {}  // 私有構造函數,防止外部調用它生成其他實例
  // 公有靜態工廠方法
  static getInstance(): Singleton1 {
    return Singleton1.instance;
  }
}

const singleton_one: Singleton1 = Singleton1.getInstance();
const singleton_two: Singleton1 = Singleton1.getInstance();
console.log(singleton_one === singleton_two); // true

 

構建者模式:

  1、定義:將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示

  2、模式結構:

    (1)抽象建造者(Builder):包含創建產品各個子部件的抽象方法的介面,通常包含返回覆雜產品的方法

    (2)具體建造者(ConcreteBuilder):實現 Builder 介面,完成複雜產品的各個部件的具體創建方法

    (3)指揮者(Director):調用建造者對象中的部件構造與裝配方法完成複雜對象的創建

    (4)產品角色(Product):包含多個組成部件的複雜對象,由具體建造者來創建其各個部件

  3、優點:

    (1)客戶端不必知道產品內部組成細節,將產品本身與產品的創建過程解耦

    (2)每一個具體建造者都相對獨立,與其他具體建造者無關,用戶使用不同的具體建造者即可得到不同的產品對象

    (3)可以更加精細地控制產品的創建過程

    (4)增加新的具體建造者無須修改原有類的代碼,指揮者類對抽象建造者類編程,系統擴展方便,符合“開閉原則”

  4、缺點:

    (1)建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,

       如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制

    (2)如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大

  5、適用場景:

    (1)需要生成的產品對象有複雜的內部結構,這些產品對象通常包含多個成員屬性

    (2)需要生成的產品對象的屬性相互依賴,需要指定其生成順序

    (3)對象的創建過程獨立於創建該對象的類

    (4)隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同的產品

// 產品角色
class Computer {
    private cpu: string;
    private mainBoard: string;
    private memory: string;
    private hardDisk: string;

    setCpu(cpu: string): void {
        this.cpu = cpu;
    }
    setMainBoard(mainBoard: string): void {
        this.mainBoard = mainBoard;
    }
    setMemory(memory: string): void {
        this.memory = memory;
    }
    setHardDisk(hardDisk: string):void {
        this.hardDisk = hardDisk;
    }

    getCpu(): string {
        return this.cpu;
    }
    getMainBoard(): string {
        return this.mainBoard;
    }
    getMemory(): string {
        return this.memory;
    }
    getHardDisk(): string {
        return this.hardDisk;
    }
}

// 抽象建造者
interface Builder {
    createCpu(cpu: string): void;
    createMainBoard(mainBoard: string): void;
    createMemory(memory: string): void;
    createHardDisk(hardDisk: string): void;

    createComputer(): Computer;
}

// 具體建造者
class ConcreteBuilder implements Builder {
    private computer: Computer = new Computer();

    createCpu(cpu: string): void {
        this.computer.setCpu(cpu);
    }
    createMainBoard(mainBoard: string): void {
        this.computer.setMainBoard(mainBoard);
    }
    createMemory(memory: string): void {
        this.computer.setMemory(memory);
    }
    createHardDisk(hardDisk: string): void {
        this.computer.setHardDisk(hardDisk);
    }

    createComputer(): Computer {
        return this.computer;
    }
}

// 指揮者
class Director {
    private builder: Builder;
    constructor(builder: Builder) {
        this.builder = builder;
    }
    createComputer(cpu: string, mainBoard: string, memory: string, hardDisk: string): Computer {
        this.builder.createCpu(cpu);
        this.builder.createMainBoard(mainBoard);
        this.builder.createMemory(memory);
        this.builder.createHardDisk(hardDisk);

        return this.builder.createComputer();
    }
}

let builder: Builder = new ConcreteBuilder();
let director: Director = new Director(builder);
let computer: Computer = director.createComputer("i7", "Lenovo", "8G", "1T");
console.log(computer.getCpu()); // i7
console.log(computer.getMainBoard());   // Lenovo
console.log(computer.getMemory());  // 8G
console.log(computer.getHardDisk());    // 1T

 

原型模式:

  1、定義:用原型實例指定創建對象的種類,並且通過復用這些原型創建新的對象

  2、要點:

    (1)通過克隆來創建新的對象實例

    (2)為克隆出來的新的對象實例複製原型實例屬性的值

  3、優點:

    (1)可以在運行時動態根據原型生成新的種類的對象

    (2)對客戶端隱藏具體的實現類型

  4、缺點:

    每個原型的子類都必須實現 clone 的操作,尤其是包含引用類型的對象時,克隆會比較麻煩

  5、適用場景:

    (1)對象之間相同或相似,即只是個別的幾個屬性不同的時候

    (2)如對象的創建過程比較麻煩,但複製比較簡單的時候

// Prototype
interface Clonable<T> {
    clone(): T;
}
// ConcretePrototype
class Origin implements Clonable<Origin> {
    name: string;

    clone(): Origin {
        let target: Origin = new Origin();
        target.name = this.name;
        return target;
    }
}

let orign: Origin = new Origin();
orign.name = "Lemon";
let cloneObj: Origin = orign.clone();
console.log(cloneObj.name); // Lemon

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 字元串值,數值,布爾值,數組,對象。 JavaScript 數據類型 JavaScript 變數能夠保存多種數據類型:數值、字元串值、數組、對象等等: var length = 7; // 數字 var lastName = "Gates"; // 字元串 var cars = ["Porsche" ...
  • 要向HTML DOM添加新元素,必須首先創建元素(元素節點),然後將其附加到現有元素。 appendChild()上一個示例中的方法將新元素作為父項的最後一個子項附加。如果您不希望可以使用insertBefore()方法: 要將元素替換為HTML DOM,請使用以下replaceChild()方法: ...
  • 背景 事情是這樣的。一天下午4點42分左右。業務反饋我開發的服務在測試環境出現問題,返回資源數據是0。查日誌發現是ES訪問超時。相當於資料庫掛了。持續了20多分鐘自己恢復。咨詢了ES團隊,最終得到下麵的答覆: 調查 1.需要換成本地磁碟,測試環境也是我們的正式環境。是否能直接替換成物理機?多少台合適 ...
  • 聲明:本文是一個系列原創(作者在GIS+BIM行業已有從業15年有餘,還是個行業的小學生,文章內容不免有錯誤或者不當之處,敬請理解),旨在通過這個系列打造一個高性能,高可擴展的GIS+BIM框架,拋磚引玉,為國內GIS+BIM行業貢獻綿薄之力。 對於行業內的人說到GIS、BIM最先想到是:引擎,是的 ...
  • 觀察者模式(Observer): 指多個對象間存在一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。 觀察者模式的角色: 1)抽象目標(Subject):也叫抽象目標類,它提供了一個用於保存觀察者對象的聚集類和增加、刪除觀察者對象的方法,以及通知所有觀察者的抽象 ...
  • 責任鏈模式: 下圖為責任鏈 1、定義:為了避免請求發送者與多個請求處理者耦合在一起,將所有請求的處理者通過前一對象 記住其下一個對象的引用而連成一條鏈;當有請求發生時,可將請求沿著這條鏈傳遞,直到有對象處理它為止 2、模型結構: (1)抽象處理者(Handler):定義一個處理請求的介面,包含抽象處 ...
  • kafka的術語(Terminology) Topic 和Consumer Group Topic 每條發佈到 Kafka 集群的消息都有一個類別,這個類別被稱為 Topic。(物理上不同 Topic 的消息分開存儲,邏輯上一個 Topic 的消息雖然保存於一個或多個 broker 上但用戶只需指定 ...
  • 適配器模式: 類適配器: 對象適配器: 1、定義:將一個介面轉換成客戶希望的另一個介面,適配器模式使介面不相容的那些類可以一起工作 2、模型結構: (1)目標抽象類(Target):客戶所期待得到的介面 (2)適配器類(Adapter):通過包裝一個需要適配的對象,把原介面轉換成目標介面 (3)適配 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...