重构_改善既有代码的设计第二天笔记

来源:互联网 发布:p2p投资网络理财产品 编辑:程序博客网 时间:2024/05/21 10:14

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

二.重构后的实例代码:

1.Rental.java

package com.test.movie.demo;

public class Rental {
 private Movie movie;
 private int daysRented; //租期长度
 
 public Rental(Movie _movie, int _daysRented){
  this.movie = _movie;
  this.daysRented = _daysRented;
 }
 
 public int getDaysRented(){
  return this.daysRented;
 }
 
 /**
  * 由于使用的是Movie类的对象,重构的时候把这个方法移动到了Movie类里面去。
  * */
// public double getcharge() {
//  double result = 0.0;
//  switch (this.getMovie().getPriceCode()) {
//  case Movie.REGULAR:
//   result  += 2;
//   if(this.getDaysRented() > 2){
//    result += (this.getDaysRented() - 2)*1.5;
//   }
//   break;
//  case Movie.NEW_RELEASE:
//   result += this.getDaysRented()*3;
//   break;
//  case Movie.CHILDRENS:
//   result += 1.5;
//   if(this.getDaysRented() >3){
//    result += (this.getDaysRented() - 3)* 1.5;
//   }
//  }
//  
//  return result;
// } 
 public double getcharge() {
  return this.movie.getCharge(this.daysRented);
 }
 
 public Movie getMovie(){
  return this.movie;
 }
 
 //重构过的提钱方法, 由于使用的是Movie类的对象,再次重构的时候把这个方法移动到了Movie类里面去。
 public int getFrequentRenterPoints(){
//  if((this.getMovie().getPriceCode() == Movie.NEW_RELEASE) && getDaysRented() > 1){
//   return 2;
//  }else {
//   return 1;
//  }
  return this.movie.getFrequentRenterPoints(this.daysRented);
 }
}

2.Customer.java

package com.test.movie.demo;

import java.util.Enumeration;
import java.util.Vector;

public class Customer {
 private String name;
 private Vector rentals = new Vector();
 
 public Customer(String _name){
  this.name = _name;
 }
 
 public void addRental(Rental arg){
  this.rentals.addElement(arg);
 }
 
 public String getName(){
  return this.name;
 }
 
 public String statement(){
  Enumeration rentals = this.rentals.elements();
  String result = "Rental Record for " + getName() + "\n";
  while (rentals.hasMoreElements()) {
   Rental each = (Rental) rentals.nextElement(); 
   
   result += "\t" + each.getMovie().getTitle() + "\t" + String.valueOf(amountFor(each)) + "\n";
  }
  
  result += "Amount owed is " +  String.valueOf(getTotalCharge()) + "\n";
  result += "You earned " + String.valueOf(getTotalFrequentRenterPoints()) + " frequent renter points";
  return result;
 }

 private int getTotalFrequentRenterPoints(){
  int result = 0;
  Enumeration rentals = this.rentals.elements();
  while (rentals.hasMoreElements()) {
   Rental each = (Rental) rentals.nextElement();
   result += each.getFrequentRenterPoints();  
  }
  return result;
 }
 
 private double getTotalCharge(){
  double result = 0;
  Enumeration rentals = this.rentals.elements();
  while (rentals.hasMoreElements()) {
   Rental each = (Rental)rentals.nextElement();
   result += each.getcharge();
  }
  return result;
 }
 
 private double amountFor(Rental aRental) {
  return aRental.getcharge();
 }
}

3.Movie.java

package com.test.movie.demo;

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;
 private Price price;
 
 public Movie(String _title, int _priceCode) {
  this.title = _title;
//  this.priceCode = _priceCode;
  setPriceCode(_priceCode);
 }

 public String getTitle() {
  return title;
 }

 public void setTitle(String title) {
  this.title = title;
 }

// public int getPriceCode() {
//  return priceCode;
// }
 public int getPriceCode() {
  return this.price.getPriceCode();
 }
// public void setPriceCode(int priceCode) {
//  this.priceCode = priceCode;
// }
 public void setPriceCode(int arg) {
  switch (arg) {
  case REGULAR:
   this.price = new RegularPrice();
   break;
  case CHILDRENS:
   this.price = new ChildrensPrice();
   break;
  case NEW_RELEASE:
   this.price = new NewReleasePrice();
   break;
  default:
   throw new IllegalArgumentException("Incorrect Price Code");
  }
 }
 
 //搬到Price类里面去
// public double getCharge(int daysRented){
//  double result = 0;
//  switch(getPriceCode()){
//  case Movie.REGULAR:
//   result += 2;
//   if(daysRented > 2){
//    result += (daysRented - 2)*1.5;
//   }
//   break;
//  case Movie.NEW_RELEASE:
//   result += daysRented*3;
//   break;
//  case Movie.CHILDRENS:
//   result += 1.5;
//   if(daysRented >3){
//    result += (daysRented - 3)*1.5;
//   }
//   break;
//  }
//  return result;
// }
 
 public double getCharge(int daysRented){
  return this.price.getCharge(daysRented);
 }
 
 //把这个函数移动到Price类中,因为价格处理都是有Price处理了
// public int getFrequentRenterPoints(int daysRented){
//  if((getPriceCode() == Movie.NEW_RELEASE) && daysRented >1){
//   return 2;
//  }else {
//   return 1;
//  }
// }
 public int getFrequentRenterPoints(int daysRented){
  return this.price.getFrequentRenterPoints(daysRented);
 }
}

 

4.Price.java

package com.test.movie.demo;

public abstract class Price {
 abstract int getPriceCode();
 
 //从Movie类里面搬过来的代码,接下来,要把他们搬到对应不同的实现类里面,改成抽象方法
// public double getCharge(int daysRented) {
//  double result = 0;
//  switch (getPriceCode()) {
//  case Movie.REGULAR:
//   result += 2;
//   if(daysRented >2){
//    result += (daysRented - 2)*1.5;
//   }
//   break;
//  case Movie.NEW_RELEASE:
//   result += daysRented*3;
//   break;
//  case Movie.CHILDRENS:
//   result += 1.5;
//   if(daysRented >3){
//    result += (daysRented -3)*1.5;
//   }
//   break;
//  }
//  return result;
// }
 abstract double getCharge(int daysRented);
 
 public int getFrequentRenterPoints(int daysRented){
  if((getPriceCode() == Movie.NEW_RELEASE) && daysRented >1){
   return 2;
  }else {
   return 1;
  }
 }
}

5.ChildrensPrice.java

package com.test.movie.demo;

public class ChildrensPrice extends Price{

 @Override
 int getPriceCode() {
  return Movie.CHILDRENS;
 }

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


6.NewReleasePrice.java

package com.test.movie.demo;

public class NewReleasePrice extends Price{

 @Override
 int getPriceCode() {
  return Movie.NEW_RELEASE;
 } 
 
 public double getCharge(int daysRented){
  return daysRented * 3;
 }
 
 public int getFrequentRenterPoints(int daysRented){
  return (daysRented > 1)?2:1;
 }
}

7.RegularPrice.java

package com.test.movie.demo;

public class RegularPrice extends Price{

 @Override
 int getPriceCode() {
  return Movie.REGULAR;
 }

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

 

三. 总结,本次重构设计到两个点,

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

2.通过继承,来实现只扩展,不修改的闭合原则。

 

0 0