设计模式

发布于 2020-05-17  548 次阅读


1. 单例模式

在系统中,一个类只有唯一的一个实例,并且该实例可以全局访问。

可以用于管理资源;如日志,线程池。

设计思路:

  • 只能有一个实例意味着不能在类的外部创造实例,那么其默认构造函数必须是private。此外拷贝构造函数和复制函数可以是private,可以delete掉。
  • 需要提供全局的访问点,所以得有个函数是static,并且返回一个static实例的引用。
class Singleton {
public:
	Singleton(Singleton const& input) = delete;
	Singleton& operator = (Singleton const& input) = delete;

	static Singleton& getInstance()
	{
		static Singleton singleton;
		return(singleton);
	}

	void fun()
	{
		cout << "do something" << endl;
	}

private:
	Singleton() = default;
};


int main()
{
	Singleton& temp = Singleton::getInstance();
	temp.fun();
	return(0);
}

2. 工厂模式

工厂模式的主要作用有:

  • 封装对象的创建
  • 分离对象封装和操作的过程
  • 用于批量管理对象的创建过程,便于程序的维护和扩展。

主要包括三种类型:

  1. 简单工厂模式
  2. 工厂方法模式(正宗)
  3. 抽象工厂模式

1. 简单工厂模式

这个模式是工厂模式最简单的一种实现。对于不同产品的创建定义一个工厂类,将产品类型作为参数传入到工厂的创建函数,根据类型分支选择不同的产品构造函数。

简单工厂模式只是一个对创建过程的封装。

为什么叫“简单”——不同的产品由同一个工厂制造

typedef enum productTypeTag
{
	typeA, typeB, typeC
}PRODUCTTYPE;

class product  //base class
{
public:
	virtual void who() = 0;
	virtual ~product()
	{
		cout << "product BASE destructor" << endl;
	};
};

class productA :public product
{
public:
	void who() override
	{
		cout << "I am A" << endl;
	}

	virtual ~productA()
	{
		cout << "product A destructor" << endl;
	};
};

class productB :public product
{
public:
	void who() override
	{
		cout << "I am B" << endl;
	}
	virtual ~productB()
	{
		cout << "product B destructor" << endl;
	};
};

class productC :public product
{
public:
	void who() override
	{
		cout << "I am C" << endl;
	}
	virtual ~productC()
	{
		cout << "product C destructor" << endl;
	};
};

class factory
{
public:
	product* createProduct(PRODUCTTYPE type)
	{
		switch (type)
		{
		case typeA:
			return(new productA());
		case typeB:
			return(new productB());
		case typeC:
			return(new productC());
		default:
			return(NULL);
		}
	}
};

int main()
{
	factory creator;
	product* A = creator.createProduct(typeA);
	product* B = creator.createProduct(typeB);
	product* C = creator.createProduct(typeC);

	A->who();
	B->who();
	C->who();

	if (A)
	{
		delete A;
		A = nullptr;
	}
	if (B)
	{
		delete B;
		B = nullptr;
	}
	if (C)
	{
		delete C;
		C = nullptr;
	}

	return(0);
}

2. 工厂方法模式

工厂方法模式在简单工程模式的基础上增加了对工程的基类抽象:

  • 不同的产品由不同的工厂的生产(这些工程是抽象工程基类派生而出)

对于简单工厂模式的有点:

  • 便于后期增加或删除产品的种类
class product  //base class
{
public:
	virtual void who() = 0;
	virtual ~product()
	{
		cout << "product BASE destructor" << endl;
	};
};

class productA :public product
{
public:
	void who() override
	{
		cout << "I am A" << endl;
	}

	virtual ~productA()
	{
		cout << "product A destructor" << endl;
	};
};

class productB :public product
{
public:
	void who() override
	{
		cout << "I am B" << endl;
	}
	virtual ~productB()
	{
		cout << "product B destructor" << endl;
	};
};

class productC :public product
{
public:
	void who() override
	{
		cout << "I am C" << endl;
	}
	virtual ~productC()
	{
		cout << "product C destructor" << endl;
	};
};

class factory
{
public:
	virtual product* createProduct() = 0;
};

class factoryA :public factory
{
public:
	product* createProduct()
	{
		return(new productA());
	}
};

