# Blog 3|設計模式 - 創建型模式 - Reference : - https://shengyu7697.github.io/archives/ - https://www.jyt0532.com/ - https://refactoringguru.cn/design-patterns/catalog ## (0)簡單工廠模式 Simple Factory - `將建立邏輯集中在一個工廠中` - `不符合開放封閉原則` - 不被視為一個正式的設計模式,更像是一個寫程式技巧 - 常被宣告成 static 如此就不需要事先準備實體化的工廠,但是也造成無法繼承並修改 create 方法 ```c++= class Phone { public: virtual ~Phone() = default; }; class Samsung : public Phone {}; class Pixel : public Phone {}; class Iphone : public Phone {}; class phoneFactory { public: static std::unique_ptr<Phone> createPhone(const std::string& phoneType) { if (phoneType == "Iphone") { return std::make_unique<Iphone>(); } else if (phoneType == "Samsung") { return std::make_unique<Samsung>(); } else if (phoneType == "Pixel") { return std::make_unique<Pixel>(); } else { return nullptr; } } }; ``` ## (1)工廠方法模式 Factory Method - `將物件的建立過程,延遲到子類別進行` - 符合`「開放封閉原則」` -  ```c++= class PhoneFactory { virtual std::unique_ptr<Phone> createPhone() = 0; }; // ConcreteCreator 1 class IphoneFactory : public PhoneFactory { std::unique_ptr<Iphone> createPhone() override { return std::make_unique<Iphone>(); } }; // ConcreteCreator 2 class SamsungFactory : public PhoneFactory { std::unique_ptr<Samsung> createPhone() override { return std::make_unique<Samsung>(); } }; ``` ## (2)抽象工廠模式 Abstract Factory - 特別適合 `GUI元件` 在跨平台上的應用 - 工廠方法模式的延伸 - 工廠方法模式:每個工廠建立`一個產品` - 抽象工廠模式:每個工廠建立`一系列產品` -  - 參考資料:[Ref1](https://shengyu7697.github.io/cpp-abstract-factory-pattern/) / [Ref2](https://refactoringguru.cn/design-patterns/abstract-factory) ```c++= class GUIFactory { public: virtual std::unique_ptr<Button> createButton() = 0; virtual std::unique_ptr<TextBox> createTextBox() = 0; virtual ~GUIFactory() = default; }; // Concrete Factory 1 class WindowsGUIFactory : public GUIFactory { public: std::unique_ptr<Button> createButton() override { return std::make_unique<WindowsButton>(); } std::unique_ptr<TextBox> createTextBox() override { return std::make_unique<WindowsTextBox>(); } }; // Concrete Factory 2 class MacGUIFactory : public GUIFactory { public: std::unique_ptr<Button> createButton() override { return std::make_unique<MacButton>(); } std::unique_ptr<TextBox> createTextBox() override { return std::make_unique<MacTextBox>(); } }; ``` ## (3)建造者模式 Builder - 將物件的建立過程分解為多個步驟,根據需求排列組合 -  ```c++= // concrete builder class LuxuryCarBuilder { private: Car* car; public: LuxuryCarBuilder() { car = new Car(); } void buildEngine() { car->setEngine("V8 Turbo Engine"); } void buildWheels() { car->setWheels("Alloy Wheels"); } void buildInterior() { car->setInterior("Leather Interior"); } Car* getCar() { return car; } }; // client CarBuilder* builder = new LuxuryCarBuilder(); builder->buildEngine(); builder->buildWheels(); builder->buildInterior(); Car* car = builder->getCar(); ``` ## (4)原型模式 Prototype - 替原有的類別提供複製的介面 - 先建立一個原型,接著快速複製這個原型 - 在C++中,這通常是透過深拷貝或淺拷貝來實現的 - 原型模式的缺點在於`複製過程的複雜性`。當物件的結構非常複雜或包含指標、動態分配的資源時,正確地實現深拷貝可能會變得困難 ```c++= class Shape { virtual Shape *clone() = 0; } class Rectangle : Shape { private: int w; int h; public: Rectangle(int _w, int _h) : w(_w), h(_h) {} Shape *clone() const override { return new Rectangle(*this) } } ``` ## (5)單一實例模式 Singleton - 保證一個類別只有一個實例 - 要注意 `多執行緒同時存取` 單一實例的問題 -  - (1)餓漢模式(Eager Singleton) ```c++= class EagerSingleton { private: EagerSingleton() {} static EagerSingleton instance; public: EagerSingleton(const EagerSingleton&) = delete; EagerSingleton& operator=(const EagerSingleton&) = delete; static EagerSingleton& getInstance() { return instance; } }; // 在 main 開始之前就初始化 EagerSingleton EagerSingleton::instance; ``` - (2)懶漢模式(Lazy Singleton) ```c++= class LazySingleton { private: LazySingleton() {} static LazySingleton* instance; static std::mutex mtx; public: LazySingleton(const LazySingleton&) = delete; LazySingleton& operator=(const LazySingleton&) = delete; static LazySingleton* getInstance() { if (instance == nullptr) { std::lock_guard<std::mutex> lock(mtx); // thread safe if (instance == nullptr) { instance = new LazySingleton(); } } return instance; } }; // 初始化 LazySingleton* LazySingleton::instance = nullptr; std::mutex LazySingleton::mtx; ``` - (3) Meyers Singleton ```c++= class MeyersSingleton { private: MeyersSingleton() {} public: MeyersSingleton(const MeyersSingleton&) = delete; MeyersSingleton& operator=(const MeyersSingleton&) = delete; static MeyersSingleton& getInstance() { static MeyersSingleton instance; return instance; } }; ```
×
Sign in
Email
Password
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