常用设计模式总结。10种常用的设计模式。
概述
复习一下常用的设计模式,使用C++实现。常用的模式如下:
- 单例模式
 - 简单工厂模式
 - 工厂方法模式
 - 抽象工厂模式
 - 建造者模式
 - 适配器模式
 - 命令模式
 - 观察者模式
 - 策略模式
 
简单工厂模式
简单工厂模式,一个工厂,根据类别来生成具体的产品
#include <iostream>
/*
简单工厂模式,一个工厂,根据类别来生成具体的产品
*/
class AbstractProduct_SF {
public:
	AbstractProduct_SF() = default;
	virtual ~AbstractProduct_SF() {};
	virtual void show() = 0;
};
class Product1SF : public AbstractProduct_SF {
public:
	void show() override{
		std::cout << "product 1" << std::endl;
	}
};
class Product2SF : public AbstractProduct_SF {
public:
	void show() override {
		std::cout << "product 2" << std::endl;
	}
};
class Factory {
public:
	AbstractProduct_SF* createProduct(int type) {
		if (type == 0) {
			return new Product1SF();
		}
		else {
			return new Product2SF();
		}
	}
};
工厂方法模式
工厂方法模式,不同的工厂生产不同的商品
#include <iostream>
/*
工厂方法模式,不同的工厂生产不同的商品
*/
class FMProduct {
public:
	virtual ~FMProduct() {};
	virtual void show() = 0;
};
class FMProduct1 : public FMProduct {
public:
	void show() override {
		std::cout << "product 1" << std::endl;
	}
};
class FMProduct2 : public FMProduct {
public:
	void show() override {
		std::cout << "product 2" << std::endl;
	}
};
class FMFactory {
public:
	virtual ~FMFactory() {}
	virtual FMProduct* createProduct() = 0;
};
class FMFactory1 :public FMFactory{
public:
	FMProduct* createProduct() {
		return new FMProduct1();
	}
};
class FMFactory2 : public FMFactory {
public:
	FMProduct* createProduct() {
		return new FMProduct2();
	}
};
抽象工厂模式
抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
假设你正在开发一款家具商店模拟器。 你的代码中包括一些类, 用于表示:
1.一系列相关产品, 例如 椅子Chair 、  沙发Sofa和 咖啡桌CoffeeTable 。
2.系列产品的不同变体。 例如, 你可以使用 现代Modern 、  维多利亚Victorian 、  装饰风艺术ArtDeco等风格生成 椅子 、  沙发和 咖啡桌 。
#include <iostream>
/*
抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
假设你正在开发一款家具商店模拟器。 你的代码中包括一些类, 用于表示:
1.一系列相关产品, 例如 椅子Chair 、  沙发Sofa和 咖啡桌CoffeeTable 。
2.系列产品的不同变体。 例如, 你可以使用 现代Modern 、 
 维多利亚Victorian 、  装饰风艺术ArtDeco等风格生成 椅子 、  沙发和 咖啡桌 。
*/
/*
抽象产品A
*/
class AbstractProductA {
public:
	AbstractProductA() = default;
	virtual ~AbstractProductA() {};
	virtual void createProductA() = 0;
};
class ConcreteProductA1 : public AbstractProductA {
public:
	virtual void createProductA() override {
		std::cout << "concrete product A1" << std::endl;
	};
};
class ConcreteProductA2 : public AbstractProductA {
public:
	virtual void createProductA() override {
		std::cout << "concrete product A2" << std::endl;
	};
};
/*
抽象产品B
*/
class AbstractProductB {
public:
	AbstractProductB() = default;
	virtual ~AbstractProductB() {};
	virtual void createProductB() = 0;
};
class ConcreteProductB1 : public AbstractProductB {
public:
	virtual void createProductB() override {
		std::cout << "concrete product B1" << std::endl;
	};
};
class ConcreteProductB2 : public AbstractProductB {
public:
	virtual void createProductB() override {
		std::cout << "concrete product B2" << std::endl;
	};
};
/*
工厂类
*/
class AbstractFactory
{
public:
	AbstractFactory() = default;
	virtual ~AbstractFactory() {};
	virtual AbstractProductA* createProductA() const = 0;
	virtual AbstractProductB* createProductB() const = 0;
};
class ConcreteFactory1 : public AbstractFactory {
public:
	ConcreteFactory1() = default;
	virtual ~ConcreteFactory1() {};
	AbstractProductA* createProductA() const override {
		std::cout << "factory1 create concrete A1" << std::endl;
		return new ConcreteProductA1();
	}
	AbstractProductB* createProductB() const override {
		std::cout << "factory1 create concrete B1" << std::endl;
		return new ConcreteProductB1();
	}
};
class ConcreteFactory2 : public AbstractFactory {
public:
	ConcreteFactory2() = default;
	virtual ~ConcreteFactory2() {};
	AbstractProductA* createProductA() const override {
		std::cout << "factory1 create concrete A2" << std::endl;
		return new ConcreteProductA2();
	}
	AbstractProductB* createProductB() const override {
		std::cout << "factory1 create concrete B2" << std::endl;
		return new ConcreteProductB2();
	}
};
建造者模式
与其他创建型模式不同, 生成器不要求产品拥有通用接口。 这使得用相同的创建过程生成不同的产品成为可能。
使用示例: 生成器模式是 C++ 世界中的一个著名模式。 当你需要创建一个可能有许多配置选项的对象时, 该模式会特别有用。
识别方法: 生成器模式可以通过类来识别, 它拥有一个构建方法和多个配置结果对象的方法。 生成器方法通常支持方法链 (例如 someBuilder->setValueA(1)->setValueB(2)->create() )。
#pragma once
#include <iostream>
#include <string>
#include <vector>
/*
* 
* 与其他创建型模式不同, 生成器不要求产品拥有通用接口。
这使得用相同的创建过程生成不同的产品成为可能。
使用示例: 生成器模式是 C++ 世界中的一个著名模式。 
当你需要创建一个可能有许多配置选项的对象时, 该模式会特别有用。
识别方法: 生成器模式可以通过类来识别, 
它拥有一个构建方法和多个配置结果对象的方法。
生成器方法通常支持方法链 (例如 someBuilder->setValueA(1)->setValueB(2)->create() )。
*/
class Product1 {
public:
	std::vector<std::string> product_setting;
	void show() {
		std::vector<std::string>::iterator item;
		for (item = product_setting.begin(); 
			item != product_setting.end();++item)
		{
			std::cout << "item  " << *item << std::endl;
		}
		return;
	}
};
class Builder
{
public:
	virtual ~Builder() {};
	virtual void productPartA() const = 0;
	virtual void productPartB() const = 0;
	virtual void productPartC() const = 0;
};
class ConcreteBuilder : public Builder {
private:
	Product1* product;
public:
	ConcreteBuilder() {
		this->reset();
	}
	virtual ~ConcreteBuilder() { delete product; };
	void reset() {
		this->product = new Product1();
	}
	void productPartA() const override {
		this->product->product_setting.push_back("part A");
	}
	void productPartB() const override {
		this->product->product_setting.push_back("part B");
	}
	void productPartC() const override {
		this->product->product_setting.push_back("part C");
	}
	Product1* getProduct() {
		Product1* result = this->product;
		reset();
		return result;
	}
};
class Director {
private:
	Builder* builder;
public:
	void set_build(Builder* builder) {
		this->builder = builder;
	}
	void buildProductPartA() {
		builder->productPartA();
	}
	void buildProductFullPart() {
		builder->productPartA();
		builder->productPartB();
		builder->productPartC();
	}
};
适配器模式
适配器是一种结构型设计模式, 它能使不兼容的对象能够相互合作。
适配器可担任两个对象间的封装器, 它会接收对于一个对象的调用, 并将其转换为另一个对象可识别的格式和接口。
#pragma once
#include <iostream>
/*
适配器模式
适配器是一种结构型设计模式, 它能使不兼容的对象能够相互合作。
适配器可担任两个对象间的封装器, 
它会接收对于一个对象的调用, 并将其转换为另一个对象可识别的格式和接口。
*/
class Target {
public:
	virtual ~Target() = default;
	virtual void request() {
		std::cout << "target request" << std::endl;
	};
};
class Adaptee {
public:
	void new_request() {
		std::cout << "new request " << std::endl;
	}
};
class Adapter : public Target {
public:
	Adaptee* adaptee_;
	Adapter(Adaptee* ad) :adaptee_(ad) {}
	void request() override {
		adaptee_->new_request();
	}
};
命令模式
命令是一种行为设计模式, 它可将请求或简单操作转换为一个对象。
此类转换让你能够延迟进行或远程执行请求, 还可将其放入队列中。
#pragma once
#include <iostream>
/**
 * 命令是一种行为设计模式, 它可将请求或简单操作转换为一个对象。
*  此类转换让你能够延迟进行或远程执行请求, 还可将其放入队列中。
 */
