DesignPattern-part3

来源:https://www.cnblogs.com/sunstrikes/archive/2023/03/24/17253112.html
-Advertisement-
Play Games

title: "modern C++ DesignPattern-Part3" date: 2018-04-12T19:08:49+08:00 lastmod: 2018-04-12T19:08:49+08:00 keywords: [設計模式, C++] tags: [設計模式] categori ...


title: "modern C++ DesignPattern-Part3"
date: 2018-04-12T19:08:49+08:00
lastmod: 2018-04-12T19:08:49+08:00
keywords: [設計模式, C++]
tags: [設計模式]
categories: []

結構式設計模式的最後兩個,享元模式:實現對象共用,減少記憶體開銷;代理模式,提供相同介面的代理

flyweight

享元模式的主要目的是實現對象的共用,即共用池,當系統中對象多的時候可以減少記憶體的開銷,通常與工廠模式一起使用。boost::flyweight使用:

struct User2
{
  flyweight<string> first_name, last_name;  //類似一個緩存

  User2(const string &first_name, const string &last_name)
    : first_name(first_name),
      last_name(last_name) {}
};

void boost_flyweight()
{
  User2 user1{"John", "Smith"};
  User2 user2{"Jane", "Smith"};
  cout << user1.first_name << endl;
  cout << boolalpha  //std::boolalpha可以把bool變成true/false字元串
       << (&user1.first_name.get() == &user2.first_name.get()) << endl;
  cout << boolalpha
       << (&user1.last_name.get() == &user2.last_name.get()) << endl;
}

示例:

class FormattedText {  //用來記錄是否被覆用的單元
    string plain_text;
    bool *caps;
public:
    explicit FormattedText(const string &plainText)
            : plain_text{plainText} {
        caps = new bool[plainText.length()];
        memset(caps, 0, plain_text.length());
    }

    ~FormattedText() {
        delete[] caps;
    }

    void capitalize(int start, int end) {
        for (int i = start; i <= end; ++i)
            caps[i] = true;
    }

    friend std::ostream &operator<<(std::ostream &os, const FormattedText &obj) {
        string s;
        for (int i = 0; i < obj.plain_text.length(); ++i) {
            char c = obj.plain_text[i];
            s += (obj.caps[i] ? toupper(c) : c);
        }
        return os << s;
    }
};

class BetterFormattedText {
public:
    struct TextRange {
        int start, end;
        bool capitalize, bold, italic;

        bool covers(int position) const {
            return position >= start && position <= end;
        }
    };

    TextRange &get_range(int start, int end) { //每當設置一個被覆用的單元,push到vector裡面,返回最後一個
        formatting.emplace_back(TextRange{start, end});
        return *formatting.rbegin();
    }

    explicit BetterFormattedText(const string &plainText)
            : plain_text{plainText} {
    }

    friend std::ostream &operator<<(std::ostream &os, const BetterFormattedText &obj) {
        string s;
        for (size_t i = 0; i < obj.plain_text.length(); i++) {
            auto c = obj.plain_text[i];
            for (const auto &rng : obj.formatting) {
                if (rng.covers(i) && rng.capitalize)
                    c = toupper(c);
            }
            s += c; // fixed!
        }
        return os << s;
    }

private:
    string plain_text;
    vector<TextRange> formatting;
};

Proxy

代理模式最經典的是shared_ptr實現,增加了引用計數的同時保持了原有的普通指針介面

Property Proxy

template <typename T> struct Property {
  T value;
  Property(const T initialValue) {
    *this = initialValue;
  }
  operator T() {  //getter
    return value;
  }
  T operator =(T newValue) {  //setter
    return value = newValue;
  }
};
//usage
struct Creature
{
  Property<int> strength{ 10 };
  Property<int> agility{ 5 };
};
void property_proxy() {
  Creature creature;
  creature.agility = 20;
  cout << creature.agility << endl;
}

