设计模式之简单工厂与策略模式



    最近开始看《大话设计模式》,虽然之前零零星星的看过,但是一直也没有深入的思考,也是赶上最近编码较多,突然感触颇深。

    首先是简单工厂模式:以一个计算器为例子,主要讲述了多态的实现,以及最后最关键的地方:何时实例化

    例子中,将计算器涉及的加减乘除分别继承于基类“操作类”,一个简单的多态使用。但是在最后选择,如何进行实例化时,提出了简单工厂的概念。

    工厂,主要就是生产用的。所以,在简单工厂中,进行实例化,代码如下:

class OperFactory
{
public:
	static Operation* GetOperation(char szOper) {
		switch (szOper)
		{
		case '+':
			return new OperationAdd();
			break;
		case '-':
			return new OperationSub();
			break;
		case '*':
			return new OperationMul();
			break;
		case '/':
			return new OperationDiv();
			break;
		default:
			return NULL;
			break;
		}
	}
};
    这样,通过多态与简单工厂模式,就可以用面向对象的方式实现简单工厂模式。个人总结下来,简单工厂模式,在于多态,更在于实例化!


    之后是策略模式,策略模式用了一个超市收银各种打折的例子来说明的。

    不同于简单工厂模式,策略模式在于选择不同的策略,主要的意思是各种不同算法的选择,还是,抽象出一个基类,下面的子类来扩展各自的算法,代码如下:

class CashSuper
{
private:
	double dbCount;
	double dbPrice;

public:
	void SetCount(double count) { dbCount = count; }
	void SetPrice(double price) { dbPrice = price; }

	virtual double GetTotalPrice() { return dbCount*dbPrice; }
};

class CashNormal : public CashSuper
{
public:
	double GetTotalPrice() { return CashSuper::GetTotalPrice(); }
};

class CashReturn : public CashSuper
{
private:
	double dbMoney;
	double dbReturn;
public:
	CashReturn(double money, double ret) :dbMoney(money), dbReturn(ret) {}

	double GetTotalPrice() {
		double dbTotal = CashSuper::GetTotalPrice();
		int nTmp = dbTotal / dbMoney;
		return dbTotal - nTmp*dbReturn;
	}
};

class CashRebate : public CashSuper
{
private:
	double dbRebate;
public:
	CashRebate(double rebate) :dbRebate(rebate) {}

	double GetTotalPrice() {
		double dbTotal = CashSuper::GetTotalPrice();
		return dbTotal*dbRebate;
	}
};
    在这种时候,可以采用前面的简单工厂模式来进行实例化:

// 套用简单工厂的方法
class CashFactory
{
public:
	static CashSuper* GetCashClass(int nType) {
		switch (nType)
		{
		case 0:
			return new CashNormal();
			break;
		case 1:
			return new CashReturn(300.0, 100.0);
			break;
		case 2:
			return new CashRebate(0.8);
			break;
		default:
			return NULL;
			break;
		}
	}
};
    但是在这种使用下,首先,实例化的是算法,不是具体的实例,在描述上有些别扭,其次,针对使用者来说,需要暴露出来2个类,分别是CashSuper以及CashFactory,这种时候,策略模式来了,增加一个上下文类,承上启下。

class CashContextEx
{
private:
	CashSuper* pSuper;
public:
	CashContextEx(int nType) {
		switch (nType)
		{
		case 0:
			pSuper = new CashNormal();
			break;
		case 1:
			pSuper = new CashReturn(300.0, 100.0);
			break;
		case 2:
			pSuper = new CashRebate(0.8);
			break;
		default:
			pSuper = NULL;
			break;
		}
	}

	void SetTotalPrice() { pSuper->SetCount(15); pSuper->SetPrice(50); }
	double GetResult() { return pSuper->GetTotalPrice(); }
};

    OK,到现在,使用者,只需要知道CashContextEx就可以,这也是与简单工厂结合的方式。


    不过,今天白天,偶然的思考中,突然发现,前面这样一点一点的方法,其实是有点进入了作者的套路中去了,因为其实如果直接写的话,很可能写成根据type初始化类,同时,提供方法来传递价格,最后提供结果,如下:

// 前面感觉被套路了
class Cash
{
private:
	double dbTotal;
public:
	Cash(int nType) {
		// 这里初始化具体算法
	}

	void SetTotalPrice(double total) { dbTotal = total; }
	double GetResult() { return 算法(dbTotal); }
};


    总结一下:其实没有必要非要按照设计模式来进行代码编写,主要还是本着原则去,利用好“封装” “继承” “多态”三大特性,关键的关键,还是要多写代码,熟练性工种,诚不欺人!!

    PS:多看书也很有用,一下一大步一大步的感觉哦!




你可能感兴趣的:(设计模式)