• 《重构 改善既有代码的设计》读书笔记1


    首先我们看重构之前的,共有三个类,Customer,Movie,Rental。全都是自己写的数据类。

    // Rental: 表示某个顾客租了一部影片
    public class Rental
    {
    private Movie _movie;
    private int _daysRented;

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

    public int getDaysRented()
    {
    return _daysRented;
    }

    public Movie getMovie()
    {
    return _movie;
    }
    }
    // Movie: 纯数据类,代表一个影片
    public class Movie
    {
    public static final int CHILDRENS = 2;
    public static final int REGULAR = 0;
    public static final int NEW_RELEASE = 1;

    private String _title;
    private int _priceCode;

    public Movie(String title, int priceCode)
    {
    _title = title;
    _priceCode = priceCode;
    }

    public int getPriceCode()
    {
    return _priceCode;
    }

    public void setPriceCode(int priceCode)
    {
    _priceCode = priceCode;
    }

    public String getTitle()
    {
    return _title;
    }
    }
    // Customer: 顾客
    public class Customer
    {
    private String _name;
    private Vector<Rental> _rentals = new Vector<Rental>();

    public Customer(String name)
    {
    _name = name;
    }

    public void addRental(Rental rental)
    {
    _rentals.add(rental);
    }

    public String getName()
    {
    return _name;
    }

    public String statement()
    {
    double totalAmount = 0;
    int frequentRenterPoints = 0;

    Enumeration<Rental> rentals = _rentals.elements();

    String result = "Rental record for " + getName() + "\n";

    while(rentals.hasMoreElements())
    {
    double thisAmount = 0;
    Rental each = rentals.nextElement();

    // determine amounts for each line
    switch(each.getMovie().getPriceCode())
    {
    case Movie.REGULAR:
    thisAmount += 2;
    if(each.getDaysRented() > 2)
    {
    thisAmount += (each.getDaysRented() - 2) * 1.5;
    }
    break;

    case Movie.NEW_RELEASE:
    thisAmount += each.getDaysRented() * 3;
    break;

    case Movie.CHILDRENS:
    thisAmount += 1.5;
    if(each.getDaysRented() > 3)
    {
    thisAmount += (each.getDaysRented() - 3) * 1.5;
    }
    break;
    }

    // add frequent renter points
    frequentRenterPoints++;
    // add bonus for a two day new release rental
    if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE)
    && each.getDaysRented() > 1)
    {
    frequentRenterPoints++;
    }

    // show figures for this rental
    result += "\t" + each.getMovie().getTitle() + "\t"
    + thisAmount + "\n";
    totalAmount += thisAmount;
    }

    // add footer lines
    result += "Amount owed is" + totalAmount + "\n";
    result += "You earned " + frequentRenterPoints + "frequent renter points";
    return result;
    }
    }

    我们可以看到,Customer中的statement()函数过于复杂,这时我们就开始想要重构了。

    首先我们看到,很明显的就是statement()中的switch语句,我们应该把它放到单独的一个函数中,所以我们要对switch处进行重构。

    第一次重构:提取函数后的Customer类

    // Customer: 顾客
    public class Customer
    {
    private String _name;
    private Vector<Rental> _rentals = new Vector<Rental>();

    public Customer(String name)
    {
    _name = name;
    }

    public void addRental(Rental rental)
    {
    _rentals.add(rental);
    }

    public String getName()
    {
    return _name;
    }

    public String statement()
    {
    double totalAmount = 0;
    int frequentRenterPoints = 0;

    Enumeration<Rental> rentals = _rentals.elements();

    String result = "Rental record for " + getName() + "\n";

    while(rentals.hasMoreElements())
    {
    double thisAmount = 0;
    Rental each = rentals.nextElement();

    thisAmount += amountFor(each);

    // add frequent renter points
    frequentRenterPoints++;
    // add bonus for a two day new release rental
    if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE)
    && each.getDaysRented() > 1)
    {
    frequentRenterPoints++;
    }

    // show figures for this rental
    result += "\t" + each.getMovie().getTitle() + "\t"
    + thisAmount + "\n";
    totalAmount += thisAmount;
    }

    // add footer lines
    result += "Amount owed is" + totalAmount + "\n";
    result += "You earned " + frequentRenterPoints + "frequent renter points";
    return result;
    }

    private double amountFor(Rental each)
    {
    double thisAmount = 0;
    // determine amounts for each line
    switch(each.getMovie().getPriceCode())
    {
    case Movie.REGULAR:
    thisAmount += 2;
    if(each.getDaysRented() > 2)
    {
    thisAmount += (each.getDaysRented() - 2) * 1.5;
    }
    break;

    case Movie.NEW_RELEASE:
    thisAmount += each.getDaysRented() * 3;
    break;

    case Movie.CHILDRENS:
    thisAmount += 1.5;
    if(each.getDaysRented() > 3)
    {
    thisAmount += (each.getDaysRented() - 3) * 1.5;
    }
    break;
    }

    return thisAmount;
    }
    }

    之后我们会发现amountFor()中的一些变量的名字不是很好,所以我们进行重命名

        private double amountFor(Rental aRental)
    {
    double result = 0;
    // determine amounts for each line
    switch(aRental.getMovie().getPriceCode())
    {
    case Movie.REGULAR:
    result += 2;
    if(aRental.getDaysRented() > 2)
    {
    result += (aRental.getDaysRented() - 2) * 1.5;
    }
    break;

    case Movie.NEW_RELEASE:
    result += aRental.getDaysRented() * 3;
    break;

    case Movie.CHILDRENS:
    result += 1.5;
    if(aRental.getDaysRented() > 3)
    {
    result += (aRental.getDaysRented() - 3) * 1.5;
    }
    break;
    }

    return result;
    }

    之后我们发现,amountFor()在Customer类中,可是却没有使用来自Customer类的信息,而是使用了来自Rental类的信息,所以我们需要考虑将amountFor()搬移到Rental类中

    在这里我们同时改了一下函数名:amountFor() -> getCharge()

    新的Rental:

    // Rental: 表示某个顾客租了一部影片
    public class Rental
    {
    private Movie _movie;
    private int _daysRented;

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

    public int getDaysRented()
    {
    return _daysRented;
    }

    public Movie getMovie()
    {
    return _movie;
    }

    public double getCharge()
    {
    double result = 0;
    // determine amounts for each line
    switch(getMovie().getPriceCode())
    {
    case Movie.REGULAR:
    result += 2;
    if(getDaysRented() > 2)
    {
    result += (getDaysRented() - 2) * 1.5;
    }
    break;

    case Movie.NEW_RELEASE:
    result += getDaysRented() * 3;
    break;

    case Movie.CHILDRENS:
    result += 1.5;
    if(getDaysRented() > 3)
    {
    result += (getDaysRented() - 3) * 1.5;
    }
    break;
    }

    return result;
    }
    }

    新的Customer中的statement:

    public String statement()
    {
    double totalAmount = 0;
    int frequentRenterPoints = 0;

    Enumeration<Rental> rentals = _rentals.elements();

    String result = "Rental record for " + getName() + "\n";

    while(rentals.hasMoreElements())
    {
    double thisAmount = 0;
    Rental each = rentals.nextElement();

    thisAmount += each.getCharge();

    // add frequent renter points
    frequentRenterPoints++;
    // add bonus for a two day new release rental
    if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE)
    && each.getDaysRented() > 1)
    {
    frequentRenterPoints++;
    }

    // show figures for this rental
    result += "\t" + each.getMovie().getTitle() + "\t"
    + thisAmount + "\n";
    totalAmount += thisAmount;
    }

    // add footer lines
    result += "Amount owed is" + totalAmount + "\n";
    result += "You earned " + frequentRenterPoints + "frequent renter points";
    return result;
    }

    之后我们发现,stateme()中的thisAmount显得有点多余了,接受each.getCharge()的执行结果,然后就不会有任何修改,所以我们运用Replace Temp With Query把thisAmount去掉

    新的statement():

    public String statement()
    {
    double totalAmount = 0;
    int frequentRenterPoints = 0;

    Enumeration<Rental> rentals = _rentals.elements();

    String result = "Rental record for " + getName() + "\n";

    while(rentals.hasMoreElements())
    {
    Rental each = rentals.nextElement();

    // add frequent renter points
    frequentRenterPoints++;
    // add bonus for a two day new release rental
    if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE)
    && each.getDaysRented() > 1)
    {
    frequentRenterPoints++;
    }

    // show figures for this rental
    result += "\t" + each.getMovie().getTitle() + "\t"
    + each.getCharge() + "\n";
    totalAmount += each.getCharge();
    }

    // add footer lines
    result += "Amount owed is" + totalAmount + "\n";
    result += "You earned " + frequentRenterPoints + "frequent renter points";
    return result;
    }

    下一步对“常客积分计算”做类似的处理,积分的计算视影片的种类而有所不同不过不像收费规则(getCharge())有那么多变化,我们将常客积分计算的任务交给Rental:

    Rental中新增加的函数:

        public int getFrequentRentalPoints()
    {
    int frequentRenterPoints = 0;
    frequentRenterPoints++;
    if(getMovie().getPriceCode() == Movie.NEW_RELEASE
    && getDaysRented() > 1)
    {
    frequentRenterPoints++;
    }

    return frequentRenterPoints;
    }

    Customer的statement函数:

    public String statement()
    {
    double totalAmount = 0;
    int frequentRenterPoints = 0;

    Enumeration<Rental> rentals = _rentals.elements();

    String result = "Rental record for " + getName() + "\n";

    while(rentals.hasMoreElements())
    {
    Rental each = rentals.nextElement();

    frequentRenterPoints += each.getFrequentRentalPoints();

    // show figures for this rental
    result += "\t" + each.getMovie().getTitle() + "\t"
    + each.getCharge() + "\n";
    totalAmount += each.getCharge();
    }

    // add footer lines
    result += "Amount owed is" + totalAmount + "\n";
    result += "You earned " + frequentRenterPoints + "frequent renter points";
    return result;
    }

    之后我们需要去除临时变量:

    Customer中的statement函数以及新增加的getTotalCharge和getTotalFrequentRenterPoints函数

        public String statement()
    {
    Enumeration<Rental> rentals = _rentals.elements();

    String result = "Rental record for " + getName() + "\n";

    while(rentals.hasMoreElements())
    {
    Rental each = rentals.nextElement();

    // show figures for this rental
    result += "\t" + each.getMovie().getTitle() + "\t"
    + each.getCharge() + "\n";
    }

    // add footer lines
    result += "Amount owed is" + getTotalCharge() + "\n";
    result += "You earned " + getTotalFrequentRenterPoints() + "frequent renter points";
    return result;
    }

    private int getTotalFrequentRenterPoints()
    {
    int result = 0;
    for(int n=0; n<_rentals.size(); n++)
    {
    result += _rentals.get(n).getFrequentRentalPoints();
    }
    return result;
    }

    private double getTotalCharge()
    {
    double result = 0;
    for(int n=0; n<_rentals.size(); n++)
    {
    result += _rentals.get(n).getCharge();
    }

    return result;
    }
  • 相关阅读:
    斯皮尔曼+假设检验
    53. Maximum Subarray
    工具网站
    Win10 不稳定经常死机 -蓝屏-电脑-电脑 系统启动后 键盘等一会才有反应
    MFC 代码无错却无法运行
    为什么喝酒不能吃头孢
    基于靶机的SQL注入的探测
    SQlMap注入的基本原理
    burp suite 简单靶机验证码绕过【前台|后台验证】自娱自乐系列
    burp suite 基于自娱自乐的靶机简单密码爆破
  • 原文地址:https://www.cnblogs.com/xiaobo68688/p/2316266.html
Copyright © 2020-2023  润新知