第1章 重构,第一个案例(1):糟糕的statement函数设计
1. 启航:影片出租,计算每一位顾客的消费金额并打印清单
1.1 场景说明:
(1)影片分类规则:普通片、儿童片和新片等3类
(2)每种影片计算租金的方式。
①普通片:基本租金为2元,超过2天的部分每天加1.5元
②新片:租期*3元
③儿童片:基本租金为1.5元,超过3天的部分每天加1.5元
(3)积分的计算:每借1片,积分加1,如果是新片且租期1天以上的额外赠送1分。
【实例分析】影片出租

//第1章:重构,第1个案例
//场景:影片出租,计算每一位顾客的消费金额
/*
说明:
1. 影片分3类:普通片、儿童片和新片。
2. 每种影片计算租金的方式。
A.普通片:基本租金为2元,超过2天的部分每天加1.5元
B.新片:租期*3
C.儿童片:基本租金为1.5元,超过3天的部分每天加1.5元
3. 积分的计算:每借1片,积分加1,如果是新片且租期1天以上的额外赠送1分。
*/
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std; //影片类(只是一个简单的纯数据类)
class Movie
{
private:
string title; //片名
int pricecode; //价格 public:
static const int CHILDRENS = ; //儿童片
static const int REGULAR = ; //普通片
static const int NEW_RELEASE = ;//新片 Movie(string title, int priceCode)
{
this->title = title;
this->pricecode = priceCode;
} string getTitle(){return title;}
void setTitle(string value)
{
title = value;
} int getPriceCode(){return pricecode;}
void setPriceCode(int value)
{
this->pricecode = value;
}
}; //租赁类(表示某个顾客租了一部影片)
class Rental
{
private:
Movie& movie; //所租的影片
int daysRented; //租期
public:
Rental(Movie& movie, int daysRented):movie(movie)
{
this->daysRented = daysRented;
} int getDaysRented(){return daysRented;} Movie& getMovie()
{
return movie;
}
}; //顾客类(用来表示顾客)
class Customer
{
private:
string name; //顾客姓名
vector<Rental*> rentals; //每个租赁记录
public:
Customer(string name)
{
this->name = name;
} void addRental(Rental* value)
{
rentals.push_back(value);
} string getName(){return name;} //statement(报表),生成租赁的详单
string statement()
{
string ret = "Rental Record for " + name + "\n";
double totalAmount = ; //总租金额
int frequentReterPoints = ; //常客积分 vector<Rental*>::iterator iter = rentals.begin();
while( iter != rentals.end())
{
double thisAmount = ; //每片需要的租金
Rental& each = *(*iter); int priceCode = (each.getMovie()).getPriceCode();
switch(priceCode)
{
case Movie::REGULAR:
thisAmount += ; //普通片基本租金为2元
if(each.getDaysRented() > ) //超过2天的每天加1.5元
thisAmount +=(each.getDaysRented() - ) * 1.5;
break;
case Movie::NEW_RELEASE:
thisAmount += each.getDaysRented() * ; //新片的租金
break;
case Movie::CHILDRENS:
thisAmount += 1.5; //儿童片基本租金为1.5元
if(each.getDaysRented() > ) //超过3天的每天加1.5元
thisAmount +=(each.getDaysRented() - ) * 1.5;
break;
} //常客积分
++frequentReterPoints; //如果是新片且租期超过1天以上,则额外送1分积分
if ((each.getMovie().getPriceCode() == Movie::NEW_RELEASE) &&
each.getDaysRented() > ) ++frequentReterPoints; //显示每个租赁记录
ostringstream oss;
oss << thisAmount;
ret += "\t" + each.getMovie().getTitle() + "\t" +
oss.str()+ "\n"; totalAmount +=thisAmount; ++iter;
} //增加页脚注释
ostringstream oss;
oss << totalAmount;
ret += "Amount owed is " + oss.str() + "\n"; oss.str("");
oss << frequentReterPoints;
ret += "You earned " + oss.str() +"\n";
return ret;
}
}; void init(Customer& customer)
{
Movie* mv = new Movie("倚天屠龙记",Movie::REGULAR);
Rental* rt = new Rental(*mv, );
customer.addRental(rt); mv = new Movie("新水浒传",Movie::NEW_RELEASE);
rt = new Rental(*mv, );
customer.addRental(rt); mv = new Movie("喜羊羊与灰太狼",Movie::CHILDRENS);
rt = new Rental(*mv, );
customer.addRental(rt);
} int main()
{
Customer customer("SantaClaus");
init(customer); cout << customer.statement() <<endl; return ;
}
/*输出结果
Rental Record for SantaClaus
倚天屠龙记 2
新水浒传 9
喜羊羊与灰太狼 4.5
Amount owed is 15.5
You earned 4
*/
1.2 存在问题
(1)报表函数(statement)太长,它做了很多原来应该由其他类完成的事情。
(2)当希望以HTML格式输出报表时,不能复用statement的任何代码,只能重新编写一个新的htmlStatement函数,然后statement复制一份并做修改。
(3)此时,如果计费标准也发生变化,必须同时修改statement和htmlStatement函数,并确保两处修改的一致性。
(4)如果用户希望改变影片分类规则,并设想了几种方案,这些方案会影响到顾客消费和常客积分的计算方式。则必须对statement做出修改。
第1章 重构,第一个案例(1):糟糕的statement函数设计的更多相关文章
- ruby代码重构第一课
(文章是从我的个人主页上粘贴过来的, 大家也可以访问我的主页 www.iwangzheng.com) 新手写代码的时候往往会出现很多重复的代码没有提取出来,大师高瞻远瞩总能提点很多有意义的改进,今天重 ...
- 学习ExtjsForVs(第一个案例HelloWord)
第一个案例-Hello Word 1.本次练习以ext-4.0.7为例,首先从网上下载ext包. 2.打开包后将里面的三个文件或文件夹拷贝到项目中. resource文件夹 bootstrap.js ...
- spring boot实战(第一篇)第一个案例
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] spring boot实战(第一篇)第一个案例 前言 写在前面的话 一直想将spring boot相关内容写成一个系列的 ...
- 第4章 TCP/IP通信案例:访问Internet上的Web服务器
第4章 TCP/IP通信案例:访问Internet上的Web服务器 4.2 部署代理服务器 书中为了演示访问Internet上的Web服务器的全过程,使用了squid代理服务器程序模拟了一个代理服务器 ...
- (转)编写Spring的第一个案例并测试Spring的开发环境
http://blog.csdn.net/yerenyuan_pku/article/details/52832145 Spring4.2.5的开发环境搭建好了之后,我们来编写Spring的第一个案例 ...
- javascript进阶教程第三章--匿名和闭包--案例实战
javascript进阶教程第三章--匿名和闭包--案例实战 一.学习任务 通过几个小练习回顾学过的知识点 二.实例 练习1: 实例描述:打开页面后规定时间内弹出一个新窗口,新窗口指定时间后自动关闭. ...
- Java生鲜电商平台-一次代码重构的实战案例
Java生鲜电商平台-一次代码重构的实战案例 说明,Java开源生鲜电商平台-一次代码重构的实战案例,根据实际的例子,分析出重构与抽象,使代码更加的健壮与高效. 1.业务说明 系统原先已有登录功能,我 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引 代码工程地址: https://g ...
- 第3章 文件I/O(8)_贯穿案例:构建标准IO函数库
9. 贯穿案例:构建标准IO函数库 //mstdio.h #ifndef __MSTDIO_H__ #define __MSTDIO_H__ #include <unistd.h> #de ...
随机推荐
- java web学习总结(七) -------------------HttpServletResponse对象(一)
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应,那我们要 ...
- Hadoop2.6.0安装—单机/伪分布
目录 环境准备 创建hadoop用户 更新apt 配置SSH免密登陆 安装配置Java环境 安装Hadoop Hadoop单机/伪分布配置 单机Hadoop 伪分布Hadoop 启动Hadoop 停止 ...
- Javaweb学习笔记——上传下载文件
一.前言 在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为comm ...
- 关于图片的PNG与JPG、JIF格式
一:GIF(Graphics Interchange Format) 简介 GIF图形交换格式是一种位图图形文件格式,以8位色(即256种颜色)重现真彩色的图像. 它实际上是一种压缩文档,采用LZW压 ...
- Android-配置文件中设置“android:clickable="false"无效的原因及解决办法
开发中遇到的问题:要实现一个button初始为不可点击,于是在配置文件中设置了android:clickable="false"运行后发现还是可以点击,于是写在了Activity中 ...
- .net 配置文件设计工具 Configuration Section Designer
Configuration Section Designer 简称 CSD 下载及英文介绍地址点击我 以下为简单使用说明 选择自己需要的版本安装好该设计插件之后重启vs 新建选择 在工具栏里选择想使用 ...
- React Native知识7-TabBarIOS组件
一:简介 两个TabBarIOS和TabBarIOS.Item组件可以实现页面Tab切换的功能,Tab页面切换的架构在应用开发中还是非常常见的.如:腾讯QQ,淘宝,美团外卖等等 二:TabBarIOS ...
- 数据结构->冒泡排序
数据结构->冒泡排序 实现效果 从小到大排序 算法原理 重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到不再需要交换,也就是说该数列 ...
- iOS开发之Bug--UITextField使用时文字向下偏移问题
这个问题,在之前项目中偶然遇到过,但是bug不明显,也不知道具体是哪种重现方式重现的,所以一直暂时略过了,但是随着项目的系统的规模变大,代码量越多, 这个问题出现的越来越明显了. 于是就只能靠百度和g ...
- [转载]Linux Bond的原理及其不足
本文转自http://www.yunweipai.com/archives/1969.html 支持原创.尊重原创,分享知识! 在企业及电信Linux服务器环境上,网络配置都会使用Bonding技术做 ...