主要目的是可以允許 Property<int>與int的隨時轉換。

Virtual Proxy

這種非常常見,使用時分兩種,eager模式和lazy模式,區別就是lazy模式是在使用的時候才會初始化

struct Image{
  virtual ~Image() = default;
  virtual void draw() = 0;
};
struct Bitmap : Image{
  Bitmap(const string& filename) {
    cout << "Loading image from " << filename << endl;
  }
  void draw() override {
    cout << "Drawing image" << endl;
  }
};
struct LazyBitmap : Image {
  LazyBitmap(const string& filename): filename(filename) {}
  ~LazyBitmap() { delete bmp; }
  void draw() override {
    if (!bmp)
      bmp = new Bitmap(filename);
    bmp->draw();
  }
private:
  Bitmap* bmp{nullptr};
  string filename;
};

void draw_image(Image& img) {
  img.draw();
}
void virtual_proxy() {
  LazyBitmap img{ "pokemon.png" };
  draw_image(img); // loaded whether the bitmap is loaded or not
  draw_image(img);
}

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

-Advertisement-
Play Games
更多相關文章
  • eval,一個我曾經避之不及的函數,最近我對它產生了一點新的感觸:eval有時候也可以用,有奇效。 一般在使用js進行開發時,是不建議使用eval這類函數的。在JavaScript中,eval可以計算傳入的字元串,將其當作js代碼來執行。因為它可執行js代碼的特性,有可能被第三方利用,傳入惡意js代 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 建模 首先我們需要一些貼圖素材 貼圖素材一般可以在3dtextures網站上找到,這裡我找了2份,包含了牆的法線貼圖和潮濕地面的法線、透明度、粗糙度貼圖 通過kokomi.AssetManager將貼圖素材一次性全部載入出來,將它們應用到 ...
  • NPM(Node Package Manager)是 Node.js 的包管理工具,用來安裝各種 Node.js 的擴展。 NPM是 JavaScript 的包管理工具,也是世界上最大的軟體註冊表。有超過 60 萬個 JavaScript 代碼包可供下載,每周下載約 30 億次。NPM讓 JavaS ...
  • 響應式基本原理就是,在初始化vue實例的時候,對data的每一個屬性都通過 Object.defineProperty 定義一次,在數據被set的時候,做一些操作,改變相應的視圖 ...
  • JavaScript(簡稱“JS”)是當前最流行、應用最廣泛的客戶端腳本語言,用來在網頁中添加一些動態效果與交互功能,在 Web 開發領域有著舉足輕重的地位。JavaScript 與 HTML 和 CSS 共同構成了我們所看到的網頁,其中: HTML 用來定義網頁的內容,例如標題、正文、圖像等; C ...
  • Vue是一款國產前端框架,它的作者尤雨溪(Evan You)是一位美籍華人,2014年2月,尤雨溪開源了一個前端開發庫 Vue.js,2015年發佈1.0.0版本,2016年4月發佈2.0版本,目前,尤雨溪全職投入 Vue.js 的開發與維護,立志將 Vue.js 打造成與 Angular/Reac ...
  • 外觀模式(Facade Pattern):它提供了一個簡單的介面,用於訪問複雜的系統或子系統。通過外觀模式,客戶端可以通過一個簡單的介面來訪問複雜的系統,而無需瞭解系統內部的具體實現細節。 在前端開發中,外觀模式常常被用於封裝一些常用的操作,以簡化代碼複雜度和提高代碼可維護性。比如,一個用於處理數據 ...
  • 最近,在看 LPL 比賽的時候,看到這樣一個有意思的六芒星能力圖動畫: 今天,我們就來使用純 CSS 實現這樣一個動畫效果! 實現背景網格 對於如下這樣一個背景網格,最好的方式當然肯定是切圖,或者使用 SVG 路徑。 如果一定要使用 CSS,勉強也能做,這就涉及了不規則圖形邊框效果,我們有一些方式可 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...