重构修练笔记 Refactoring Xiu Lian Notes (1) - 练气期

笔记纯属虚构,如有雷同,纯属巧合

        万物皆有定数,普通人入门练气期一味求快,只满足身体自身需求,对于后面更高层级没有远见,导致后面越修炼越难,极其不便和难受,从而有人直接崩盘而道陨神消。需要一种新的方法打通经络,别人修仙那格局还是小了,咱们直接修神,练就大神通。本道法旨在带你走向新的修炼道路,本法为重构道法,护道人为可靠的测试自我检测能力。

提供一个简单的 练气期案例- 租借影片 参考本法能力

电影类

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) {
        this._title = _title;
        this._priceCode = _priceCode;
    }

    public int getPriceCode() {
        return _priceCode;
    }

    public void setPriceCode(int _priceCode) {
        this._priceCode = _priceCode;
    }

    public String getTitle() {
        return _title;
    }
}

租借类

public class Rental {

    private Movie _movie;
    private int _dayRented;

    public Movie getMovie() {
        return _movie;
    }

    public int getDaysRented() {
        return _dayRented;
    }
}

客户类

public class Customer {

    private String _name;
    private Vector _rentals = new Vector();

    public Customer(String _name) {
        this._name = _name;
    }

    public void addRental(Rental arg){
        _rentals.addElement(arg);
    }

    public String getName() {
        return _name;
    }

    public String statement(){
        double totalAmount = 0;
        int freguentRenterPoints =0;
        Enumeration rentals = _rentals.elements();
        String result = "Rental Record for "+getName()+"\n";
        while (rentals.hasMoreElements()){
            double thisAmount= 0;
            Rental each = (Rental) rentals.nextElement();

            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:
                    if (each.getDaysRented() > 2){
                        thisAmount += (each.getDaysRented() - 3) * 1.5;
                    }
                    break;
            }

            freguentRenterPoints++;

            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE)
                    &&each.getDaysRented() > 1){
                freguentRenterPoints ++;
            }

            result+="\t"+each.getMovie().getTitle()+"\t"+
            String.valueOf(thisAmount)+"\n";
            totalAmount+=thisAmount;
        }

        result+="Amount owed is"+String.valueOf(totalAmount)+"\n";
        result+="You earned "+String.valueOf(freguentRenterPoints)+" frequent renter points";
        return result;
    }

}

上面提供了三个类

        这是一个基础的客人租借电影的功能案例,租借的价格类型有儿童、常规、新发布的所对应的价格和积分会不一样,而本方法直接三种主要变化信息揉在一起,短期看是没有任何问题,但是长此以往,会产生新的问题,如新类型和新的计算方式等,最主要的是可读性很差,应该减赋,提供更为畅心的方式编写我们的代码

改造如下

V1 提炼基础的能力 - 划分到对应的功能

1.将statement的计算积分方法和计算租借金额方法放到租借里面,可以更为方便通过电影类型来识别计算方式,为了取值更为方便

2.抽离总费用的计算总和和总积分数,剥离单个 - 总计的能力划分

效果:消除了冗长的代码,但是入口方法更为精炼,可读性也有所提高,但是原本的动态字段依然存在,只是剥离到其他类中

V2 改造动态数据能力- 运用GOF神的State模式实现动态业务的抽离控制

1.将方案1中的电影价格类型的计算积分方法和计算租借金额方法,下沉到电影类中(Movie),更为方便的组合需要的价格类型和新价格类型的拓展

2.电影模块补充价格类型字段,补充两种能力如下,同步修改总计的方式

        a.计算积分能力

        b.计算租借金额能力

效果:客人还是保持着租借能力和租借电影的选择权,而把电影价格类型独立出来作为独立个体类,实现自己可控的积分计算方式和租借计算方式,对于后续拓展,只需要调整电影价格类型即可

 客户类

public class Customer {

    private String _name;
    private Vector _rentals = new Vector();

    public Customer(String _name) {
        this._name = _name;
    }

    public void addRental(Rental arg){
        _rentals.addElement(arg);
    }

    public String getName() {
        return _name;
    }

