浅析一道C++设计面试题
2009-03-17 21:59
435 查看
问题描述:
有一个饭店搞活动,普通客人吃饭打9折,银卡客户在此基础上再打8折,金卡客户再在此基础上打7折,问:该如何设计这个程序并用C++代码实现?
拿到这个题目后我的第一反应是使用一个抽象类提供一个打折操作的接口,然后普通客人、银卡客户和金卡客户分别实现该接口,在具体实现时使用多态来实现该功能,具体代码如下:
使用这个方式后,自己还沾沾自喜,以为回答的很完美,不过仔细想一下,如果这时候需求变为所有的客人都在原价的基础上打折而不是在其他客户的基础上打折该怎么办?重新编写代码,然后修改折扣计算方法。哦~!这就违反了面向对象中“对修改关闭,对扩展开放”的原则,那该怎么解决呢?可以使用设计模式中的“装饰者模式”解决,关于装饰者模式的讨论请自行查找资料,代码如下:
这里可以看出,如果打折方式变化,只需修改main中的代码,而不需修改类中任何代码。
程序输出:
在其他会员基础上打折的输出为:
9
7.2
5.04
请按任意键继续. . .
在原价基础上打折的输出为:
9
8
7
请按任意键继续. . .
有一个饭店搞活动,普通客人吃饭打9折,银卡客户在此基础上再打8折,金卡客户再在此基础上打7折,问:该如何设计这个程序并用C++代码实现?
拿到这个题目后我的第一反应是使用一个抽象类提供一个打折操作的接口,然后普通客人、银卡客户和金卡客户分别实现该接口,在具体实现时使用多态来实现该功能,具体代码如下:
#include <iostream> using namespace std; 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; }
使用这个方式后,自己还沾沾自喜,以为回答的很完美,不过仔细想一下,如果这时候需求变为所有的客人都在原价的基础上打折而不是在其他客户的基础上打折该怎么办?重新编写代码,然后修改折扣计算方法。哦~!这就违反了面向对象中“对修改关闭,对扩展开放”的原则,那该怎么解决呢?可以使用设计模式中的“装饰者模式”解决,关于装饰者模式的讨论请自行查找资料,代码如下:
#include <iostream> #include <string> using namespace std; 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
请按任意键继续. . .
相关文章推荐
- 浅析一道C++设计面试题
- 与全局变量构造析构顺序有关的一道面试题(C++)
- 与全局变量构造析构顺序有关的一道面试题(C++)
- 与全局变量构造析构顺序有关的一道面试题(C++)
- 一道c/c++面试题的解题思路
- C++面试题之程序设计其他问题面试题
- 一道C++面试题的误区
- C++ sizeof() 和一道面试题
- C/C++的面试题一道
- 一道java线程面试题--设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
- 面试题48:用C++设计一个不能被继承的类
- C++ sizeof() 和一道面试题
- 一道短小强悍的C++面试题
- C++一道面试题(atexit)
- 原创:我自己设计了一道面试题(1)
- 一道 c++字符串 面试题
- 一道有趣的面试题 - 设计模式的运用
- 通过一道面试题来看 C++的RVO 优化
- 与全局变量构造析构顺序有关的一道面试题(C++)
- 设计的两道面试题C++