class Command {
public:
	virtual ~Command() = default;
	virtual void execute() const = 0;
};
class CopyCommand : public Command {
public:
	void execute() const override{
		std::cout << "execute copy" << std::endl;
	}
};
class PasteReceiver {
public:
	void doPaste() {
		std::cout << "do paste" << std::endl;
	}
};
//由具体的receiver来执行具体的业务逻辑
class PasteCommand : public Command {
public:
	PasteCommand(PasteReceiver* receiver) {
		receiver_ = receiver;
	}
	void execute() const override {
		receiver_->doPaste();
	}
private:
	PasteReceiver* receiver_;
};
class Invoker {
private:
	Command* copy_command_ = nullptr;
	Command* paste_command_ = nullptr;
public:
	void setCopyCmd(Command* cmd) {
		copy_command_ = cmd;
	}
	void setPasteCmd(Command* cmd) {
		paste_command_ = cmd;
	}
	void doCmd() {
		if (copy_command_) {
			copy_command_->execute();
		}
		if (paste_command_) {
			paste_command_->execute();
		}
	}
};
观察者模式
观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件 发生时通知多个 “观察” 该对象的其他对象。
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <list>
/*
观察者模式是一种行为设计模式,
允许你定义一种订阅机制, 可在对象事件
发生时通知多个 “观察” 该对象的其他对象。
*/
class Observer {
public:
	virtual ~Observer() = default;
	virtual void update(std::string msg) = 0;
};
class Subject {
public:
	virtual ~Subject() = default;
	virtual void attach(Observer* observer) = 0;
	virtual void detach(Observer* observer) = 0;
	virtual void notify() = 0;
};
class ConcreteSubject : public Subject {
public:
	virtual ~ConcreteSubject() = default;
	void attach(Observer* observer) override {
		observer_list_.push_back(observer);
	}
	void detach(Observer* observer) override {
		observer_list_.remove(observer);
	}
	void notify() override {
		std::list<Observer*>::iterator iterator 
			= observer_list_.begin();
		while (iterator != observer_list_.end())
		{
			(*iterator)->update(curr_msg_);
			++iterator;
		}
	}
	void updateMsg(std::string msg) {
		curr_msg_ = msg;
		notify();
	}
public:
	std::string curr_msg_;
	std::list<Observer*> observer_list_;
};
class ConcreteObserver :public Observer {
public:
	ConcreteObserver(Subject* subject)
		: subject_(subject) {
		this->subject_->attach(this);
	};
	void update(std::string msg) override {
		message_from_subject_ = msg;
		std::cout << "get update msg:" 
			<< msg << std::endl;
	}
	void removeFromSubject() {
		this->subject_->detach(this);
	}
	void show() {
		std::cout << "msg:" << message_from_subject_;
	}
private:
	Subject* subject_;
	std::string message_from_subject_;
};
策略模式
策略是一种行为设计模式, 它将一组行为转换为对象, 并使其在原始上下文对象内部能够相互替换。
原始对象被称为上下文, 它包含指向策略对象 的引用并将执行行为的任务分派给策略对象。 为了改变上下文完成其工作的方式, 其他对象可以使用另一个对象来替换当前链接的 策略对象。
#pragma once
#include <iostream>
/*
策略是一种行为设计模式, 它将一组行为转换为对象, 并使其在原始上下文对象内部能够相互替换。
原始对象被称为上下文, 它包含指向策略对象
的引用并将执行行为的任务分派给策略对象。 
为了改变上下文完成其工作的方式, 
其他对象可以使用另一个对象来替换当前链接的
策略对象。
*/
class Strategy {
public:
	virtual ~Strategy() = default;
	virtual void alg() = 0;
};
class Strategy1 : public Strategy {
public:
	void alg() override {
		std::cout << "use strategy 1" << std::endl;
	}
};
class Strategy2 : public Strategy {
public:
	void alg() override {
		std::cout << "use strategy 2" << std::endl;
	}
};
class Context {
public:
	Context(Strategy* strategy) : strategy_(strategy) {
	}
	void set_strategy(Strategy* strategy) {
		if (strategy_) {
			delete strategy_;
		}
		this->strategy_ = strategy;
	}
	void use() {
		this->strategy_->alg();
	}
private:
	Strategy* strategy_;
};
使用方法
#include <iostream>
#include "abstract_factory.h"
#include "builder.h"
#include "sample_factory.h"
#include "factory_method.h"
#include "Adapter.h"
#include "command.h"
#include "observer.h"
#include "strategy.h"
void abstractFactoryClientCode(const AbstractFactory& factory) {
	const AbstractProductA* product_a = factory.createProductA();
	const AbstractProductB* product_b = factory.createProductB();
	//TODO use
	delete product_a;
	delete product_b;
}
void testAbstractFactory() {
	ConcreteFactory1* f1 = new ConcreteFactory1();
	abstractFactoryClientCode(*f1);
	delete f1;
	std::cout << std::endl;
	ConcreteFactory2* f2 = new ConcreteFactory2();
	abstractFactoryClientCode(*f2);
	delete f2;
	return ;
}
void testBuilder(){
	Director* director = new Director();
	ConcreteBuilder* builder = new ConcreteBuilder();
	director->set_build(builder);
	std::cout << "part A" << std::endl;
	director->buildProductPartA();
	builder->getProduct()->show();
	std::cout << "full part" << std::endl;
	director->buildProductFullPart();
	builder->getProduct()->show();
}
void testSampleFactory() {
	Factory* sample_factory = new Factory();
	auto product1 = sample_factory->createProduct(0);
	product1->show();
	auto product2 = sample_factory->createProduct(1);
	product2->show();
	delete product1;
	delete product2;
	delete sample_factory;
}
void testFactoryMethod() {
	FMFactory1* factory1 = new FMFactory1();
	auto product1 = factory1->createProduct();
	product1->show();
	FMFactory2* factory2 = new FMFactory2();
	auto product2 = factory2->createProduct();
	product2->show();
}
void testAdapter() {
	Target* target = new Target();
	target->request();
	Adaptee* adaptee = new Adaptee();
	adaptee->new_request();
	Adapter* adapter = new Adapter(adaptee);
	adapter->request();
}
void testCommand() {
	Invoker* invoker = new Invoker();
	invoker->setCopyCmd(new CopyCommand());
	PasteReceiver* receiver = new PasteReceiver();
	invoker->setPasteCmd(new PasteCommand(receiver));
	invoker->doCmd();
}
void testObserver() {
	ConcreteSubject* subject = new ConcreteSubject();
	ConcreteObserver* ob1 = new ConcreteObserver(subject);
	ConcreteObserver* ob2 = new ConcreteObserver(subject);
	ConcreteObserver* ob3 = new ConcreteObserver(subject);
	
	subject->updateMsg("123");
	subject->updateMsg("456");
}
void testStrategy() {
	Context* context = new Context(new Strategy1());
	context->use();
	context->set_strategy(new Strategy2());
	context->use();
}
int main()
{
    std::cout << "Hello World!\n";
	//abstract factory
	testAbstractFactory();
	//builder
	testBuilder();
	//sample factory 
	testSampleFactory();
	//factory method
	testFactoryMethod();
	//adapter
	testAdapter();
	//command
	testCommand();
	//observer
	testObserver();
	//strategy
	testStrategy();
	
	system("pause");
}