首页 > 其他 > 详细

重构,第一个案例

时间:2019-03-04 23:37:22      阅读:242      评论:0      收藏:0      [点我收藏+]

一、租赁程序

一个简单的影片租赁程序,计算每一个位顾客的消费金额并打印详单。

顾客租了哪些影片、租期多长,程序便更具租赁时间和影片类型算出费用。

影片分为三类:普通片、儿童片和新片。

除了计算费用,还要为常客计算积分,积分会根据租片种类是否为新片而不同

 

程序内容:

movie类:

技术分享图片
/* movie.h */
#ifndef MOVIE_H
#define MOVIE_H

#include <iostream>
#include <string>

class Movie
{
public:
    Movie(std::string title = "empty", int price = 0);

    int getPriceCode();
    void setPriceCode(int arg);
    std::string getTitle();

    static const int REGULAR;          //普通影片
    static const int NEW_RELEASE;      //新片
    static const int CHILDRENS;        //儿童影片
private:
    std::string _title;                 //影片名
    int _priceCode;                     //价格码
};


#endif // MOVIE_H

/* movie.cpp */
#include "movie.h"

const int REGULAR = 0;          //普通影片
const int NEW_RELEASE = 1;      //新片
const int CHILDRENS = 2;        //儿童影片

Movie::Movie(std::__cxx11::string title, int price)
    :_title(title), _priceCode(price)
{

}

int Movie::getPriceCode()
{
    return _priceCode;
}

void Movie::setPriceCode(int arg)
{
    _priceCode = arg;
}

std::__cxx11::string Movie::getTitle()
{
    return _title;
}
movie类

rental类:

技术分享图片
/* rental.h */
#ifndef RENTAL_H
#define RENTAL_H

#include "movie.h"

class Rental
{
public:
    Rental(Movie movie, int daysRented);
    int getDaysRented();
    Movie getMovie();

private:
    Movie _movie;       //租赁的影片
    int _daysRented;    //租期
};

#endif // RENTAL_H

/* rental.cpp */
#include "rental.h"

Rental::Rental(Movie movie, int daysRented)
{
    _movie = movie;
    _daysRented = daysRented;
}

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

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

customer类:

技术分享图片
/* customer.h */
#ifndef CUSTOMER_H
#define CUSTOMER_H

#include <string>
#include <iostream>
#include <vector>
#include "movie.h"
#include "rental.h"

class Customer
{
public:
    Customer(std::string name);
    void addRental(Rental arg);
    std::string getName();
    std::string statement();
    std::vector<Rental>& getRentals();

private:
    std::string _name;                  //顾客名
    std::vector<Rental> _rentals;       //租赁列表
};

#endif // CUSTOMER_H

/* customer.cpp */
#include "customer.h"

Customer::Customer(std::__cxx11::string name)
{
    _name = name;
}

void Customer::addRental(Rental arg)
{
    _rentals.push_back(arg);
}

std::__cxx11::string Customer::getName()
{
    return _name;
}

std::__cxx11::string Customer::statement()
{
    double totalAmount = 0;                 //总金额
    int frequentRenterPoints = 0;           //积分点
    
    std::string result = "Rental Record for " + getName() + "\n";
    std::vector<Rental>::iterator iter = _rentals.begin();
    for(;iter != _rentals.end();++iter) {
        double thisAmount = 0;              //当前单个租赁金额
        Rental each = *iter;

        switch(each.getMovie().getPriceCode()) {
        case 0:             //普通片,起步价为2元,租期超过2天的部分每天1.5元
            thisAmount += 2;
            if(each.getDaysRented() > 2)
                thisAmount += (each.getDaysRented() - 2) * 1.5;
            break;
        case 1:             //新片,每天3元
            thisAmount += each.getDaysRented() * 3;
            break;
        case 2:             //儿童片,起步价1.5元,租期超过3天的部分每天1.5元
            thisAmount += 1.5;
            if(each.getDaysRented() > 3)
                thisAmount += (each.getDaysRented() - 3) * 1.5;
            break;
        }
        frequentRenterPoints++;         //每借一张加1个积分点
        //积分累加条件:新版本的片子,借的时间大于1天
        if((each.getMovie().getPriceCode() == 1) && each.getDaysRented() > 1) {
            frequentRenterPoints++;
        }
        //添加详单
        result += "\t" + each.getMovie().getTitle() + "\t"
                + std::to_string(thisAmount) + "\n";
        totalAmount += thisAmount;
    }
    //添加脚注
    result += "Amount owed is " + std::to_string(totalAmount) + "\n";
    result += "You earned " + std::to_string(frequentRenterPoints) +
            " frequent renter points" +"\n";
    return result;
}

