1863 字
9 分鐘
Design Patterns 筆記

Creational Patterns#

Factory Method#

  • Creational Patterns
  • provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created
  • 總而言之,就是提供一個可以父類別,讓使用者可以根據不同的需求去創造子類別,並實例化父類別的function,不一定每次調用都會創建新的實例

Code#

#include<iostream>
using namespace std;


class Button {
public:
	virtual void render() = 0;
	virtual void onClick(void (*f)()) = 0;

};

class WindowsButton: public Button {
public:
	void render() override {
		cout << "render Windows Button" << endl;
	}

	void onClick(void (*f)()) override {
		cout << "Windows Button clicked" << endl;
	}
};

class HTMLButton: public Button {
public:
	void render() override {
		cout << "render HTML Button" << endl;
	}

	void onClick(void (*f)()) override {
		cout << "Web Button clicked" << endl;
	}
};



class Dialog {
public:
	virtual Button* createButton() = 0;

	void render() {
		Button* okButton = createButton();

		okButton->onClick(closeDialog);
		okButton->render();
	}

	static void closeDialog() {
		cout << "Close Dialog" << endl;
	}
};

class WindowsDialog: public Dialog {

public:
	Button* createButton() override {
		return new WindowsButton();
	}

};


class WebDialog: public Dialog {

public:
	Button* createButton() override {
		return new HTMLButton();
	}

};


class Application {
public:

	Dialog* dialog;
	void init(string config) {
		if(config == "Windows") {
			dialog = new WindowsDialog();
		} else if(config == "Web"){
			dialog = new WebDialog();
		} else {
			cout << "Unknown OS" << endl;
		}
	}

};


int main() {
	Application Client;
	Client.init("Web");
	Client.dialog->render();

}

Abstract Factory Method#

  • Creational Patterns
  • lets you produce families of related objects without specifying their concrete classes
  • 總而言之,就是根據要求創建不同的工廠,而工廠生產的產品一樣,但是type不同,根據要求返回不同類型的多個產品

Code#

#include<iostream>
using namespace std;



class Button {
public:
	virtual void paint() = 0;
};

class WinButton:public Button {
public:
	void paint() override {
		cout << "Windows Button painted" << endl;
	}
};

class MacButton:public Button {
public:
	void paint() override {
		cout << "macOS Button painted" << endl;
	}
};

class Checkbox {
public:
	virtual void paint() = 0;
};

class WinCheckbox:public Checkbox {
public:
	void paint() override {
		cout << "Windows Checkbox painted" << endl;
	}
};

class MacCheckbox:public Checkbox {
public:
	void paint() override {
		cout << "macOS Checkbox painted" << endl;
	}
};

class GUIFactory {
public:
	virtual Button* createButton() = 0;
	virtual Checkbox* createCheckbox() = 0;
};

class WinFactory: public GUIFactory{
public:
	Button* createButton() override {
		return new WinButton();
	}
	Checkbox* createCheckbox() override{
		return new WinCheckbox();
	}

};

class MacFactory: public GUIFactory{
public:
	Button* createButton() override {
		return new MacButton();
	}
	Checkbox* createCheckbox() override{
		return new MacCheckbox();
	}

};



class Application {
	GUIFactory* factory;
	Button* button;
	Checkbox* checkbox;
public:
	Application(GUIFactory* factory): factory(factory) {
		this->factory = factory;
	}
	void createUI() {
		button = factory->createButton();
		checkbox = factory->createCheckbox();
	}
	void paint() {
		button->paint();
		checkbox->paint();
	}
};

class ApplicationConfigurator {
public:
	void main(string config) {
		
		GUIFactory* factory;
		if(config == "Windows") {
			factory = new WinFactory();
		} else if(config == "Mac") {
			factory = new MacFactory();
		} else {
			cout << "Unknow OS" << endl;
		}

		Application app(factory);
		app.createUI();
		app.paint();
	}
};

int main() {
	ApplicationConfigurator Client;
	Client.main("Windows");
	Client.main("Mac");

}

Builder Method#

  • Creational Patterns
  • allows you to produce different types and representations of an object using the same construction code.
  • 總而言之,就是讓初始化的建構子不要太繁瑣,將對象構造的程式碼從產品類中抽離,並放在一個名為Builder的獨立對象中,Builder不允許其他對象訪問正在建造中的產品。

Code#

#include <iostream>
#include <string>
using namespace std;

class Car{
	int _seats;
	string _engine;
	bool _hasTripComputer;
	bool _hasGPS;

public:
	void setSeats(int seats) {
		_seats = seats;
        cout << "Setting seats to " << seats << endl;
	}
	void setEngine(string engine) {
		_engine = engine;
		cout << "Installing " << engine << " engine" << endl;
	}
	void setTripComputer(bool tmp) {
		_hasTripComputer = tmp;
		if (tmp) {
            cout << "Installing trip computer" << endl;
        }
	}
	void setGPS(bool tmp) {
		_hasGPS = tmp;
		if (tmp) {
            cout << "Installing GPS" << endl;
        }
	}
	void display() {
		cout << "Car with " << _seats << " seats, engine: " << _engine;
		cout << ", Trip computer: " << (_hasTripComputer ? "Yes" : "No");
		cout << ", GPS: " << (_hasGPS ? "Yes" : "No") << endl;
	}
};

class Manual{
	int _seats;
	string _engine;
	bool _hasTripComputer;
	bool _hasGPS;
public:
    void setSeats(int seats) {
		_seats = seats;
        cout << "Adding manual for seats: " << seats << endl;
    }

    void setEngine(const std::string engine) {
		_engine = engine;
        cout << "Adding manual for " << engine << " engine" << endl;
    }

