重构 第1章 重构,第一个案例

来源:互联网 发布:录音配乐软件 编辑:程序博客网 时间:2024/04/28 23:07

本章通过1个案例,逐步的感受下重构

案例说明

这是一个非常简单的案例,展示了一个影片出租店用的程序,计算每一位顾客的消费金额并打印详单的模块,同时还需要计算每一位客人的积分。
抽象了三个实体:影片(片名、片类型)、租赁(影片、租赁天数)、顾客(姓名、租赁清单),

代码详见下面的三个类以及测试类。

customer.java

mport java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        double totalAmount = 0;        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            double thisAmount = 0;            Rental each = rentalEnumeration.nextElement();            // determine amounts for each line            switch (each.getMovie().getPriceCode()) {                case Movie.REGULAR:                    thisAmount += 2;                    if (each.getDayRented() > 2) {                        thisAmount += (each.getDayRented() - 2) * 1.5;                    }                    break;                case Movie.NEW_RELEASE:                    thisAmount += each.getDayRented() * 3;                    break;                case Movie.CHILDREN:                    thisAmount += 1.5;                    if (each.getDayRented() > 3) {                        thisAmount += (each.getDayRented() - 3) * 1.5;                    }                    break;            }            // add frequent renter points            frequentRenterPointers++;            // add bonus for two day new release rental            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDayRented() > 1) {                frequentRenterPointers++;            }            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }}
Movie.java

