故事:
在一个软件村里
有一名资深「面向过程」程序员——老过(C语言)
和一名「面向对象」信徒——阿对(Java)
同时受雇于一家挨踢店
有一天老板突发奇想
决定让这两名程序员进行一次比赛
获胜者将获得一个限量的
360 度全自动按摩椅
编程比赛开始了
老过的代码
#include <stdio.h>
double getUnit(){
double Unit;
printf("请输入商品单价:");
scanf("%lf",&Unit);
printf("商品单价为:%f\n", Unit);
return Unit;
}
int getnumber(){
int Number;
printf("请输入商品数量:");
scanf("%d",&Number);
printf("商品数量为:%d\n", Number);
return Number;
}
int main(){
double Unit = getUnit();
printf("\n");
int Number = getnumber();
printf("\n");
double Price = Unit * Number;
printf("总价为:%lf\n",Price);
return 0;
}
而阿对则是
import java.util.Scanner;
public class Bill {
public static void main(String[] args) {
Price();
}
public static void Price(){
var unit = getUnit();
var num = getNumber();
double Price = unit * num;
System.out.println("总价格为:"+Price);
}
public static double getUnit(){
Scanner sc = new Scanner(System.in);
System.out.print("请输入商品单价:");
double Unit = sc.nextDouble();
return Unit;
}
public static int getNumber(){
Scanner sc = new Scanner(System.in);
System.out.print("请输入商品数量:");
int Num = sc.nextInt();
return Num;
}
}
老过看到新需求,微微一笑
//C语言
#include <stdio.h>
#include<time.h>
double getUnit(){
double Unit;
printf("请输入商品单价:");
scanf("%lf",&Unit);
printf("商品单价为:%f\n", Unit);
return Unit;
}
int getnumber(){
int Number;
printf("请输入商品数量:");
scanf("%d",&Number);
printf("商品数量为:%d\n", Number);
return Number;
}
int BoolLoversDay(){
time_t now = time(NULL);
struct tm *t = localtime(&now);
int month = t->tm_mon + 1;
int day = t->tm_mday;
if (month == 7 && day == 7) {
return 1;
} else {
return 0;
}
}
int main(){
double Unit = getUnit();
printf("\n");
int Number = getnumber();
printf("\n");
int LoverDay = BoolLoversDay();
if(LoverDay)
{
double Price = (Unit * Number)*0.77;
printf("总价为:%lf\n",Price);
}
else{
double Price = (Unit * Number);
printf("总价为:%lf\n",Price);
}
return 0;
}
他决定让新的收银方式继承 Bill 类
先修改Bill 类,并在其中新增 discount 方法,再专门开个Main来运行
Main
//Main
import java.util.Calendar;
public class Main {
public static void main(String[] args){
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH)+1;
int date = c.get(Calendar.DATE);
System.out.print("当前日期:"+ month + "月 ");
System.out.println(+ date + "日");
if( month == 10 && date == 5){
LoversDayBill.discount();
}
else{
Bill.discount();
}
}
}
Bill
//Bill
import java.util.Scanner;
public class Bill{
//折扣
public static void discount(){
double price = Price();
System.out.println("总价为:"+price);
}
//总价
public static double Price(){
var unit = getUnit();
var num = getNumber();
double Price = unit * num;
return Price;
}
//单价
public static double getUnit(){
Scanner sc = new Scanner(System.in);
System.out.print("请输入商品单价:");
double Unit = sc.nextDouble();
return Unit;
}
//数量
public static int getNumber(){
Scanner sc = new Scanner(System.in);
System.out.print("请输入商品数量:");
int Num = sc.nextInt();
return Num;
}
}
LoversDayBill
//LoversDayBill
public class LoversDayBill extends Bill{
public static void discount(){
double price = Price();
price = price*0.77;
System.out.println("情人节限定!本次消费是:"+price);
}
}
当老过和阿对同时将程序交给老板时
老过已经开始幻想自己将来
坐在按摩椅上的舒服日子
听到新需求
老过一阵头大
不由在群里吐槽
吐槽归吐槽
老过再次增加了条件判断
//C语言
#include <stdio.h>
#include<time.h>
#include <stdlib.h>
double getUnit(){
double Unit;
printf("请输入商品单价:");
scanf("%lf",&Unit);
printf("商品单价为:%f\n", Unit);
return Unit;
}
int getnumber(){
int Number;
printf("请输入商品数量:");
scanf("%d",&Number);
printf("商品数量为:%d\n", Number);
return Number;
}
int BoolLoversDay(){
time_t now = time(NULL);
struct tm *t = localtime(&now);
int month = t->tm_mon + 1;
int day = t->tm_mday;
if (month == 7 && day == 7) {
return 1;
} else {
return 0;
}
}
int BoolNationalDay(){
time_t now = time(NULL);
struct tm *t = localtime(&now);
int month = t->tm_mon + 1;
int day = t->tm_mday;
if (month == 10 && 1<= day && day <=7) {
return 1;
} else {
return 0;
}
}
int BoolAutumnDay(){
time_t now = time(NULL);
struct tm *t = localtime(&now);
int month = t->tm_mon + 1;
int day = t->tm_mday;
if (month == 8 && day == 15) {
return 1;
} else {
return 0;
}
}
int main(){
srand((unsigned)time(NULL));
double Unit = getUnit();
printf("\n");
int Number = getnumber();
printf("\n");
int LoverDay = BoolLoversDay();
int NationalDay = BoolNationalDay();
int AutumnDay = BoolAutumnDay();
//情人节
if(LoverDay)
{
double Price = (Unit * Number)*0.77;
printf("总价为:%lf\n",Price);
}
//国庆节
else if(NationalDay){
double Price = (Unit * Number);
int Rom = rand()%10;
if(Price<100 && Rom == 0)
{
printf("随机数为:%d\n",Rom);
Price = 0;
printf("总价为:%lf\n",Price);
}
else {
printf("总价为:%lf\n",Price);
}
}
//中秋节
else if (AutumnDay) {
double Price = (Unit * Number);
if(Price>399)
{
Price = Price - 100;
printf("总价为:%lf\n",Price);
}
else {
printf("总价为:%lf\n",Price);
}
}
//其他情况
else {
double Price = (Unit * Number);
printf("总价为:%lf\n",Price);
}
return 0;
}
看着越来越复杂的 Bill 类和 getPrice 方法
老过眉头紧锁他深知事情远没有结束
中秋和国庆一过他还需要到这个复杂的类中删掉打折的方法
天知道老板还会再提什么天马行空的需求无论是新增或删除代码,在这个过长的类里做修改都是件不太愉快的事。
为了在一个很长的函数中找到需要修改的位置,「面向过程」使得老过不得不浏览大量与修改无关的代码,小心翼翼地修改后,又要反复确认不会影响到类的其他部分。
老过在心底里默默地祈祷这个类不再需要修改提交了自己的程序
阿对创建了两个新的对象
MidAutumnDayBill
//MidAutumnDayBill
public class MidAutumnDayBill extends Bill {
public static void discount(){
double price = Price();
if(price >= 399){
price = price - 100;
System.out.println("中秋节快乐!满减有活动!本次消费是:" + price);
}
else{
System.out.println("中秋节快乐!本次消费是:" + price);
}
}
}
NationalDayBill
//NationalDayBill
import java.util.Random;
public class NationalDayBill extends Bill{
public static void discount(){
double price = Price();
Random lucky = new Random();
int num = lucky.nextInt(10);
System.out.println("国庆节幸运数字是:" + num);
if( price<100 && num == 0){
price = 0;
System.out.println("国庆节快乐!获得免单资格!本次消费我来买单!");
}
else{
System.out.println("国庆节快乐!本次消费为:" + price);
}
}
}
Main
//Main
import java.util.Calendar;
public class Main {
public static void main(String[] args){
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH)+1;
int date = c.get(Calendar.DATE);
System.out.print("当前日期:"+ month + "月 ");
System.out.println(+ date + "日");
if( month == 7 && date == 7){
System.out.println("今天是情人节,愿有情人终成眷属。");
LoversDayBill.discount();
}
else if(month == 8 && date == 15){
System.out.println("中秋节团团圆圆!月饼吃不停!");
MidAutumnDayBill.discount();
}
else if(month == 10 && date <=7 && date >=1 ){
System.out.println("国庆假期到来咯!好玩玩不停!");
NationalDayBill.discount();
}
else{
Bill.discount();
}
}
}
有一个好消息要告诉大家!
当老板兴高采烈地说出这句话时
老过和阿对都露出了心惊胆战的表情
这句话往往意味着要更改需求
老过反抗道
但他并没有说出心里另一个小九九
实在不想再去给 Bill 类添加代码了
这次修改老过花了较长的时间才完成
//C语言
#include <stdio.h>
#include<time.h>
#include <stdlib.h>
double getUnit(){
double Unit;
printf("请输入商品单价:");
scanf("%lf",&Unit);
printf("商品单价为:%f\n", Unit);
return Unit;
}
int getnumber(){
int Number;
printf("请输入商品数量:");
scanf("%d",&Number);
printf("商品数量为:%d\n", Number);
return Number;
}
int BoolLoversDay(){
time_t now = time(NULL);
struct tm *t = localtime(&now);
int month = t->tm_mon + 1;
int day = t->tm_mday;
if (month == 7 && day == 7) {
return 1;
} else {
return 0;
}
}
int BoolNationalDay(){
time_t now = time(NULL);
struct tm *t = localtime(&now);
int month = t->tm_mon + 1;
int day = t->tm_mday;
if (month == 10 && 1<= day && day <=7) {
return 1;
} else {
return 0;
}
}
int BoolAutumnDay(){
time_t now = time(NULL);
struct tm *t = localtime(&now);
int month = t->tm_mon + 1;
int day = t->tm_mday;
if (month == 8 && day == 15) {
return 1;
} else {
return 0;
}
}
int isCouple(){
int Couple;
printf("是否为情侣:");
scanf("%d",&Couple);
return Couple;
}
int main(){
srand((unsigned)time(NULL));
double Unit = getUnit();
printf("\n");
int Number = getnumber();
printf("\n");
int LoverDay = BoolLoversDay();
int NationalDay = BoolNationalDay();
int AutumnDay = BoolAutumnDay();
int Couple = isCouple();
printf("\n");
//情人节
if(LoverDay && Couple ==1 )
{
double Price = (Unit * Number)*0.77;
if(Price >= 99){
int gifts = rand()%3 + 1;
if(gifts == 1){
printf("获得精美礼品:鲜花一束!\n");
printf("总价为:%lf\n",Price);
}
else if(gifts == 2){
printf("获得精美礼品:巧克力一份!\n");
printf("总价为:%lf\n",Price);
}
else {
printf("获得精美礼品:9.9元抵扣劵一张!\n");
Price = Price - 9.9;
printf("总价为:%lf\n",Price);
}
}
else{
printf("很遗憾,未获得礼品资格:\n");
printf("总价为:%lf\n",Price);
}
}
//国庆节
else if(NationalDay){
double Price = (Unit * Number);
int Rom = rand()%10;
if(Price<100 && Rom == 0)
{
printf("随机数为:%d\n",Rom);
Price = 0;
printf("总价为:%lf\n",Price);
}
else {
printf("总价为:%lf\n",Price);
}
}
//中秋节
else if (AutumnDay) {
double Price = (Unit * Number);
if(Price>399)
{
Price = Price - 100;
printf("总价为:%lf\n",Price);
}
else {
printf("总价为:%lf\n",Price);
}
}
//其他情况
else {
double Price = (Unit * Number);
printf("总价为:%lf\n",Price);
}
return 0;
}
看着那个只属于七夕节的 gifts 变量
老过像看着自己白衬衫上的油渍一样难受
以后每次收费时都会生成一个
只有七夕节才会用到的变量
都是因为老板的需求太奇葩
才让这个程序看起来乱糟糟的
由于这个类做了修改
本来已经测试通过的代码又得重测一遍
阿对只修改了之前的LoversDayBill
//LoversDayBill
import java.util.Scanner;
import java.util.Random;
public class LoversDayBill extends Bill{
public static void discount(){
double price = Price();
if( isCouple() == 1 ){
price = price*0.77;
System.out.println("情人节有折扣!本次消费是:"+price);
if(price >= 99){
lucky();
}
}else{
System.out.println("情人节快乐!本次消费是:"+price);
}
}
public static int isCouple(){
Scanner sc = new Scanner(System.in);
System.out.print("本次购买是否为情侣:");
int Couple = sc.nextInt();
return Couple;
}
public static void lucky(){
Random lucky = new Random();
int num = lucky.nextInt(3);
if(num == 0){
System.out.println(" 获得精美礼品——鲜花一束!!!");
}
else if(num == 1){
System.out.println(" 获得精美礼品——巧克力一份!!!");
}
else{
System.out.println(" 获得精美礼品——9.9元折扣券一张!!!");
}
}
}
当老板看完老过和阿对的代码后
再次兴奋地提出新需求时
老过顿时晕了过去…
比赛真是太焦灼了
最后赢得奖励的是?