    public String statement(){
        Enumeration rentals = _rentals.elements();
        String result = "Rental Record for "+getName()+"\n";
        while (rentals.hasMoreElements()){
            Rental each = (Rental) rentals.nextElement();
            result+= "\t"+each.getMovie().getTitle()+"\t"+each.getCharge()+"\n";
        }

        result+="Amount owed is "+String.valueOf(getTotalCharge())+"\n";
        result+="You earned "+String.valueOf(getFrequentRenterPoints())+" frequent renter points";
        return result;
    }

    private double getTotalCharge() {
        double result = 0;
        Enumeration rentals = _rentals.elements();
        while (rentals.hasMoreElements()){
            Rental each = (Rental) rentals.nextElement();
            result +=each.getCharge();
        }
        return result;
    }

    private double getFrequentRenterPoints(){
        double result = 0;
        Enumeration rentals = _rentals.elements();
        while (rentals.hasMoreElements()){
            Rental each = (Rental) rentals.nextElement();
            result +=each.getFrequentRenterPoints();
        }
        return result;
    }

}

租借类

public class Rental {

    private Movie _movie;
    private int _dayRented;

    public void setMovie(Movie _movie) {
        this._movie = _movie;
    }

    public void setDayRented(int _dayRented) {
        this._dayRented = _dayRented;
    }

    public Movie getMovie() {
        return _movie;
    }

    public int getDaysRented() {
        return _dayRented;
    }

    public int getFrequentRenterPoints() {
        return _movie.getFrequentRenterPoints(_dayRented);
    }

    public double getCharge(){
        return _movie.getCharge(_dayRented);
    }
}

电影类

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 Price _priceCode;

    public Movie(String title, int priceCode) {
        this._title = title;
        setPriceCode(priceCode);
    }

    public int getPriceCode() {
        return _priceCode.getPriceCode();
    }

    public void setPriceCode(int arg) {
        switch (arg){
            case CHILDRENS:
                _priceCode = new ChildrensPrice();
                break;
            case REGULAR:
                _priceCode = new RegularPrice();
                break;
            case NEW_RELEASE:
                _priceCode = new NewReleasePrice();
                break;
            default:
                throw new IllegalArgumentException("Incorrect Price code");
        }
    }

    public String getTitle() {
        return _title;
    }

    public int getFrequentRenterPoints(int daysRented) {
        return _priceCode.getFrequentRenterPoints(daysRented);
    }

    public double getCharge(int dayRented){
        return  _priceCode.getCharge(dayRented);
    }
}

价格类及继承类型类

public abstract class Price {
    abstract int getPriceCode();

    abstract double getCharge(int dayRented);

    int getFrequentRenterPoints(int daysRented){
        return 1;
    }
}


public class ChildrensPrice extends Price{

    int getPriceCode(){
        return Movie.CHILDRENS;
    }

    public double getCharge(int dayRented) {
        double result= 0;
        if (dayRented > 2){
            result += (dayRented - 3) * 1.5;
        }
        return result;
    }
}


public class NewReleasePrice extends Price{

    int getPriceCode(){
        return Movie.NEW_RELEASE;
    }

    public double getCharge(int dayRented) {
        double result= 0;
        result += dayRented*3;
        return result;
    }

    int getFrequentRenterPoints(int daysRented) {
        return daysRented > 1?2:1;
    }
}

public class RegularPrice extends Price{
    int getPriceCode(){
        return Movie.REGULAR;
    }

    public double getCharge(int dayRented) {
        double result= 0;
        result += 2;
        if (dayRented > 2){
            result += (dayRented - 2) * 1.5;
        }
        return result;
    }
}

Test类

    @Test
    void test(){
        Customer customer = new Customer("Marcus");
        Rental rental = new Rental();
        rental.setMovie(new Movie("日常影片",Movie.REGULAR));
        rental.setDayRented(5);

        customer.addRental(rental);

        System.out.println(customer.statement());
    }

效果 ​​​​​

 感悟:这种改造其实一开始设计的时候没有提炼好需要的功法语句,所以导致练气不顺。但本次道法改造之后明显可以看到后续修炼新的神通或者道法都可以快速接入和上手,对于身体经络更为直观的看到了解会运行的效果,对于后续的道法运行更为方便畅心

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值