首先是简单工厂模式:以一个计算器为例子,主要讲述了多态的实现,以及最后最关键的地方:何时实例化。
例子中,将计算器涉及的加减乘除分别继承于基类“操作类”,一个简单的多态使用。但是在最后选择,如何进行实例化时,提出了简单工厂的概念。
工厂,主要就是生产用的。所以,在简单工厂中,进行实例化,代码如下:
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(); }
};
不过,今天白天,偶然的思考中,突然发现,前面这样一点一点的方法,其实是有点进入了作者的套路中去了,因为其实如果直接写的话,很可能写成根据type初始化类,同时,提供方法来传递价格,最后提供结果,如下:
// 前面感觉被套路了
class Cash
{
private:
double dbTotal;
public:
Cash(int nType) {
// 这里初始化具体算法
}
void SetTotalPrice(double total) { dbTotal = total; }
double GetResult() { return 算法(dbTotal); }
};
PS:多看书也很有用,一下一大步一大步的感觉哦!