问题描述:
有一个饭店搞活动,普通客人吃饭打9折,银卡客户在此基础上再打8折,金卡客户再在此基础上打7折,问:该如何设计这个程序并用C++代码实现?
拿到这个题目后我的第一反应是使用一个抽象类提供一个打折操作的接口,然后普通客人、银卡客户和金卡客户分别实现该接口,在具体实现时使用多态来实现该功能,具体代码如下:
class ICustomer
{
public:
ICustomer(double price = 0.0):m_Price(price)
{
}
~ICustomer()
{
}
void SetPrice(const double price)
{
m_Price = price;
}
virtual double Discount() = 0;
protected:
double m_Price;
};
class Comman : public ICustomer
{
public:
Comman()
{
}
~Comman()
{
}
double Discount()
{
return m_Price * 0.9;
}
};
class Silver : public ICustomer
{
public:
Silver()
{
}
~Silver()
{
}
double Discount()
{
return m_Price * 0.9 * 0.9;
}
};
class Gold : public ICustomer
{
public:
Gold()
{
}
~Gold()
{
}
double Discount()
{
return m_Price * 0.9 * 0.9 * 0.8;
}
};
void main(void)
{
ICustomer* test = new Silver();
test->SetPrice(10);
cout<<test->Discount()<<endl;
}
使用这个方式后,自己还沾沾自喜,以为回答的很完美,不过仔细想一下,如果这时候需求变为所有的客人都在原价的基础上打折而不是在其他客户的基础上打折该怎么办?重新编写代码,然后修改折扣计算方法。哦~!这就违反了面向对象中“对修改关闭,对扩展开放”的原则,那该怎么解决呢?可以使用设计模式中的“装饰者模式”解决,关于装饰者模式的讨论请自行查找资料,代码如下:
class ICustomer
{
public:
ICustomer(double price = 0.0):m_Price(price)
{
}
~ICustomer()
{
}
void SetPrice(double price)
{
m_Price = price;
}
virtual double Cost() = 0;
protected:
double m_Price;
};
class Customer : public ICustomer
{
public:
Customer()
{
}
~Customer()
{
}
double Cost()
{
return m_Price;
}
};
class CommanCostomer : public ICustomer
{
public:
CommanCostomer(ICustomer* customer) : pCustomer(customer)
{
}
double Cost()
{
return pCustomer->Cost() * 0.9;
}
private:
ICustomer* pCustomer;
};
class SilverCostomer : public ICustomer
{
public:
SilverCostomer(ICustomer* customer) : pCustomer(customer)
{
}
double Cost()
{
return pCustomer->Cost() * 0.8;
}
private:
ICustomer* pCustomer;
};
class GoldCostomer : public ICustomer
{
public:
GoldCostomer(ICustomer* customer) : pCustomer(customer)
{
}
double Cost()
{
return pCustomer->Cost() * 0.7;
}
private:
ICustomer* pCustomer;
};
void main(void)
{
// 在其他客户基础上打折
ICustomer* customer = new Customer();
customer->SetPrice(10.0);
customer = new CommanCostomer(customer);
cout<<customer->Cost()<<endl;
customer = new SilverCostomer(customer);
cout<<customer->Cost()<<endl;
customer = new GoldCostomer(customer);
cout<<customer->Cost()<<endl;
// 在原价基础上打折
/*ICustomer* customer = new Customer();
customer->SetPrice(10.0);
customer = new CommanCostomer(customer);
cout<<customer->Cost()<<endl;
ICustomer* customer1 = new Customer();
customer1->SetPrice(10.0);
customer1 = new SilverCostomer(customer1);
cout<<customer1->Cost()<<endl;
ICustomer* customer2 = new Customer();
customer2->SetPrice(10.0);
customer2 = new GoldCostomer(customer2);
cout<<customer2->Cost()<<endl;*/
}
这里可以看出,如果打折方式变化,只需修改main中的代码,而不需修改类中任何代码。
程序输出:
在其他会员基础上打折的输出为:
9
7.2
5.04
请按任意键继续. . .
在原价基础上打折的输出为:
9
8
7
请按任意键继续. . .