株式会社エス・スリー・フォー

C++/C#/VB.NETによる リファクタリング – リファクタリング後(C#)

Movie.cs

// Movie.cs

namespace csharp_after {

  public class Movie {

    public enum enumPriceCode {
      CHILDRENS = 2, REGULAR = 0, NEW_RELEASE = 1
    }

    private string _title;
    private Price  _price;

    public Movie(string title, enumPriceCode priceCode) {
      _title = title;
      PriceCode = priceCode;
    }

    public enumPriceCode PriceCode {
      get { return _price.PriceCode; }
      set {
        switch ( value ) {
        case Movie.enumPriceCode.REGULAR :
          _price = new RegularPrice();
          break;
        case Movie.enumPriceCode.CHILDRENS :
          _price = new ChildrensPrice();
          break;
        case Movie.enumPriceCode.NEW_RELEASE :
          _price = new NewReleasePrice();
          break;
        default:
          throw new System.Exception("不正な料金コード");
        }
      }
    }

     public string Title {
       get { return _title; }
     }

     public double getCharge(int daysRented) {
       return _price.getCharge(daysRented);
     }

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

  }
}

Rental.cs

// Rental.cs

namespace csharp_after {

  public class Rental {

    private Movie _movie;
    private int _daysRented;

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

    public int DaysRented {
      get { return _daysRented; }
    }

    public Movie Movie {
      get { return _movie; }
    }

    public double Charge {
      get { return _movie.getCharge(_daysRented); }
    }

    public int FrequentRenterPoints {
      get { return _movie.getFrequentRenterPoints(_daysRented); }
    }

  }

}

Customer.cs

// Customer.cs

namespace csharp_after {

  public class Customer {

    private string _name;
    private System.Collections.ArrayList _rentals;

    public Customer(string name) {
      _rentals = new System.Collections.ArrayList();
      _name = name;
    }

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

    public string Name {
      get { return _name; }
    }

    public string statement() {
      string result = "Rental Record for " + Name + "\n";
      foreach ( Rental each in _rentals ) {
        // この貸し出しに対する数値の表示
        result += "\t" + each.Movie.Title + "\t" +
                  each.Charge.ToString() + "\n";
      }
      // フッタ部分の追加
      result += "Amount owed is " + TotalCharge.ToString() + "\n";
      result += "You earned " + TotalFrequentRenterPoints.ToString() +
                " frequent renter points";
      return result;
    }

    double TotalCharge {
      get {
        double result = 0;
        foreach ( Rental each in _rentals ) {
          result += each.Charge;
        }
        return result;
      }
    }

    double TotalFrequentRenterPoints {
      get {
        int result = 0;
        foreach ( Rental each in _rentals ) {
          result += each.FrequentRenterPoints;
        }
        return result;
      }
    }
  }

}

Price.cs

// Price.cs

namespace csharp_after {

  public abstract class Price {

    abstract public Movie.enumPriceCode PriceCode { get; } 
    abstract public double getCharge(int daysRented);
    virtual public int getFrequentRenterPoints(int daysRented) { return 1; }
  }

  class ChildrensPrice : Price {

    public override Movie.enumPriceCode PriceCode {
      get { return Movie.enumPriceCode.CHILDRENS; }
    }

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

  }

  class NewReleasePrice : Price {

    public override Movie.enumPriceCode PriceCode {
      get { return Movie.enumPriceCode.NEW_RELEASE; }
    }

    public override double getCharge(int daysRented) {
      return daysRented * 3;
    }

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

  }

  class RegularPrice : Price {

    public override Movie.enumPriceCode PriceCode {
      get { return Movie.enumPriceCode.REGULAR; }
    }

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

}