学习 重构--改善既有的代码

来源:互联网 发布:coreldraw mac 编辑:程序博客网 时间:2024/06/05 16:58

    读书笔记,记录自己的点点滴滴!学无止境,记录自己的每一个脚步!

 今天看了书的第一小章,就让我感觉自己井底之蛙了,自己感觉已近挺不错的代码,在真正的程序员里居然那么的糟糕!

     首先说起书中的第一个例子:

                  这是一个影片出租店用的程序,计算每一位顾客的消费金额并打印报表(statement)。操作者告诉程序:顾客租了哪些影片、租期多长,程序便根据租赁时间和影片类型算出费用。影片分为三类:普通片、儿童片和新片。除了计算费用,还要为常客计算点数;点数会随着「租片种类是否为新片」而有不同。

  

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 arg) {    _priceCode = arg;  }   public String getTitle (){      return _title;  };Rental(租赁) Rental class 表示「某个顾客租了一部影片」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;    } }Customer(顾客) Customer class 用来表示顾客。就像其他classes 一样,它也拥有数据和相应的访问函数(accessor): class Customer {  private String _name;                        //姓名  private Vector _rentals = new Vector();        //租借记。   public Customer (String name){      _name = name;  };   public void addRental(Rental arg) {    _rentals.addElement(arg);  }  public String getName (){      return _name;  }; Customer「还提供了一个用以制造报表的函数(method),图1.2显示这个函数带来的交互过程(interactions )。完整代码显示于下一页。 


public String statement() {       double totalAmount = 0;        //总消费金。       int frequentRenterPoints = 0;        //常客积点       Enumeration rentals = _rentals.elements();       String result = "Rental Record for " + getName() + "\n";       while (rentals.hasMoreElements()) {           double thisAmount = 0;           Rental each = (Rental) 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" +String.valueOf(thisAmount) + "\n";           totalAmount += thisAmount;        }       //add footer lines(结尾打印)       result +=  "Amount owed is " + String.valueOf(totalAmount) + "\n";       result += "You earned " + String.valueOf(frequentRenterPoints) +" frequent renter points";       return result; 

       这个程序你的第一印象是什么,好还是差 ! 给我的感觉是已近不错了!功能都实现的了! 但是看了书的评论:(这个起始程序给你留下什么印象?我会说它设计得不好,而且很明显不符合面向对象精神。对于这样一个小程序,这些缺点其实没有什么关系。快速而随性(quick and dirty )地设计一个简单的程序并没有错。但如果这是复杂系统中具有代表性的一段, 那么我就真的要对这个程序信心动摇了。Customer 里头那个长长的statement()  做的事情实在太多了,它做了很多原本应该由其他完成的事情。)  自己真的还差很多! 待续。。。