设计模式1简单工厂模式
请用C++,java,C#等任意一种面向对象语言实现一个计算机控制台程序,要求输入的两个数和运算符号,得到结果。
你看到题目,觉得这道题不难,没一会就写好了,如下
version_1.cpp #include using namespace std; int main(int argc, char const* argv[]) { char b; double a, c, d; cout << "请输入数字A: " << endl; cin >> a; cout << "请输入运算符(+, -, *, /):" << endl; cin >> b; cout << "请输入数字B: " << endl; cin >> c; if (b == "+") { d = a + c; } if (b == "-") { d = a - c; } if (b == "*") { d = a * c; } if (b == "/") { d = a / c; } cout << "两个数的运算结果为: " << d << endl; return 0; }
其实上面的代码有几个问题。 命名a b c d 很不规范 判断分支的写法,写了4个if,意味着每个条件都要做判断,相当于计算机做了3次无用功 如果除数为0则将程序异常。 虽然C++代码里会输出inf,但是相对于应用场景来说是有问题的。
针对以上的问题,进行修改,结果如下:
version_2.cpp #include using namespace std; int main(int argc, char const* argv[]) { char op; double num1, num2, result; cout << "请输入数字A: " << endl; cin >> num1; cout << "请输入运算符(+, -, *, /):" << endl; cin >> op; cout << "请输入数字B: " << endl; cin >> num2; if (op == "+") { result = num1 + num2; } else if (op == "-") { result = num1 - num2; } else if (op == "*") { result = num1 * num2; } else if (op == "/") { if (num2 == 0) { cout << "除数不能为0!" << endl; return 0; } result = num1 / num2; } cout << "两个数的运算结果为: " << result << endl; return 0; }
改到实现计算器是没有问题的,但是有没有写出让人满意的代码呢?
现在我让你写一个window程序的计算器,要有图形界面的,是不是说我下面这段代码要再写一遍呢? if (op == "+") { result = num1 + num2; } else if (op == "-") { result = num1 - num2; } else if (op == "*") { result = num1 * num2; } else if (op == "/") { if (num2 == 0) { cout << "除数不能为0!" << endl; return 0; } result = num1 / num2; }
还是说你打算直接复制过去?
题目说要用面向对象的语言写出计算器的程序。
面向对象,封装,我们把这段代码封装成类,实现代码的复用。
version_3.cpp #include using namespace std; class Calc { public: static double calc(double num1, double num2, const char op) { if (op == "+") { return num1 + num2; } else if (op == "-") { return num1 - num2; } else if (op == "*") { return num1 * num2; } else if (op == "/") { if (num2 == 0) { cout << "除数不能为0!" << endl; return 0; } return num1 / num2; } else { throw; } } }; int main(int argc, char const* argv[]) { char op; double num1, num2, result; cout << "请输入数字A: " << endl; cin >> num1; cout << "请输入运算符(+, -, *, /):" << endl; cin >> op; cout << "请输入数字B: " << endl; cin >> num2; result = Calc::calc(num1, num2, op); cout << "两个数的运算结果为: " << result << endl; return 0; }
这样,我们就把计算方法封装好了,实现了代码的复用。
现在,来了一个新需求,要加一个 开根号(sqrt) 的运算,你要怎么改?
只要修改 Calc 类就行了,加一个 if 判断。
这样可行, 但是 有一个问题,你现在要加一个开根号的运算,却要 加减乘除 的运算都参与编译,如果你大意了,把加法写做除法,那凉凉。
所以引出了我们今天所学的简单工厂模式, 其实就是如何去实例化对象的问题
针对不同的的操作符生成不同的运算类对象,利用C++的多态调用子类的函数进行运算。
如果需要加一个 开根号的运算,实现一个 开根号的运算类,在工厂类中增加一个判断就好了,就不会改到原来的运算类的实现,也不用原有的运算类参与到编译的过程,避免了出错。
version_4.cpp #include using namespace std; class Calc { public: virtual double calc(double num1, double num2) { return 0; }; }; class AddCalc : public Calc { public: double calc(double num1, double num2) override { return num1 + num2; } }; class SubCalc : public Calc { public: double calc(double num1, double num2) override { return num1 - num2; } }; class MulCalc : public Calc { public: double calc(double num1, double num2) override { return num1 * num2; } }; class DivCalc : public Calc { public: double calc(double num1, double num2) override { if (num2 == 0) { cout << "除数不能为0!" << endl; return 0; } return num1 / num2; } }; class CalcFactory { public: static Calc* CreateCalc(const char op) { if (op == "+") { return new AddCalc; } else if (op == "-") { return new SubCalc; } else if (op == "*") { return new MulCalc; } else if (op == "/") { return new DivCalc; } else { throw; } } }; int main(int argc, char const* argv[]) { char op; Calc *calc; double num1, num2, result; cout << "请输入数字A: " << endl; cin >> num1; cout << "请输入运算符(+, -, *, /):" << endl; cin >> op; cout << "请输入数字B: " << endl; cin >> num2; calc = CalcFactory::CreateCalc(op); result = calc->calc(num1, num2); cout << "两个数的运算结果为: " << result << endl; return 0; }
最后复习一下C++多态的三个必要条件: 是一个指针 父类指针指向子类对象 调用虚函数
你学会了吗? 自己实现一遍吧,会有收获的。
华为正式官宣!微软这回慢了一步纵观全球操作系统市场,主要可以分为两大领域,一个是PC电脑,另一个就是智能手机。其中美国微软公司旗下的Windows,在PC电脑系统方面占据了绝对垄断的地位而谷歌的安卓和苹果的iO
岂止华为,OPPO也出手了,5G反击正式开始,向专利流氓说不点击关注,每天精彩不断!导读岂止华为,OPPO也出手了,5G反击正式开始,向专利流氓说不!众所周知,在这个移动互联网横行的时代,网络已经变成了我们生活中最为重要的东西了而此前在2G
直播带货取代传统线下电商的核心点是什么?随着时代的进步,科技的发展,商业由传统线下交易演变成线上交易,成就国内电商的爆发,再由传统电商演变成短视频带货模式。可以说是每个模式都是根据消费者追求决定,说白了就是人的欲望未得到
Windows10系统,必须做的三个设置,我来教你Windows10系统,必做的三个设置。第一个设置,找出此电脑和控制面板,首先右击桌面,点击个性化,点击主题,找到桌面图标设置。把计算机和控制面板打上对勾,点击确定,我们会发现,桌
宇宙中有100颗恒星突然消失,难道它们都被地外生命吸收了吗?周而复始是宇宙之中普遍的规律。任何有生命和无生命的物质,都逃脱不了这个亘古不变的真理。恒星即将死亡图片既然是恒星,那就用我们最熟悉的,也是我们时时刻刻离不开的太阳来说吧,它诞生于4
地球上第一个人类是怎么出现的?题主认为解释不了人类进化,大概是以为生物进化以个体为单位,而凑巧出现1男1女2个古人类的几率很低。然而并不是这样。生物进化是以种群为单位的渐变过程,最开始出现了一批人类,而后才有了
电饭锅是怎么知道饭熟了跳闸而保温的?在网上搜了一幅电饭锅的结构示意图,不知能否看明白?做饭时,按下按钮开关,通过杠杆AOBC向上推动永磁体,使永磁体靠近感温磁钢(注意在永磁体靠近前,感温磁钢是没有磁性的,靠近后,被磁
新买的路由器不小心放20的冰箱里了,还能用么?新买的路由器不小心放20的冰箱里了,还能用么?如题,丈母娘不知道是啥,把新买的路由器不小心放20的冰箱里了,放了大概4个小时还能用么?新买的路由器不小心放20的冰箱里4个小时,应该
iphone是不是关闭了一个卡,另外一个卡的信号就好很多了?双卡的iPhone在日常使用中,卡2的信号通常都不太好,单卡状态下的信号就要好很多,出现这种状况的原因也比较好理解,单卡的iPhone信号都一般般,更何况双卡呢?苹果在系统生态以及
阿里巴巴和腾讯有没有和国企央企竞争的实力?一般来说,同等条件下民企的竞争力是要比国企和央企来的更强的,不管任何行业,只要这个行业是允许民营资本进入且政策上不对民营资本有过多限制的就行。银联云闪付完全不是支付宝的对手云闪付是
激光电视才是家用大屏的王者奥维云网数据显示,今年17月液晶电视平均销售尺寸达到54。2吋,远超去年同期70吋以上电视销量提升超5085吋产品更是增长175。5。从这些数据不难看出,大屏家用显示时代已然来临。