原创 [OOD] 適配器模式

背景世界上電源插頭標準很多, 這裏只說國標和英標:中國標準:英國標準:各地插頭標準不同帶來的另一個問題是各地的標準插座主要針對當地插頭設計。 常在世界各地跑的朋友都知道一定要配個轉接頭, 比如這個:這個轉換頭名稱是World Travel

原创 類是如何定義出來的

類是如何定義出來的 Object Oriented是多種軟件設計方法中的一種,其核心目標是爲了降低系統的複雜性,以及代碼複用。 在OO裏,一個類(Class)代表了一組具有共同結構和行爲的一組對象(Objects),是OO語言的基

原创 [OOD-More C++ Idioms] 律師與委託人 (Attorney-Client)

律師與委託人 (Attorney-Client) 目的 控制訪問類實現細節的粒度。 動機 C++中的friend會開始類內部的所有細節,也因此破壞了封裝性。C++沒有提供可以選擇性使用某一部分私有成員的方式,要麼全部開放,要麼全部

原创 大型項目開發: 頭文件順序

經驗告訴我們,某些編碼實踐雖然在C++中完全合法,但是絕對不能應用於大型項目環境中。 大型項目環境下必須有適當的約束,否則很容易變得難以控制並很難維護(摘自<<大規模C++程序設計>>)。下面以Chromium中運用的兩個Coding S

原创 Google C++ Coding Style:引用參數

Google C++ Coding Style定義 輸入參數以值或者const引用形式傳入,輸出參數使用指針。 所有以引用形式輸入參數必須加上const,即const T&的形式。 即如下形式: void Foo(const st

原创 [OOD] 爲什麼單一職責原則(SRP)是最難運用的

單一職責原則(SRP)已經幾乎是每一個程序員都知道的設計原則。最早由Robert C. Martin在<<敏捷軟件開發 — 原則、模式與實踐>>中正式提出。書中作者在結論中提到:  SRP是所有設計原則最簡單的,但也是最難運用的。(中文翻

原创 [OOD]違反里氏替換原則的解決方案

關於OOD中的里氏替換原則,大家耳熟能祥了,不再展開,可以參考設計模式的六大設計原則之里氏替換原則。這裏嘗試討論常常違反的兩種形式和解決方案。 違反里氏替換原則的根源是對子類及父類關係不明確。我們在設計繼承關係常常受一些主觀認識的

原创 文本壓縮算法的對比和選擇

本文主要粗略介紹數據壓縮主要算法類別,以及最新針對Web文本資源的zStd和Brotli算法的設計要點。爲Web業務應用如何使用它們替換傳統gzip提供些參考。最後是一個文本有損壓縮的嘗試。 在數據壓縮領域裏,文本壓縮的歷史最久,

原创 [OOD] 隔離變化-橋接模式

背景正如電腦主機和顯示器之間,主機的配置千變萬化,不斷升級,顯示器可能升級緩慢。如果這時你買的是一體機,硬件升級就要受到限制。這就是一個典型的分離變化的需求場景。在應用中,一個業務會有多個協作者,直接耦合會導致其中一個類的變化就會影響其它

原创 API的設計與實現

關於API的設計與實現 API的設計是軟件開發中一個獨特的領域。最主要的特殊點在於API是供開發者使用的界面,即Application Programmer Interfaces。類似於用戶可以直接使用到的GUI的作用一樣。所以相

原创 如何避免類的膨脹

類的膨脹(Bloating)指的是類中成員過多,甚至出現無序增加的情況。過大的類,會使得複雜度急劇增加,維護會變得更爲困難。所以需要控制類的增長。本文總結了一下,簡單介紹四種解決的方式,我故意用四個來講,主要爲了介紹最後一種方式。

原创 大型項目開發: 隔離 (《大規模C++程序設計》書摘)

書中第六章 隔離。 主要在撰述什麼需要定義在頭文件?什麼應當移到編譯單元中? 核心仍然是先區分接口定義與實現細節。實現細節的改變會導致客戶代碼的重新編譯,從邏輯上也表示與客戶代碼間可能存在着強耦合。 實現細節與隔離 主要考察以下

原创 大型項目開發:謹慎使用智能指針

智能指針使用上的問題 智能指針的使用太普遍了,它讓程序員擺脫了內存管理的惡夢,但實際上智能指針本身也可能引入另一個惡夢。主要包括兩個問題點: 性能問題。因爲需要引入一些變量(bookkeeping),甚至在多線程下的一些互斥操作

原创 軟件設計的複雜度

什麼是軟件設計的複雜度 軟件技術發展的使命之一就是控制複雜度(Complexity)。從高級語言的產生,到結構化編程,再到面向對象編程、組件化編程等等。關於複雜度的定義並不一致,想要詳細瞭解的可以讀讀The Many Faces

原创 Google C++ Coding Style:右值引用(Rvalue Reference)

右值引用是一個C++11特性,標記爲T&&。GSG中定義:只爲移動建構函數(Move constructor)和移動賦值操作(Move assignment)使用右值引用。並且不要使用std::Forward(提供的完美轉發特性)