java多态替换switch_第1章 重构,第一个案例(3):运用多态取代switch

3.运用多态取代与价格相关的条件逻辑

3.1 switch和“常客积分”代码的再次搬迁

(1)switch:最好不要在另一个对象的属性上运用switch语句

switch(getMovie().getPriceCode()) //在movie对象的priceCode属性上运用switch

{ //这意味着可以将getCharge函数从Rental类移动到Movie类去//选择在Movie类中封装计算费用功能,还有一个//原因,就是可以控制因影片类型变化导致的计算//方式变化,从而对其它对象产生影响。

}

(2)常客积分:getFrequentRenterPoints函数的再次搬迁。用跟处理getCharge相同的手法处理常客积分,将因影片类型变化而变化的所有东西都放到Movie类中去处理。Rental类中只需调用Movie相应的方法即可。

【实例分析】影片出租1.3.1

608c7415fd1cbf378c7b5335132cfcb5.png

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//第1章:重构,第1个案例//场景:影片出租,计算每一位顾客的消费金额/*说明:

1. 影片分3类:普通片、儿童片和新片。

2. 每种影片计算租金的方式。

A.普通片:基本租金为2元,超过2天的部分每天加1.5元

B.新片:租期*3

C.儿童片:基本租金为1.5元,超过3天的部分每天加1.5元

3. 积分的计算:每借1片,积分加1,如果是新片且租期1天以上的额外赠送1分。*/#include#include#include#include

using namespacestd;//影片类

classMovie

{private:string title; //片名

int priceCode; //价格

public:enumMovieType{

REGULAR= 0, //普通片

NEW_RELEASE, //新片

CHILDRENS //儿童片

};

Movie(string title, intpriceCode)

{this->title =title;this->priceCode =priceCode;

}string getTitle(){returntitle;}void setTitle(stringvalue)

{

title=value;

}int getPriceCode(){returnpriceCode;}void setPriceCode(intvalue)

{this->priceCode =value;

}//将原来Rental类中的getCharge移到该类中,并将租期作为参数传入//搬到这里来的原因是//1.switch语句中getPriceCode为本类对象的属性//2.封装影片类型的变化导致计算方式变化于该类中,从而降低对其他类的影响

double getCharge(intdaysRented)

{double result = 0 ;//相当于statement中的thisamount;

switch(getPriceCode())

{caseMovie::REGULAR:

result+= 2; //普通片基本租金为2元

if(daysRented > 2) //超过2天的每天加1.5元

result +=(daysRented - 2 ) * 1.5;break;caseMovie::NEW_RELEASE:

result+= daysRented * 3; //新片的租金

break;caseMovie::CHILDRENS:

result+= 1.5; //儿童片基本租金为1.5元

if(daysRented > 3) //超过3天的每天加1.5元

result +=(daysRented - 3 ) * 1.5;break;

}returnresult;

}//将原Rental类中常客积分搬到该类中//原因是常客积分的计费方式与影片类型有关,也是为了控制当//影片类型变化时,由于计算方式变化对其他类的影响

int getFrequentRenterPoints(intdaysRented)

{//如果是新片且租期超过1天以上,则额外送1分积分

if ((getPriceCode() == Movie::NEW_RELEASE) &&daysRented> 1 ) return 2;else return 1;

}

};//租赁类(表示某个顾客租了一部影片)

classRental

{private:

Movie& movie; //所租的影片

int daysRented; //租期

public:

Rental(Movie& movie, intdaysRented):movie(movie)

{this->daysRented =daysRented;

}int getDaysRented(){returndaysRented;}

Movie&getMovie()

{returnmovie;

}doublegetCharge()

{returnmovie.getCharge(daysRented);

}//将原Customer类的statement中计算常客积分的代码移到Rental类

intgetFrequentRenterPoints()

{returnmovie.getFrequentRenterPoints(daysRented);

}

};//顾客类(用来表示顾客)

classCustomer

{private:string name; //顾客姓名

vector rentals; //每个租赁记录//获得总消费

doublegetTotalCharge()

{double result = 0;

vector::iterator iter =rentals.begin();while( iter !=rentals.end())

{

Rental& each = *(*iter);

result+=each.getCharge();++iter;

}returnresult;

}//获得总积分

intgetTotalFrequentRenterPointers()

{int result = 0;

vector::iterator iter =rentals.begin();while( iter !=rentals.end())

{

Rental& each = *(*iter);

result+=each.getFrequentRenterPoints();++iter;

}returnresult;

}voidcleanUp()

{

vector::iterator iter =rentals.begin();while( iter !=rentals.end())

{delete(*iter);++iter;

}

rentals.clear();

}

template

stringnumToString(T num)

{

stringstream ss;

ss<

}public:

Customer(stringname)

{this->name =name;

}void addRental(Rental*value)

{

rentals.push_back(value);

}string getName(){returnname;}//statement(报表),生成租赁的详单

stringstatement()

{string ret = "Rental Record for" + name + "\n";</

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值