public class Movie {    public static final int REGULAR = 0;    public static final int NEW_RELEASE = 1;    public static final int CHILDREN = 2;    private String title;    private int priceCode;    public Movie(String title, int priceCode) {        this.title = title;        this.priceCode = priceCode;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public int getPriceCode() {        return priceCode;    }    public void setPriceCode(int priceCode) {        this.priceCode = priceCode;    }}

public class Rental {    private Movie movie;    private int dayRented;    public Movie getMovie() {        return movie;    }    public int getDayRented() {        return dayRented;    }    public Rental(Movie movie, int dayRented) {        this.movie = movie;        this.dayRented = dayRented;    }}


测试类:用于每次重构后,确认没有错误,影响原有的功能;

import org.junit.Assert;public class TestOutput {    @org.junit.Test    public void Should_get_correct_statement() {        // 三部影片        Movie movie1 = new Movie("xxxxx", Movie.NEW_RELEASE);        Movie movie2 = new Movie("AAAAA", Movie.CHILDREN);        Movie movie3 = new Movie("DDDDD", Movie.REGULAR);        //两名顾客        Customer customer1 = new Customer("H1212");        Customer customer2 = new Customer("J1212");        //顾客租约        Rental rental1 = new Rental(movie1, 10);        Rental rental2 = new Rental(movie2, 1);        Rental rental3 = new Rental(movie3, 3);        customer1.addRental(rental1);        customer1.addRental(rental2);        customer2.addRental(rental2);        customer2.addRental(rental3);        Assert.assertEquals(customer1.statement(), "Rental Records for H1212\n" +                "\txxxxx\t30.0\n" +                "\tAAAAA\t1.5\n" +                "Amount owed is 31.5\n" +                "You earned 3 frequent renter points");        Assert.assertEquals(customer2.statement(), "Rental Records for J1212\n" +                "\tAAAAA\t1.5\n" +                "\tDDDDD\t3.5\n" +                "Amount owed is 5.0\n" +                "You earned 2 frequent renter points");    }}
Customer提供了 statement 方法来输出租赁清单信息 ;

如果你发现自己需要为程序添加一个特性,而代码结构使你无法方便达成目的,那就重构那个程序,使特性的添加比较容易进行,然后再添加特性。

1 重构第一步,准备测试类

重构的第一步就是要为即将修改的代码建立一组可靠的测试环境,这些测试是必要的,避免因为重构带来新的 bug。

测试类已经在上面写好了。 

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

其中我们发现statement 方法(Long Method),需要分解长函数,把较小的代码移至更合适的地方。重构 statement 可以分以下几个步骤: 

2 提炼 Switch 语句,提炼到单独的函数中比较合适。

注意两个临时变量,thisAmount 和 each,需要处理;

任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员。 

提炼amountFor函数:
import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        double totalAmount = 0;        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            double thisAmount = 0;            Rental each = rentalEnumeration.nextElement();            thisAmount = amountFor(each);            // add frequent renter points            frequentRenterPointers++;            // add bonus for two day new release rental            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDayRented() > 1) {                frequentRenterPointers++;            }            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }    private double amountFor(Rental each) {        double thisAmount = 0;        switch (each.getMovie().getPriceCode()) {            case Movie.REGULAR:                thisAmount += 2;                if (each.getDayRented() > 2) {                    thisAmount += (each.getDayRented() - 2) * 1.5;                }                break;            case Movie.NEW_RELEASE:                thisAmount += each.getDayRented() * 3;                break;            case Movie.CHILDREN:                thisAmount += 1.5;                if (each.getDayRented() > 3) {                    thisAmount += (each.getDayRented() - 3) * 1.5;                }                break;        }        return thisAmount;    }}

修改变量名称:amountFor内的变量名称

import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        double totalAmount = 0;        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            double thisAmount = 0;            Rental each = rentalEnumeration.nextElement();            thisAmount = amountFor(each);            // add frequent renter points            frequentRenterPointers++;            // add bonus for two day new release rental            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDayRented() > 1) {                frequentRenterPointers++;            }            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }    private double amountFor(Rental aRental) {        double result = 0;        switch (aRental.getMovie().getPriceCode()) {            case Movie.REGULAR:                result += 2;                if (aRental.getDayRented() > 2) {                    result += (aRental.getDayRented() - 2) * 1.5;                }                break;            case Movie.NEW_RELEASE:                result += aRental.getDayRented() * 3;                break;            case Movie.CHILDREN:                result += 1.5;                if (aRental.getDayRented() > 3) {                    result += (aRental.getDayRented() - 3) * 1.5;                }                break;        }        return result;    }}

4 搬移金额代码:amountFor使用的更多的是来自Rental类的信息,将其移动到rental类

import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        double totalAmount = 0;        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            double thisAmount = 0;            Rental each = rentalEnumeration.nextElement();            thisAmount = amountFor(each);            // add frequent renter points            frequentRenterPointers++;            // add bonus for two day new release rental            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDayRented() > 1) {                frequentRenterPointers++;            }            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }    private double amountFor(Rental aRental) {        return aRental.getCharge();    }}public class Rental {    private Movie movie;    private int dayRented;    public Movie getMovie() {        return movie;    }    public int getDayRented() {        return dayRented;    }    public Rental(Movie movie, int dayRented) {        this.movie = movie;        this.dayRented = dayRented;    }    public double getCharge() {        double result = 0;        switch (getMovie().getPriceCode()) {            case Movie.REGULAR:                result += 2;                if (getDayRented() > 2) {                    result += (getDayRented() - 2) * 1.5;                }                break;            case Movie.NEW_RELEASE:                result += getDayRented() * 3;                break;            case Movie.CHILDREN:                result += 1.5;                if (getDayRented() > 3) {                    result += (getDayRented() - 3) * 1.5;                }                break;        }        return result;    }}

5 寻找旧函数的所有引用点,删除无用的旧函数,其实就是内联函数:cmd+option+N

import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        double totalAmount = 0;        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            double thisAmount = 0;            Rental each = rentalEnumeration.nextElement();            thisAmount = each.getCharge();            // add frequent renter points            frequentRenterPointers++;            // add bonus for two day new release rental            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDayRented() > 1) {                frequentRenterPointers++;            }            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }}

6 继续内联,删除无用的临时变量

删除无用的临时变量, thisAmount 只是接受了一下 getCharge(),后面没有作任何变化,

可以采用以查询替换变量原则去除变量 thisAmount,暂时先不讨论两次计算带来的性能开销,这个完全可以优化掉。

import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        double totalAmount = 0;        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            Rental each = rentalEnumeration.nextElement();            // add frequent renter points            frequentRenterPointers++;            // add bonus for two day new release rental            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDayRented() > 1) {                frequentRenterPointers++;            }            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }}

7 提炼”常客积分计算“代码,FrequentRenterPoint

提炼完成函数后,放入Rental类中;

import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        double totalAmount = 0;        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            Rental each = rentalEnumeration.nextElement();            frequentRenterPointers += each.getFrequentRenterPoints();            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }}public class Rental {    private Movie movie;    private int dayRented;    public Movie getMovie() {        return movie;    }    public int getDayRented() {        return dayRented;    }    public Rental(Movie movie, int dayRented) {        this.movie = movie;        this.dayRented = dayRented;    }    public double getCharge() {        double result = 0;        switch (getMovie().getPriceCode()) {            case Movie.REGULAR:                result += 2;                if (getDayRented() > 2) {                    result += (getDayRented() - 2) * 1.5;                }                break;            case Movie.NEW_RELEASE:                result += getDayRented() * 3;                break;            case Movie.CHILDREN:                result += 1.5;                if (getDayRented() > 3) {                    result += (getDayRented() - 3) * 1.5;                }                break;        }        return result;    }    int getFrequentRenterPoints() {        if ((getMovie().getPriceCode() == Movie.NEW_RELEASE) && getDayRented() > 1) {            return 2;        }        return 1;//不喜欢用else    }}

8 去除临时变量,使用查询代替

去除totalAmount和frequentRenterPointers 临时变量:
经过上述重构之后,发现临时变量依旧是一个灾难,就需要再使用用查询代替临时变量(Replace Temp With Query)的手法来清理这两个变量:
totalAmount:

import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        int frequentRenterPointers = 0;        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            Rental each = rentalEnumeration.nextElement();            frequentRenterPointers += each.getFrequentRenterPoints();            //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 " + frequentRenterPointers + " frequent renter points";        return result;    }    private double getTotalCharge() {        double result = 0;        Enumeration rentalList = rentals.elements();        while (rentalList.hasMoreElements()) {            Rental each = (Rental) rentalList.nextElement();            result += each.getCharge();        }        return result;    }}
frequentRenterPointers:

import java.util.Enumeration;import java.util.Vector;public class Customer {    private String name;    private Vector<Rental> rentals = new Vector<>();    public Customer(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void addRental(Rental rental) {        rentals.add(rental);    }    public String statement() {        Enumeration<Rental> rentalEnumeration = rentals.elements();        String result = "Rental Records for " + getName() + "\n";        while (rentalEnumeration.hasMoreElements()) {            Rental each = rentalEnumeration.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 " + getFrequentRenterPointers() + " frequent renter points";        return result;    }    private double getTotalCharge() {        double result = 0;        Enumeration rentalList = rentals.elements();        while (rentalList.hasMoreElements()) {            Rental each = (Rental) rentalList.nextElement();            result += each.getCharge();        }        return result;    }    private int getFrequentRenterPointers() {        int result = 0;        Enumeration rentalList = rentals.elements();        while (rentalList.hasMoreElements()) {            Rental each = (Rental) rentalList.nextElement();            result += each.getFrequentRenterPoints();        }        return result;    }}

9 switch语句的移动

switch应该放在正确位置:根据movie选择,所以放到movie中

最好不要在另一个对象的属性基础上运用Switch语句,如果不得不用,也应该咋对象自己的数据上使用,而不是别人的身上;

public class Movie {    public static final int REGULAR = 0;    public static final int NEW_RELEASE = 1;    public static final int CHILDREN = 2;    private String title;    private int priceCode;    public Movie(String title, int priceCode) {        this.title = title;        this.priceCode = priceCode;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public int getPriceCode() {        return priceCode;    }    public void setPriceCode(int priceCode) {        this.priceCode = priceCode;    }    public double getCharge(int dayRented) {        double result = 0;        switch (getPriceCode()) {            case Movie.REGULAR:                result += 2;                if (dayRented > 2) {                    result += (dayRented - 2) * 1.5;                }                break;            case Movie.NEW_RELEASE:                result += dayRented * 3;                break;            case Movie.CHILDREN:                result += 1.5;                if (dayRented > 3) {                    result += (dayRented - 3) * 1.5;                }                break;        }        return result;    }    public int getFrequentRenterPoints(int dayRented) {        if ((getPriceCode() == Movie.NEW_RELEASE) && dayRented > 1) {            return 2;        }        return 1;//不喜欢用else    }}public class Rental {    private Movie movie;    private int dayRented;    public Movie getMovie() {        return movie;    }    public int getDayRented() {        return dayRented;    }    public Rental(Movie movie, int dayRented) {        this.movie = movie;        this.dayRented = dayRented;    }    public double getCharge() {        return movie.getCharge(dayRented);    }    int getFrequentRenterPoints() {        return movie.getFrequentRenterPoints(dayRented);    }}


10 继承体系

创建price,分别不用类型继承;

public class Movie {    public static final int REGULAR = 0;    public static final int NEW_RELEASE = 1;    public static final int CHILDREN = 2;    private String title;    private int priceCode;    private Price price;    public Movie(String title, int priceCode) {        this.title = title;        setPriceCode(priceCode);    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public int getPriceCode() {        return price.getPriceCode();    }    public void setPriceCode(int priceCode) {        switch (priceCode) {            case REGULAR:                price = new RegularPrice();                break;            case CHILDREN:                price = new ChildrensPrice();                break;            case NEW_RELEASE:                price = new NewReleasePrice();                break;            default:                throw new IllegalArgumentException("Incorrect price code");        }    }    public double getCharge(int dayRented) {        double result = 0;        switch (getPriceCode()) {            case Movie.REGULAR:                result += 2;                if (dayRented > 2) {                    result += (dayRented - 2) * 1.5;                }                break;            case Movie.NEW_RELEASE:                result += dayRented * 3;                break;            case Movie.CHILDREN:                result += 1.5;                if (dayRented > 3) {                    result += (dayRented - 3) * 1.5;                }                break;        }        return result;    }    public int getFrequentRenterPoints(int dayRented) {        if ((getPriceCode() == Movie.NEW_RELEASE) && dayRented > 1) {            return 2;        }        return 1;//不喜欢用else    }}public abstract class Price {    abstract int getPriceCode();}class ChildrensPrice extends Price {    @Override    int getPriceCode() {        return Movie.CHILDREN;    }}class NewReleasePrice extends Price {    @Override    int getPriceCode() {        return Movie.NEW_RELEASE;    }}class RegularPrice extends Price {    @Override    int getPriceCode() {        return Movie.REGULAR;    }}

11 多态取代Switch,创建price及子类

在price类加抽象函数,并在所有子类中加上对应的具体函数;

public abstract class Price {    abstract int getPriceCode();    abstract double getCharge(int dayRenter);}class ChildrensPrice extends Price {    @Override    int getPriceCode() {        return Movie.CHILDREN;    }    @Override    double getCharge(int dayRented) {        double result = 1.5;        if (dayRented > 3) {            result += (dayRented - 3) * 1.5;        }        return result;    }}class NewReleasePrice extends Price {    @Override    int getPriceCode() {        return Movie.NEW_RELEASE;    }    @Override    double getCharge(int dayRented) {        return dayRented * 3;    }}class RegularPrice extends Price {    @Override    int getPriceCode() {        return Movie.REGULAR;    }    @Override    double getCharge(int dayRented) {        double result = 2;        if (dayRented > 2) {            result += (dayRented - 2) * 1.5;        }        return result;    }}import org.junit.Before;public class Movie {    public static final int REGULAR = 0;    public static final int NEW_RELEASE = 1;    public static final int CHILDREN = 2;    private String title;    private int priceCode;    private Price price;    public Movie(String title, int priceCode) {        this.title = title;        setPriceCode(priceCode);    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public int getPriceCode() {        return price.getPriceCode();    }    public void setPriceCode(int priceCode) {        switch (priceCode) {            case REGULAR:                price = new RegularPrice();                break;            case CHILDREN:                price = new ChildrensPrice();                break;            case NEW_RELEASE:                price = new NewReleasePrice();                break;            default:                throw new IllegalArgumentException("Incorrect price code");        }    }    public double getCharge(int dayRented) {        return price.getCharge(dayRented);    }    public int getFrequentRenterPoints(int dayRented) {        if ((getPriceCode() == Movie.NEW_RELEASE) && dayRented > 1) {            return 2;        }        return 1;//不喜欢用else    }}

12 继续修改晚上其他几个函数

public abstract class Price {    abstract int getPriceCode();    abstract double getCharge(int dayRenter);    public int getFrequentRenterPoints(int dayRented) {        return 1;    }}class ChildrensPrice extends Price {    @Override    int getPriceCode() {        return Movie.CHILDREN;    }    @Override    double getCharge(int dayRented) {        double result = 1.5;        if (dayRented > 3) {            result += (dayRented - 3) * 1.5;        }        return result;    }}class NewReleasePrice extends Price {    @Override    int getPriceCode() {        return Movie.NEW_RELEASE;    }    @Override    double getCharge(int dayRented) {        return dayRented * 3;    }    public int getFrequentRenterPoints(int dayRented) {        return (dayRented > 1) ? 2 : 1;    }}class RegularPrice extends Price {    @Override    int getPriceCode() {        return Movie.REGULAR;    }    @Override    double getCharge(int dayRented) {        double result = 2;        if (dayRented > 2) {            result += (dayRented - 2) * 1.5;        }        return result;    }}import org.junit.Before;public class Movie {    public static final int REGULAR = 0;    public static final int NEW_RELEASE = 1;    public static final int CHILDREN = 2;    private String title;    private int priceCode;    private Price price;    public Movie(String title, int priceCode) {        this.title = title;        setPriceCode(priceCode);    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public int getPriceCode() {        return price.getPriceCode();    }    public void setPriceCode(int priceCode) {        switch (priceCode) {            case REGULAR:                price = new RegularPrice();                break;            case CHILDREN:                price = new ChildrensPrice();                break;            case NEW_RELEASE:                price = new NewReleasePrice();                break;            default:                throw new IllegalArgumentException("Incorrect price code");        }    }    public double getCharge(int dayRented) {        return price.getCharge(dayRented);    }    public int getFrequentRenterPoints(int dayRented) {        return price.getFrequentRenterPoints(dayRented);    }}

0 0