    void setTripComputer(bool tmp) {
		_hasTripComputer = tmp;
        if (tmp) {
            cout << "Adding manual for trip computer" << endl;
        }
    }

    void setGPS(bool tmp) {
		_hasGPS = tmp;
        if (tmp) {
            cout << "Adding manual for GPS" << endl;
        }
    }
    void display() {
		cout << "Car with " << _seats << " seats, engine: " << _engine;
		cout << ", Trip computer: " << (_hasTripComputer ? "Yes" : "No");
		cout << ", GPS: " << (_hasGPS ? "Yes" : "No") << endl;
	}
};

class Builder {
public:
	virtual void reset() = 0;
	virtual void setSeats(int seats) = 0;
	virtual void setEngine(string engine) = 0;
	virtual void setTripComputer(bool tmp) = 0;
	virtual void setGPS(bool tmp) = 0;
};

class CarBuilder: public Builder {
	Car car;
public:
	CarBuilder() {
		reset();
	}
	void reset() override {
		car = Car();
	}
	void setSeats(int quantity) override {
		car.setSeats(quantity);
	}
	void setEngine(string engine) override {
		car.setEngine(engine);
	}
	void setTripComputer(bool tmp) override {
		car.setTripComputer(tmp);
	}
	void setGPS(bool tmp) override {
		car.setGPS(tmp);
	}

	Car getProduct() {
		return car;
	}
};

class CarManualBuilder: public Builder{
    Manual manual;
public:
    void reset() override {
        manual = Manual();
    }
    void setSeats(int seats) override {
        manual.setSeats(seats);
    }
    void setEngine(const string engineType) override {
        manual.setEngine(engineType);
    }
    void setTripComputer(bool included) override {
        manual.setTripComputer(included);
    }
    void setGPS(bool included) override {
        manual.setGPS(included);
    }
    Manual getProduct() {
        return manual;
    }
};

class Director {
public:
	void constrcuctSportsCar(Builder& builder) {
		builder.reset();
		builder.setSeats(2);
		builder.setEngine("SportEngine");
		builder.setTripComputer(true);
		builder.setGPS(true);
	}
	void constrcuctSUV(Builder& builder) {
		builder.reset();
		builder.setSeats(4);
		builder.setEngine("SUVEngine");
		builder.setTripComputer(true);
		builder.setGPS(true);
	}
};

class Application {
public:
	void makeCar() {
		Director director;

		CarBuilder builder;
		director.constrcuctSportsCar(builder);
		Car car = builder.getProduct();
		car.display();

		CarManualBuilder manualBuilder;
		director.constrcuctSportsCar(manualBuilder);
		Manual manual = manualBuilder.getProduct();
		manual.display();
	}
};

int main() {
	Application client;
	client.makeCar();
}

Prototype Method#

  • Creational Patterns

  • lets you copy existing objects without making your code dependent on their classes.

  • 簡單來說,就是做一個通用接口(Prototype),讓使用者可以用該接口clone不同類型的對象

Singleton Method#

  • Creational Patterns
  • lets you ensure that a class has only one instance, while providing a global access point to this instance.
  • 保證一個class只有一個instance,並提供一個訪問該instance的global access

Strcutional Patterns#

Adapter Method#

  • Structural Patterns
  • allows objects with incompatible interfaces to collaborate.
  • 適配器,轉換資料,讓資料可以換一種格式以供客戶使用其他接口

Bridge Method#

  • Structural Patterns
  • lets you split a large class or a set of closely related classes into two separate hierarchies—abstraction and implementation—which can be developed independently of each other.
  • 將繼承關係轉換為關聯關係,降低程式碼的複雜度,還有類與類之間的耦合;將抽象與實現解耦,使得兩者可以獨立變化
  • 淺顯易懂的影片 https://youtu.be/3Wkp4AEaubI?si=8o4P7IHKFQ9r1QcT

Composite Method#

  • 就是樹,應該吧

Decorator Method#

  • 寫一個新的class,對原有的class新增功能;相較於對原有的class新增子類,這個方法不用被限制於原有類,繼承是靜態的,無法在執行時更改已有對象的行為,只能由不同子類創建的對象來替代當前的整個對象;且子類只能有一個父類。
  • 所以 Decorator 比生成子類更加靈活。

Facade Method#

  • 提供用戶一個簡單明瞭的接口,不讓背後繁瑣的系統程序顯現在表面

Flyweight Method#

  • 將重複的狀態儲存起來,降低系統的浪費

Proxy Method#

  • 就,代理,可以控制客戶請求,並處理過濾,減少對原系統負荷

Behavioral Design Patterns#

Chain of Responsibility Method#

  • 對請求處理,一個處理者沒處理完就給下一個,層層遞進,直到請求處理完成

Command Method#

  • 將使用者操作轉換成命令,而不是操作直接對應處理程序

Iterator Method#

  • 對collection創建一個迭代器,讓用戶可以獲取下一個元素、當前位置、重新開始迭代等;在不暴露底層結構的情況下遍歷元素。

Mediator Method#

  • 減少對象之間混亂的依賴關係,限制對象之間的直接交互,迫使對象們藉由一個中介者對象進行合作

Memento Method#

在不破壞對象封裝情況的前提下創建對象狀態快照,可通過讓負責人維護原發器狀態歷史紀錄來簡化原發器代碼

Observer Method#

定義一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆得到通知並被自動更新

State Method#

將原始對象指向每種狀態的class,且將所以與狀態相關的工作委託給狀態class

Strategy Method#

將算法裝到一個名為策略的獨立class,並在需要策略算法時,通過接口將工作委派給策略的class去選擇並回傳演算法

Design Patterns 筆記
https://yuyutw123.github.io/posts/designpattern/
作者
YuYutw123
發佈於
2024-05-14
許可協議
CC BY-NC-SA 4.0