设计模式(3)-策略模式(Strategy) (三)

2014-11-24 11:48:37 · 作者: · 浏览: 4
if(daysRented>2)
{
result += (daysRented-2)*1.5;
}
break;
case NEW_RELEASE:
result += daysRented*3;
break;
case DISCOUNT:
result +=2;
if(daysRented>2)
{
result += (daysRented-2)*1;
}
break;
}
qDebug()< return result;
}
#include
#include "rental.h"

Rental::Rental(Movie movie, int daysRented)
{
qDebug()<<"construct Rental";
_movie = movie;
_daysRented = daysRented;
}

Movie Rental::getMovie()
{
return _movie;
}

int Rental::getDaysRented()
{
return _daysRented;
}

double Rental::getCharge(int daysRented)
{
double result = 0;
qDebug()< switch(getMovie().getPriceCode())
{
case REGULAR:
result +=2;
if(daysRented>2)
{
result += (daysRented-2)*1.5;
}
break;
case NEW_RELEASE:
result += daysRented*3;
break;
case DISCOUNT:
result +=2;
if(daysRented>2)
{
result += (daysRented-2)*1;
}
break;
}
qDebug()< return result;
}

main.cpp

[html]
#include "movie.h"
#include "rental.h"

int main()
{
int daysRented = 30;
Movie movie("Book1",NEW_RELEASE);
Rental rental(movie,daysRented);
movie.setPriceCode(NEW_RELEASE);
rental.getCharge(daysRented);
return 0;
}
#include "movie.h"
#include "rental.h"

int main()
{
int daysRented = 30;
Movie movie("Book1",NEW_RELEASE);
Rental rental(movie,daysRented);
movie.setPriceCode(NEW_RELEASE);
rental.getCharge(daysRented);
return 0;
}

运行结果如下:

[html]
"construct Movie::Movie(Book1,1)"
construct Movie::Movie()
construct Rental
1
90
"construct Movie::Movie(Book1,1)"
construct Movie::Movie()
construct Rental
1
90
示例调用了getCharge,并返回了priceCode相应的计价。相对于《重构》一书最原始代码,这段代码经过了一定的重构处理。

先看下述代码,

[html]
double Rental::getCharge(int daysRented)
{
double result = 0;
qDebug()< switch(getMovie().getPriceCode())
{
case REGULAR:
result +=2;
if(daysRented>2)
{
result += (daysRented-2)*1.5;
}
break;
case NEW_RELEASE:
result += daysRented*3;
break;
case DISCOUNT:
result +=2;
if(daysRented>2)
{
result += (daysRented-2)*1;
}
break;
}
qDebug()< return result;
}
double Rental::getCharge(int daysRented)
{
double result = 0;
qDebug()< switch(getMovie().getPriceCode())
{
case REGULAR:
result +=2;
if(daysRented>2)
{
result += (daysRented-2)*1.5;
}
break;
case NEW_RELEASE:
result += daysRented*3;
break;
case DISCOUNT:
result +=2;
if(daysRented>2)
{
result += (daysRented-2)*1;
}
break;
}
qDebug()< return result;
}
这段代码,有一些不好的地方:

(1) 这段代码通过priceCode判断电影的租金,采用了switch-case语言,实质上还是面向过程的范畴,代码可重用性很低;

(2) 如果情形较多,switch-case会变得十分庞大。

有什么办法能去掉switch-case吗?下面通过引入策略模式实现这一目的。

先看UML图,

图2

(1) 引入了一个Price基类,提供了getCharge()接口供子类实现;

(2) 将switch-case语句中的3种情形抽取为3个Price子类;

(3) Movie调用了Price提供的接口。

【代码清单】

price.h

[html]
#ifndef PRICE_H
#define PRICE_H

class Price
{
public:
Price();

private:
int _priceCode;

public:
int getPriceCode();