要点:最好不要在另一个对象的属性基础上运用条件分支语句,如果不得不使用,也应该在对象自己的数据上使用。
方法:getCharge() 和 getFrequentRenterPoints()移动到Movie类中去。
在运用继承重构代码之前 rental & movie 代码如下:
rental.h:
#ifndef RENTAL_H
#define RENTAL_H
#include "movie.h"
class Rental
{
public:
Rental(Movie movie, int daysRented);
double getCharge();
int getDaysRented();
Movie getMovie();
int getFrequentRenterPoints();
private:
Movie _movie;
int _daysRented;
};
#endif //RENTAL_H
rental.cpp:
#include "rental.h"
Rental::Rental(Movie movie, int daysRented)
{
_movie = movie;
_daysRented = daysRented;
}
double Rental::getCharge()
{
return _movie.getCharge(_daysRented);
}
int Rental::getDaysRented()
{
return _daysRented;
}
Movie Rental::getMovie()
{
return _movie;
}
int Rental::getFrequentRenterPoints()
{
return _movie.getFrequentRenterPoints(_daysRented);
}
movie.h:
#ifndef MOVIE_H
#define MOVIE_H
#include <string>
using std::string;
class Movie
{
public:
Movie(string title = "empty", int priceCode = 0);
double getCharge(int daysRented);
int getFrequentRenterPoints(int daysRented);
int getPriceCode();
void setPriceCode(int arg);
string getTitle();
public:
static const int REGULAR;
static const int NEW_RELEASE;
static const int CHILDRENS;
private:
string _title;
int _priceCode;
};
#endif //MOVIE_H
movie.cpp:
#include "movie.h"
const int Movie::REGULAR = 0;
const int Movie::NEW_RELEASE = 1;
const int Movie::CHILDRENS = 2;
Movie::Movie(string title , int priceCode)
{
_title = title;
_priceCode = priceCode;
}
double Movie::getCharge(int daysRented)
{
double result = 0;
// determine amounts for each line
switch(getPriceCode())
{
case REGULAR:
result += 2;
if (daysRented > 2)
{
result += (daysRented - 2) * 1.5;
}
break;
case NEW_RELEASE:
result += daysRented * 3;
break;
case CHILDRENS:
result += 1.5;
if (daysRented > 3)
{
result += (daysRented - 3) * 1.5;
}
break;
}
return result;
}
int Movie::getFrequentRenterPoints(int daysRented)
{
// add bonus for a two day new release rental
if ((getPriceCode() == NEW_RELEASE) && daysRented > 1)
return 2;
else
return 1;
}
int Movie::getPriceCode()
{
return _priceCode;
}
void Movie::setPriceCode(int arg)
{
_priceCode = arg;
}
string Movie::getTitle()
{
return _title;
}