class factoryB :public factory
{
public:
	product* createProduct()
	{
		return(new productB());
	}
};

class factoryC :public factory
{
public:
	product* createProduct()
	{
		return(new productC());
	}
};	

int main()
{
	factory* creatorA = new factoryA();
	product* A = creatorA->createProduct();

	factory* creatorB = new factoryB();
	product* B = creatorB->createProduct();

	factory* creatorC = new factoryC();
	product* C = creatorC->createProduct();


	A->who();
	B->who();
	C->who();

	if (creatorA)
	{
		delete creatorA;
		creatorA = nullptr;
	}
	if (creatorB)
	{
		delete creatorB;
		creatorB = nullptr;
	}
	if (creatorC)
	{
		delete creatorC;
		creatorC = nullptr;
	}

	if (A)
	{
		delete A;
		A = nullptr;
	}
	if (B)
	{
		delete B;
		B = nullptr;
	}
	if (C)
	{
		delete C;
		C = nullptr;
	}

	return(0);
}

3. 抽象工厂模式

适用于结构多产品,而工厂方法模式适用于结构单一的产品。当具有多个抽象产品类型时,抽象工程便可以派上用场。

抽象工厂:

  • 低端工厂生产不同种类低端产品
  • 高端工厂生产不同种类高端产品
/* Product A */
class productA
{
public:
	virtual void who() = 0;
};

class productALow :public productA 
{
public:
	void who() override
	{
		cout << "I am A low" << endl;
	}
};

class productAHigh :public productA
{
public:
	void who() override
	{
		cout << "I am A high" << endl;
	}
};

/* Product B */
class productB
{
public:
	virtual void who() = 0;
};

class productBLow :public productB
{
public:
	void who() override
	{
		cout << "I am B low" << endl;
	}
};

class productBHigh :public productB
{
public:
	void who() override
	{
		cout << "I am B high" << endl;
	}
};

/* Factory */
class factory
{
public:
	virtual productA* producesorA() = 0;
	virtual productB* producesorB() = 0;
};

class factoryLow :public factory 
{
	productA* producesorA() override
	{
		return(new productALow());
	}

	productB* producesorB() override
	{
		return(new productBLow());
	}
};

class factoryHigh :public factory
{
	productA* producesorA() override
	{
		return(new productAHigh());
	}

	productB* producesorB() override
	{
		return(new productBHigh());
	}
};


int main()
{
	factory* High = new factoryHigh();
	productA* highA = High->producesorA();
	productB* highB = High->producesorB();

	factory* Low = new factoryLow();
	productA* lowA = Low->producesorA();
	productB* lowB = Low->producesorB();

	highA->who();
	highB->who();
	lowA->who();
	lowB->who();

	delete High, highA, highB, Low, lowA, lowB;
	High = nullptr;
	highA = nullptr;
	highB = nullptr;
	Low = nullptr;
	lowA = nullptr;
	lowB = nullptr;
}

3. 策略模式

这个模式定义并封装了一系列算法,这些算法可以相互替换。这让算法独立于使用它的客户程序,可以独立变化。

三种类型的 class:

  • 抽象策略类(基类)
  • 封装了相关算法和行为(派生类)
  • 持有一个策略类引用,以给客户端调用

下面举例来看看策略模式是怎样设计的。关于这例子的出处和应用场景,请点这里

class wind
{
public:
	virtual void windType() = 0;
	virtual ~wind() = default;
};

class windWarm :public wind
{
public:
	void windType() override
	{
		cout << "The warm mode is on" << endl;
	}
};

class windCold :public wind
{
public:
	void windType() override
	{
		cout << "The cold mode is on" << endl;
	}
};

class windStop :public wind
{
public:
	void windType() override
	{
		cout << "The stop mode is on" << endl;
	}
};


class windMode
{
public:
	windMode(wind* input) :curWind(input) {};
	
	void windType()
	{
		curWind->windType();
	}

	~windMode()
	{
		delete curWind;
	}

private:
	wind* curWind;
};

int main()
{
	windMode* warm = new windMode(new windWarm());
	windMode* cold = new windMode(new windCold());
	windMode* stop = new windMode(new windStop());

	warm->windType();
	cold->windType();
	stop->windType();

	delete warm, cold, stop;
	warm = nullptr;
	cold = nullptr;
	stop = nullptr;
}