std::vector<Rental> &Customer::getRentals()
{
    return _rentals;
}
Customer类

main程序:

技术分享图片
#include <iostream>
#include <string>
#include <vector>

#include "movie.h"
#include "rental.h"
#include "customer.h"

using namespace std;

int main()
{
    /* create 10 movies */
    std::vector<Movie> movies;
    for(int i=0;i<10;i++) {
        Movie tempMovie("Movie"+std::to_string(i+1), i+1);
        movies.push_back(tempMovie);
    }

    /* create 5 customers */
    std::vector<Customer> customers;
    for(int i=0;i<5;i++) {
        Customer tempCustomers("customer" + std::to_string(i+1));
        for(int j=2*i;j<2*i+2;++j) {
            Movie tempMovie = movies[j];
            Rental tempRent(tempMovie, i+1);
            tempCustomers.addRental(tempRent);
        }

        customers.push_back(tempCustomers);
    }

    //print out all movies information;
    const std::vector<Movie>::size_type numMovies = movies.size();
    for(int i=0;i<numMovies;++i) {
        Movie tempMovie = movies[i];
        std::cout << " the Tile of the "<<i+1 << "("
                 << tempMovie.getTitle() << "," << tempMovie.getPriceCode() << ")"
                 << std::endl;
    }
    std::cout << std::endl;

    //print out all customers information
    const std::vector<Customer>::size_type numCustomers = customers.size();
    for(int i=0;i<numCustomers;++i) {
        Customer tempCust = customers[i];
        std::cout << "the " << std::to_string(i+1) << " the customer " << tempCust.getName()
                  << " has rented these movies:" << std::endl;
        const std::vector<Rental>::size_type numRentals = tempCust.getRentals().size();
        for(int j=0;j<numRentals;++j) {
            std::cout << "    (" << tempCust.getRentals()[j].getMovie().getTitle()
                      << ", " << tempCust.getRentals()[j].getDaysRented() << ")" << std::endl;
        }
    }
    std::cout << std::endl;

    for(int i=0;i<numCustomers;++i) {
        Customer tempCust = customers[i];
        std::cout << tempCust.statement() << std::endl;
    }

    return 0;
}
main程序

 

1.2 程序评价

customer里头的statement()做的事情太多了,它做了很多应该其他类做的事情。

如果需要修改输出的格式,那就需要再增加一个新的计算函数。

如果需要修改影片的分类方式,它又会影响顾客消费和常客积分。这样程序又需要更改了。

 

如果发现自己需要为程序添加一个特性,代码结构让你无法很方便地达成目的,就先重构那个程序,让代码更容易添加特性。

重构前,先检查自己是否有一套可靠的测试机制。这些测试必须可以自我检验。

 

1.3 分解和重组statement()

第一步:找出代码的逻辑泥团并运用Extract Method

然后:找出函数内的局部变量和参数

其次:找出其中的被修改的和未被修改的。

未被修改的:用作参数

修改的:用作返回值

 

重构,第一个案例

原文:https://www.cnblogs.com/ch122633/p/10474038.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!