ここでは,書籍『リファクタリング ―プログラミングの体質改善テクニック』の中の例題『RentalVideo』(Java 言語による) の C# + NUnit 移植版をご紹介します.
テスト成功
テスト失敗
コンパイルエラー
RentalVideoTest.cs (新規作成)
using System;
using NUnit.Framework;
[TestFixture]
public class TestMovie
{
[Test]
public void TestCreateMovies()
{
Movie movie1 = new Movie("七人の侍" , Movie.Kind.REGULAR );
Assert.AreEqual("七人の侍" , movie1.Title);
Assert.AreEqual(Movie.Kind.REGULAR , movie1.PriceCode);
Movie movie2 = new Movie("ラスト サムライ" , Movie.Kind.NEW_RELEASE);
Assert.AreEqual("ラスト サムライ" , movie2.Title);
Assert.AreEqual(Movie.Kind.NEW_RELEASE, movie2.PriceCode);
Movie movie3 = new Movie("フランダースの犬", Movie.Kind.CHILDRENS );
Assert.AreEqual("フランダースの犬", movie3.Title);
Assert.AreEqual(Movie.Kind.CHILDRENS , movie3.PriceCode);
}
}
[TestFixture]
public class TestRental
{
[Test]
public void TestCreateRentals()
{
Rental rental1 = new Rental(new Movie("E.T." , Movie.Kind.REGULAR ), 8);
Assert.AreEqual("E.T." , rental1.GetMovie().Title);
Assert.AreEqual(Movie.Kind.REGULAR , rental1.GetMovie().PriceCode);
Assert.AreEqual(8, rental1.DaysRented);
Rental rental2 = new Rental(new Movie("ロード・オブ・ザ・リング 王の帰還", Movie.Kind.NEW_RELEASE), 3);
Assert.AreEqual("ロード・オブ・ザ・リング 王の帰還", rental2.GetMovie().Title);
Assert.AreEqual(Movie.Kind.NEW_RELEASE, rental2.GetMovie().PriceCode);
Assert.AreEqual(3, rental2.DaysRented);
Rental rental3 = new Rental(new Movie("トイ・ストーリー2" , Movie.Kind.CHILDRENS ), 2);
Assert.AreEqual("トイ・ストーリー2" , rental3.GetMovie().Title);
Assert.AreEqual(Movie.Kind.CHILDRENS , rental3.GetMovie().PriceCode);
Assert.AreEqual(2, rental3.DaysRented);
}
}
[TestFixture]
public class TestCustomer
{
[Test]
public void TestCreateCustomer()
{
Customer customer = new Customer("福井 太郎");
Assert.AreEqual("福井 太郎", customer.Name);
}
[Test]
public void TestCustomerStatement()
{
Customer customer = new Customer("福井 太郎");
customer.Add(new Rental(new Movie("マトリックス" , Movie.Kind.REGULAR ), 8));
customer.Add(new Rental(new Movie("マトリックス リボリューションズ", Movie.Kind.NEW_RELEASE), 2));
customer.Add(new Rental(new Movie("ファインディング ニモ" , Movie.Kind.CHILDRENS ), 4));
string statement = customer.Statement();
Assert.AreEqual("レンタル記録: 福井 太郎\n\tマトリックス\t1100円\n\tマトリックス リボリューションズ\t600円\n\tファインディング ニモ\t300円\n総額 2000円\n今回の獲得レンタル ポイントは 4 ポイントです.", statement);
}
}
RentalVideo.cs (新規作成)
using System;
using System.Collections;
class Movie
{
public enum Kind
{
REGULAR ,
NEW_RELEASE,
CHILDRENS
}
private string title;
private Kind priceCode;
public Movie(string title, Kind priceCode)
{
this.title = title;
this.priceCode = priceCode;
}
public Kind PriceCode
{
get { return priceCode; }
set { priceCode = value; }
}
public string Title
{
get { return title; }
}
}
class Rental
{
private Movie movie;
private int daysRented;
public Rental(Movie movie, int daysRented)
{
this.movie = movie;
this.daysRented = daysRented;
}
public int DaysRented
{
get { return daysRented; }
}
public Movie GetMovie()
{ return movie; }
}
class Customer
{
private string name;
private ArrayList rentals = new ArrayList();
public Customer(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
public void Add(Rental rental)
{
rentals.Add(rental);
}
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
int thisAmount = 0;
// 一行ごとに金額を計算
switch (each.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
thisAmount += 200;
if (each.DaysRented > 2)
thisAmount += (each.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
thisAmount += each.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
thisAmount += 150;
if (each.DaysRented > 3)
thisAmount += (each.DaysRented - 3) * 150;
break;
}
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + thisAmount + "円\n";
totalAmount += thisAmount;
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
int thisAmount = 0;
// 一行ごとに金額を計算
switch (each.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
thisAmount += 200;
if (each.DaysRented > 2)
thisAmount += (each.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
thisAmount += each.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
thisAmount += 150;
if (each.DaysRented > 3)
thisAmount += (each.DaysRented - 3) * 150;
break;
}
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + thisAmount + "円\n";
totalAmount += thisAmount;
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
private int AmountFor(Rental each)
{
int thisAmount = 0;
switch (each.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
thisAmount += 200;
if (each.DaysRented > 2)
thisAmount += (each.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
thisAmount += each.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
thisAmount += 150;
if (each.DaysRented > 3)
thisAmount += (each.DaysRented - 3) * 150;
break;
}
return thisAmount;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
int thisAmount = 0AmountFor(each);
// 一行ごとに金額を計算
switch (each.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
thisAmount += 200;
if (each.DaysRented > 2)
thisAmount += (each.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
thisAmount += each.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
thisAmount += 150;
if (each.DaysRented > 3)
thisAmount += (each.DaysRented - 3) * 150;
break;
}
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + thisAmount + "円\n";
totalAmount += thisAmount;
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
…
}
RentalVideo.cs
private int AmountFor(Rental eachaRental)
{
int thisAmountresult = 0;
switch (eachaRental.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
thisAmountresult += 200;
if (eachaRental.DaysRented > 2)
thisAmountresult += (eachaRental.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
thisAmountresult += eachaRental.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
thisAmountresult += 150;
if (eachaRental.DaysRented > 3)
thisAmountresult += (eachaRental.DaysRented - 3) * 150;
break;
}
return thisAmountresult;
}
RentalVideo.cs
class Rental
{
…
public int GetCharge()
{
int result = 0;
switch (aRental.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (aRental.DaysRented > 2)
result += (aRental.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += aRental.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (aRental.DaysRented > 3)
result += (aRental.DaysRented - 3) * 150;
break;
}
return result;
}
}
class Customer
{
…
private int AmountFor(Rental aRental)
{
int result = 0;
switch (aRental.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (aRental.DaysRented > 2)
result += (aRental.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += aRental.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (aRental.DaysRented > 3)
result += (aRental.DaysRented - 3) * 150;
break;
}
return result;
}
}
RentalVideo.cs
class Rental
{
…
public int GetCharge()
{
int result = 0;
switch (aRental.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (aRental.DaysRented > 2)
result += (aRental.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += aRental.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (aRental.DaysRented > 3)
result += (aRental.DaysRented - 3) * 150;
break;
}
return result;
}
}
RentalVideo.cs
class Customer
{
…
private int AmountFor(Rental aRental)
{
int result = 0;
switch (aRental.GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (aRental.DaysRented > 2)
result += (aRental.DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += aRental.DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (aRental.DaysRented > 3)
result += (aRental.DaysRented - 3) * 150;
break;
}
return result;
return aRental.GetCharge();
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
int thisAmount = AmountFor(each)each.GetCharge();
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + thisAmount + "円\n";
totalAmount += thisAmount;
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
…
}
RentalVideo.cs
class Customer
{
…
private int AmountFor(Rental aRental)
{
return aRental.GetCharge();
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
int thisAmount = each.GetCharge();
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + thisAmounteach.GetCharge() + "円\n";
totalAmount += thisAmounteach.GetCharge();
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
int thisAmount = each.GetCharge();
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
totalAmount += each.GetCharge();
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
totalAmount += each.GetCharge();
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
}
class Rental
{
…
public int GetFrequentRenterPoints()
{
int frequentRenterPoints = 0;
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
return frequentRenterPoints;
}
}
RentalVideo.cs
class Rental
{
…
public int GetFrequentRenterPoints()
{
int frequentRenterPoints = 0;
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
return frequentRenterPoints;
}
}
RentalVideo.cs
class Rental
{
…
public int GetFrequentRenterPoints()
{
int frequentRenterPoints = 0;
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
ifreturn ((GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && DaysRented > 1) ? 2 : 1;
frequentRenterPoints++;
return frequentRenterPoints;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPoints++;
// 新作を二日以上借りた場合はボーナス ポイント
if ((each.GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && each.DaysRented > 1)
frequentRenterPoints++;
frequentRenterPoints += each.GetFrequentRenterPoints();
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
totalAmount += each.GetCharge();
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPoints += each.GetFrequentRenterPoints();
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
totalAmount += each.GetCharge();
}
// フッタ部分の追加
result += "総額 " + totalAmount + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
private int GetTotalCharge()
{
int totalAmount = 0;
foreach (Rental each in rentals)
{
totalAmount += each.GetCharge();
}
return totalAmount;
}
}
RentalVideo.cs
class Customer
{
…
private int GetTotalCharge()
{
int totalAmountresult = 0;
foreach (Rental each in rentals)
{
totalAmountresult += each.GetCharge();
}
return totalAmountresult;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int totalAmount = 0;
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPoints += each.GetFrequentRenterPoints();
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
totalAmount += each.GetCharge();
}
// フッタ部分の追加
result += "総額 " + totalAmountGetTotalCharge() + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
…
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPoints += each.GetFrequentRenterPoints();
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
}
// フッタ部分の追加
result += "総額 " + GetTotalCharge() + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPoints + " ポイントです.";
return result;
}
…
private int GetTotalFrequentRenterPoints()
{
int frequentRenterPoints = 0;
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPoints += each.GetFrequentRenterPoints();
}
return frequentRenterPoints;
}
}
RentalVideo.cs
class Customer
{
…
private int GetTotalFrequentRenterPoints()
{
int frequentRenterPointsresult = 0;
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPointsresult += each.GetFrequentRenterPoints();
}
return frequentRenterPointsresult;
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成
public string Statement()
{
int frequentRenterPoints = 0;
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
frequentRenterPoints += each.GetFrequentRenterPoints();
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
}
// フッタ部分の追加
result += "総額 " + GetTotalCharge() + "円\n";
result += "今回の獲得レンタル ポイントは " + frequentRenterPointsGetTotalFrequentRenterPoints() + " ポイントです.";
return result;
}
…
}
RentalVideoTest.cs
public class TestCustomer
{
…
[Test]
public void TestCustomerHtmlStatement()
{
Customer customer = new Customer("福井 太郎");
customer.Add(new Rental(new Movie("マトリックス" , Movie.Kind.REGULAR ), 8));
customer.Add(new Rental(new Movie("マトリックス リボリューションズ", Movie.Kind.NEW_RELEASE), 2));
customer.Add(new Rental(new Movie("ファインディング ニモ" , Movie.Kind.CHILDRENS ), 4));
string statement = customer.HtmlStatement();
Assert.AreEqual("<h1>レンタル記録: <em>福井 太郎</em></h1>\n<p>\nマトリックス: 1100円<br>\nマトリックス リボリューションズ: 600円<br>\nファインディング ニモ: 300円<br>\n<p>総額 <em>2000</em>円<br>\n今回の獲得レンタル ポイントは <em>4</em> ポイントです.\n</p>\n", statement);
}
}
RentalVideo.cs
class Customer
{
…
// レシート生成 (HTML版)
public string HtmlStatement()
{
string result = "<h1>レンタル記録: <em>" + Name + "</em></h1>\n<p>\n";
foreach (Rental each in rentals)
{
// この貸し出しに関する数値の表示
result += each.GetMovie().Title + ": " + each.GetCharge() + "円<br>\n";
}
// フッタ部分の追加
result += "<p>総額 <em>" + GetTotalCharge() + "</em>円<br>\n";
result += "今回の獲得レンタル ポイントは <em>" + GetTotalFrequentRenterPoints() + "</em> ポイントです.\n</p>\n";
return result;
}
…
}
RentalVideo.cs
class Movie
{
…
public int GetCharge()
{
int result = 0;
switch (GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (DaysRented > 2)
result += (DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (DaysRented > 3)
result += (DaysRented - 3) * 150;
break;
}
return result;
}
}
class Rental
{
…
public int GetCharge()
{
int result = 0;
switch (GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (DaysRented > 2)
result += (DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (DaysRented > 3)
result += (DaysRented - 3) * 150;
break;
}
return result;
}
…
}
RentalVideo.cs
class Movie
{
…
public int GetCharge(int daysRented)
{
int result = 0;
switch (GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (DaysRenteddaysRented > 2)
result += (DaysRenteddaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += DaysRenteddaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (DaysRenteddaysRented > 3)
result += (DaysRenteddaysRented - 3) * 150;
break;
}
return result;
}
}
RentalVideo.cs
class Rental
{
…
public int GetCharge()
{
int result = 0;
switch (GetMovie().PriceCode)
{
case Movie.Kind.REGULAR :
result += 200;
if (DaysRented > 2)
result += (DaysRented - 2) * 150;
break;
case Movie.Kind.NEW_RELEASE:
result += DaysRented * 300;
break;
case Movie.Kind.CHILDRENS :
result += 150;
if (DaysRented > 3)
result += (DaysRented - 3) * 150;
break;
}
return result;
return GetMovie().GetCharge(DaysRented);
}
…
}
RentalVideo.cs
class Movie
{
…
public int GetFrequentRenterPoints()
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && DaysRented > 1) ? 2 : 1;
}
}
class Rental
{
…
public int GetFrequentRenterPoints()
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && DaysRented > 1) ? 2 : 1;
}
}
RentalVideo.cs
class Movie
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && DaysRenteddaysRented > 1) ? 2 : 1;
}
}
RentalVideo.cs
class Rental
{
…
public int GetFrequentRenterPoints()
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetMovie().PriceCode == Movie.Kind.NEW_RELEASE) && DaysRented > 1) ? 2 : 1;
GetMovie().GetFrequentRenterPoints(DaysRented);
}
}
RentalVideo.cs
class Movie
{
…
public Movie(string title, Kind priceCode)
{
this.title = title;
this.priceCodePriceCode = priceCode;
}
…
}
RentalVideo.cs
abstract class Price
{
public abstract Movie.Kind GetPriceCode();
}
class RegularPrice : Price
{
public override Movie.Kind GetPriceCode()
{ return Movie.Kind.REGULAR; }
}
class NewReleasePrice : Price
{
public override Movie.Kind GetPriceCode()
{ return Movie.Kind.NEW_RELEASE; }
}
class ChildrensPrice : Price
{
public override Movie.Kind GetPriceCode()
{ return Movie.Kind.CHILDRENS; }
}
RentalVideo.cs
abstract class Price
{
public enum Kind
{
REGULAR ,
NEW_RELEASE,
CHILDRENS
}
…
}
…
class Movie
{
public enum Kind
{
REGULAR ,
NEW_RELEASE,
CHILDRENS
}
…
}
abstract class Price
{
public abstract Movie.Kind GetPriceCode();
}
class RegularPrice : Price
{
public override Movie.Kind GetPriceCode()
{ return Movie.Kind.REGULAR; }
}
class NewReleasePrice : Price
{
public override Movie.Kind GetPriceCode()
{ return Movie.Kind.NEW_RELEASE; }
}
class ChildrensPrice : Price
{
public override Movie.Kind GetPriceCode()
{ return Movie.Kind.CHILDRENS; }
}
RentalVideo.cs
abstract class Price
{
…
}
RentalVideo.cs
class Movie
{
public enum Kind
{
REGULAR ,
NEW_RELEASE,
CHILDRENS
}
…
}
RentalVideoTest.cs
[TestFixture]
public class TestMovie
{
[Test]
public void TestCreateMovies()
{
Movie movie1 = new Movie("七人の侍" , Movie.Price.Kind.REGULAR );
Assert.AreEqual("七人の侍" , movie1.Title);
Assert.AreEqual(Movie.Price.Kind.REGULAR , movie1.PriceCode);
Movie movie2 = new Movie("ラスト サムライ" , Movie.Price.Kind.NEW_RELEASE);
Assert.AreEqual("ラスト サムライ" , movie2.Title);
Assert.AreEqual(Movie.Price.Kind.NEW_RELEASE, movie2.PriceCode);
Movie movie3 = new Movie("フランダースの犬", Movie.Price.Kind.CHILDRENS );
Assert.AreEqual("フランダースの犬", movie3.Title);
Assert.AreEqual(Movie.Price.Kind.CHILDRENS , movie3.PriceCode);
}
}
[TestFixture]
public class TestRental
{
[Test]
public void TestCreateRentals()
{
Rental rental1 = new Rental(new Movie("E.T." , Movie.Price.Kind.REGULAR ), 8);
Assert.AreEqual("E.T." , rental1.GetMovie().Title);
Assert.AreEqual(Movie.Price.Kind.REGULAR , rental1.GetMovie().PriceCode);
Assert.AreEqual(8, rental1.DaysRented);
Rental rental2 = new Rental(new Movie("ロード・オブ・ザ・リング 王の帰還", Movie.Price.Kind.NEW_RELEASE), 3);
Assert.AreEqual("ロード・オブ・ザ・リング 王の帰還", rental2.GetMovie().Title);
Assert.AreEqual(Movie.Price.Kind.NEW_RELEASE, rental2.GetMovie().PriceCode);
Assert.AreEqual(3, rental2.DaysRented);
Rental rental3 = new Rental(new Movie("トイ・ストーリー2" , Movie.Price.Kind.CHILDRENS ), 2);
Assert.AreEqual("トイ・ストーリー2" , rental3.GetMovie().Title);
Assert.AreEqual(Movie.Price.Kind.CHILDRENS , rental3.GetMovie().PriceCode);
Assert.AreEqual(2, rental3.DaysRented);
}
}
[TestFixture]
public class TestCustomer
{
…
[Test]
public void TestCustomerStatement()
{
Customer customer = new Customer("福井 太郎");
customer.Add(new Rental(new Movie("マトリックス" , Movie.Price.Kind.REGULAR ), 8));
customer.Add(new Rental(new Movie("マトリックス リボリューションズ", Movie.Price.Kind.NEW_RELEASE), 2));
customer.Add(new Rental(new Movie("ファインディング ニモ" , Movie.Price.Kind.CHILDRENS ), 4));
string statement = customer.Statement();
Assert.AreEqual("レンタル記録: 福井 太郎\n\tマトリックス\t1100円\n\tマトリックス リボリューションズ\t600円\n\tファインディング ニモ\t300円\n総額 2000円\n今回の獲得レンタル ポイントは 4 ポイントです.", statement);
}
[Test]
public void TestCustomerHtmlStatement()
{
Customer customer = new Customer("福井 太郎");
customer.Add(new Rental(new Movie("マトリックス" , Movie.Price.Kind.REGULAR ), 8));
customer.Add(new Rental(new Movie("マトリックス リボリューションズ", Movie.Price.Kind.NEW_RELEASE), 2));
customer.Add(new Rental(new Movie("ファインディング ニモ" , Movie.Price.Kind.CHILDRENS ), 4));
string statement = customer.HtmlStatement();
Assert.AreEqual("<h1>レンタル記録: <em>福井 太郎</em></h1>\n<p>\nマトリックス: 1100円<br>\nマトリックス リボリューションズ: 600円<br>\nファインディング ニモ: 300円<br>\n<p>総額 <em>2000</em>円<br>\n今回の獲得レンタル ポイントは <em>4</em> ポイントです.\n</p>\n", statement);
}
}
RentalVideo.cs
class Movie
{
…
public Movie(string title, Price.Kind priceCode)
{
this.title = title;
PriceCode = priceCode;
}
private Price.Kind priceCode;
…
public Price.Kind PriceCode
{
get { return priceCode; }
set { priceCode = value; }
}
…
public int GetCharge(int daysRented)
{
int result = 0;
switch (PriceCode)
{
case Price.Kind.REGULAR :
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
break;
case Price.Kind.NEW_RELEASE:
result += daysRented * 300;
break;
case Price.Kind.CHILDRENS :
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
break;
}
return result;
}
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((PriceCode == Price.Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
RentalVideo.cs
class NewReleasePrice : Price
{
…
private Price.Kind priceCode;
private Price price;
…
public Price.Kind PriceCode
{
get
{
return priceCode;
return price.GetPriceCode();
}
set
{
priceCode = value;
switch (value)
{
case Price.Kind.REGULAR : price = new RegularPrice (); break;
case Price.Kind.NEW_RELEASE: price = new NewReleasePrice (); break;
case Price.Kind.CHILDRENS : price = new ChildrensPrice (); break;
default : throw new ArgumentException ();
}
}
}
}
RentalVideo.cs
abstract class Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
switch (PriceCode)
{
case Price.Kind.REGULAR :
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
break;
case Price.Kind.NEW_RELEASE:
result += daysRented * 300;
break;
case Price.Kind.CHILDRENS :
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
break;
}
return result;
}
}
…
class Movie
{
…
public int GetCharge(int daysRented)
{
int result = 0;
switch (PriceCode)
{
case Price.Kind.REGULAR :
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
break;
case Price.Kind.NEW_RELEASE:
result += daysRented * 300;
break;
case Price.Kind.CHILDRENS :
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
break;
}
return result;
}
…
}
RentalVideo.cs
abstract class Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
switch (PriceCodeGetPriceCode())
{
case Price.Kind.REGULAR :
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
break;
case Price.Kind.NEW_RELEASE:
result += daysRented * 300;
break;
case Price.Kind.CHILDRENS :
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
break;
}
return result;
}
}
RentalVideo.cs
class Movie
{
…
public int GetCharge(int daysRented)
{
return price.GetCharge(daysRented);
int result = 0;
switch (PriceCode)
{
case Price.Kind.REGULAR :
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
break;
case Price.Kind.NEW_RELEASE:
result += daysRented * 300;
break;
case Price.Kind.CHILDRENS :
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
break;
}
return result;
}
…
}
RentalVideo.cs
abstract class Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
switch (GetPriceCode())
{
case Kind.REGULAR :
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
break;
case Kind.NEW_RELEASE:
result += daysRented * 300;
break;
case Kind.CHILDRENS :
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
break;
}
return result;
}
}
class RegularPrice : Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
return result;
}
}
class NewReleasePrice : Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
result += daysRented * 300;
return result;
}
}
class ChildrensPrice : Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
return result;
}
}
RentalVideo.cs
class RegularPrice : Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
return result;
}
}
class NewReleasePrice : Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
result += daysRented * 300;
return result;
return daysRented * 300;
}
}
class ChildrensPrice : Price
{
…
public int GetCharge(int daysRented)
{
int result = 0;
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
return result;
}
}
RentalVideo.cs
abstract class Price
{
…
public abstract int GetCharge(int daysRented);
{
int result = 0;
switch (GetPriceCode())
{
case Kind.REGULAR :
result += 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
break;
case Kind.NEW_RELEASE:
result += daysRented * 300;
break;
case Kind.CHILDRENS :
result += 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
break;
}
return result;
}
}
RentalVideo.cs
class RegularPrice : Price
{
…
public override int GetCharge(int daysRented)
…
}
class NewReleasePrice : Price
{
…
public override int GetCharge(int daysRented)
…
}
class ChildrensPrice : Price
{
…
public override int GetCharge(int daysRented)
…
}
RentalVideo.cs
abstract class Price
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((PriceCode == Price.Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
…
class Movie
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((PriceCode == Price.Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
RentalVideo.cs
abstract class Price
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((PriceCodeGetPriceCode() == Price.Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
RentalVideo.cs
class Movie
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((PriceCode == Price.Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
return price.GetFrequentRenterPoints(daysRented);
}
}
RentalVideo.cs
abstract class Price
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetPriceCode() == Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
class NewReleasePrice : Price
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetPriceCode() == Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
RentalVideo.cs
abstract class Price
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetPriceCode() == Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
class NewReleasePrice : Price
{
…
public int GetFrequentRenterPoints(int daysRented)
{
// 新作を二日以上借りた場合はボーナス ポイント
return ((GetPriceCode() == Kind.NEW_RELEASE) && daysRented > 1) ? 2 : 1;
}
}
RentalVideo.cs
abstract class Price
{
…
public virtual int GetFrequentRenterPoints(int daysRented)
{
return 1;
}
}
class NewReleasePrice : Price
{
…
public override int GetFrequentRenterPoints(int daysRented)
{
// 二日以上借りた場合はボーナス ポイント
return (daysRented > 1) ? 2 : 1;
}
}
RentalVideoTest.cs
[TestFixture]
public class TestMovie
{
[Test]
public void TestCreateMovies()
{
…
Movie movie4 = new Movie("交響曲第9番ニ長調", Price.Kind.MUSIC );
Assert.AreEqual("交響曲第9番ニ長調", movie4.Title);
Assert.AreEqual(Price.Kind.MUSIC , movie4.PriceCode);
}
}
[TestFixture]
public class TestRental
{
[Test]
public void TestCreateRentals()
{
…
Rental rental4 = new Rental(new Movie("グレイテスト・ヒッツ 1" , Price.Kind.MUSIC ), 9);
Assert.AreEqual("グレイテスト・ヒッツ 1" , rental4.GetMovie().Title);
Assert.AreEqual(Price.Kind.MUSIC , rental4.GetMovie().PriceCode);
Assert.AreEqual(9, rental4.DaysRented);
}
}
[TestFixture]
public class TestCustomer
{
…
[Test]
public void TestCustomerStatement()
{
…
customer.Add(new Rental(new Movie("ザ・マイルス・デイビス・ストーリー", Price.Kind.MUSIC ), 6));
string statement = customer.Statement();
Assert.AreEqual("レンタル記録: 福井 太郎\n\tマトリックス\t1100円\n\tマトリックス リボリューションズ\t600円\n\tファインディング ニモ\t300円\n総額 2000円\n今回の獲得レンタル ポイントは 4 ポイントです.", statement);
Assert.AreEqual("レンタル記録: 福井 太郎\n\tマトリックス\t1100円\n\tマトリックス リボリューションズ\t600円\n\tファインディング ニモ\t300円\n\tザ・マイルス・デイビス・ストーリー\t900円\n総額 2900円\n今回の獲得レンタル ポイントは 5 ポイントです.", statement);
}
[Test]
public void TestCustomerHtmlStatement()
{
…
customer.Add(new Rental(new Movie("ザ・マイルス・デイビス・ストーリー", Price.Kind.MUSIC ), 6));
string statement = customer.HtmlStatement();
Assert.AreEqual("<h1>レンタル記録: <em>福井 太郎</em></h1>\n<p>\nマトリックス: 1100円<br>\nマトリックス リボリューションズ: 600円<br>\nファインディング ニモ: 300円<br>\n<p>総額 <em>2000</em>円<br>\n今回の獲得レンタル ポイントは <em>4</em> ポイントです.\n</p>\n", statement);
Assert.AreEqual("<h1>レンタル記録: <em>福井 太郎</em></h1>\n<p>\nマトリックス: 1100円<br>\nマトリックス リボリューションズ: 600円<br>\nファインディング ニモ: 300円<br>\nザ・マイルス・デイビス・ストーリー: 900円<br>\n<p>総額 <em>2900</em>円<br>\n今回の獲得レンタル ポイントは <em>5</em> ポイントです.\n</p>\n", statement);
}
}
RentalVideo.cs
abstract class Price
{
public enum Kind
{
REGULAR ,
NEW_RELEASE,
CHILDRENS ,
MUSIC
}
…
}
…
class MusicPrice : Price
{
public override Kind GetPriceCode()
{ return Kind.MUSIC; }
public override int GetCharge(int daysRented)
{
return daysRented * 150;
}
}
class Movie
{
…
public Price.Kind PriceCode
{
get
{
return price.GetPriceCode();
}
set
{
switch (value)
{
case Price.Kind.REGULAR : price = new RegularPrice (); break;
case Price.Kind.NEW_RELEASE: price = new NewReleasePrice (); break;
case Price.Kind.CHILDRENS : price = new ChildrensPrice (); break;
case Price.Kind.MUSIC : price = new MusicPrice (); break;
default : throw new ArgumentException ();
}
}
}
…
}
RentalVideoTest.cs
using System;
using NUnit.Framework;
[TestFixture]
public class TestMovie
{
[Test]
public void TestCreateMovies()
{
Movie movie1 = new Movie("七人の侍" , Price.Kind.REGULAR );
Assert.AreEqual("七人の侍" , movie1.Title);
Assert.AreEqual(Price.Kind.REGULAR , movie1.PriceCode);
Movie movie2 = new Movie("ラスト サムライ" , Price.Kind.NEW_RELEASE);
Assert.AreEqual("ラスト サムライ" , movie2.Title);
Assert.AreEqual(Price.Kind.NEW_RELEASE, movie2.PriceCode);
Movie movie3 = new Movie("フランダースの犬", Price.Kind.CHILDRENS );
Assert.AreEqual("フランダースの犬" , movie3.Title);
Assert.AreEqual(Price.Kind.CHILDRENS , movie3.PriceCode);
Movie movie4 = new Movie("交響曲第9番ニ長調", Price.Kind.MUSIC );
Assert.AreEqual("交響曲第9番ニ長調", movie4.Title);
Assert.AreEqual(Price.Kind.MUSIC , movie4.PriceCode);
}
}
[TestFixture]
public class TestRental
{
[Test]
public void TestCreateRentals()
{
Rental rental1 = new Rental(new Movie("E.T." , Price.Kind.REGULAR ), 8);
Assert.AreEqual("E.T." , rental1.GetMovie().Title);
Assert.AreEqual(Price.Kind.REGULAR , rental1.GetMovie().PriceCode);
Assert.AreEqual(8, rental1.DaysRented);
Rental rental2 = new Rental(new Movie("ロード・オブ・ザ・リング 王の帰還", Price.Kind.NEW_RELEASE), 3);
Assert.AreEqual("ロード・オブ・ザ・リング 王の帰還", rental2.GetMovie().Title);
Assert.AreEqual(Price.Kind.NEW_RELEASE, rental2.GetMovie().PriceCode);
Assert.AreEqual(3, rental2.DaysRented);
Rental rental3 = new Rental(new Movie("トイ・ストーリー2" , Price.Kind.CHILDRENS ), 2);
Assert.AreEqual("トイ・ストーリー2" , rental3.GetMovie().Title);
Assert.AreEqual(Price.Kind.CHILDRENS , rental3.GetMovie().PriceCode);
Assert.AreEqual(2, rental3.DaysRented);
Rental rental4 = new Rental(new Movie("グレイテスト・ヒッツ 1" , Price.Kind.MUSIC ), 9);
Assert.AreEqual("グレイテスト・ヒッツ 1" , rental4.GetMovie().Title);
Assert.AreEqual(Price.Kind.MUSIC , rental4.GetMovie().PriceCode);
Assert.AreEqual(9, rental4.DaysRented);
}
}
[TestFixture]
public class TestCustomer
{
[Test]
public void TestCreateCustomer()
{
Customer customer = new Customer("福井 太郎");
Assert.AreEqual("福井 太郎", customer.Name);
}
[Test]
public void TestCustomerStatement()
{
Customer customer = new Customer("福井 太郎");
customer.Add(new Rental(new Movie("マトリックス" , Price.Kind.REGULAR ), 8));
customer.Add(new Rental(new Movie("マトリックス リボリューションズ" , Price.Kind.NEW_RELEASE), 2));
customer.Add(new Rental(new Movie("ファインディング ニモ" , Price.Kind.CHILDRENS ), 4));
customer.Add(new Rental(new Movie("ザ・マイルス・デイビス・ストーリー", Price.Kind.MUSIC ), 6));
string statement = customer.Statement();
Assert.AreEqual("レンタル記録: 福井 太郎\n\tマトリックス\t1100円\n\tマトリックス リボリューションズ\t600円\n\tファインディング ニモ\t300円\n\tザ・マイルス・デイビス・ストーリー\t900円\n総額 2900円\n今回の獲得レンタル ポイントは 5 ポイントです.", statement);
}
[Test]
public void TestCustomerHtmlStatement()
{
Customer customer = new Customer("福井 太郎");
customer.Add(new Rental(new Movie("マトリックス" , Price.Kind.REGULAR ), 8));
customer.Add(new Rental(new Movie("マトリックス リボリューションズ", Price.Kind.NEW_RELEASE), 2));
customer.Add(new Rental(new Movie("ファインディング ニモ" , Price.Kind.CHILDRENS ), 4));
customer.Add(new Rental(new Movie("ザ・マイルス・デイビス・ストーリー", Price.Kind.MUSIC ), 6));
string statement = customer.HtmlStatement();
Assert.AreEqual("<h1>レンタル記録: <em>福井 太郎</em></h1>\n<p>\nマトリックス: 1100円<br>\nマトリックス リボリューションズ: 600円<br>\nファインディング ニモ: 300円<br>\nザ・マイルス・デイビス・ストーリー: 900円<br>\n<p>総額 <em>2900</em>円<br>\n今回の獲得レンタル ポイントは <em>5</em> ポイントです.\n</p>\n", statement);
}
}
RentalVideo.cs
using System;
using System.Collections;
abstract class Price
{
public enum Kind
{
REGULAR ,
NEW_RELEASE,
CHILDRENS ,
MUSIC
}
public abstract Kind GetPriceCode();
public abstract int GetCharge(int daysRented);
public virtual int GetFrequentRenterPoints(int daysRented)
{
return 1;
}
}
class RegularPrice : Price
{
public override Kind GetPriceCode()
{ return Kind.REGULAR; }
public override int GetCharge(int daysRented)
{
int result = 200;
if (daysRented > 2)
result += (daysRented - 2) * 150;
return result;
}
}
class NewReleasePrice : Price
{
public override Kind GetPriceCode()
{ return Kind.NEW_RELEASE; }
public override int GetCharge(int daysRented)
{
return daysRented * 300;
}
public override int GetFrequentRenterPoints(int daysRented)
{
// 二日以上借りた場合はボーナス ポイント
return (daysRented > 1) ? 2 : 1;
}
}
class ChildrensPrice : Price
{
public override Kind GetPriceCode()
{ return Kind.CHILDRENS; }
public override int GetCharge(int daysRented)
{
int result = 150;
if (daysRented > 3)
result += (daysRented - 3) * 150;
return result;
}
}
class MusicPrice : Price
{
public override Kind GetPriceCode()
{ return Kind.MUSIC; }
public override int GetCharge(int daysRented)
{
return daysRented * 150;
}
}
class Movie
{
private string title;
private Price price;
public Movie(string title, Price.Kind priceCode)
{
this.title = title;
PriceCode = priceCode;
}
public Price.Kind PriceCode
{
get
{
return price.GetPriceCode();
}
set
{
switch (value)
{
case Price.Kind.REGULAR : price = new RegularPrice (); break;
case Price.Kind.NEW_RELEASE: price = new NewReleasePrice (); break;
case Price.Kind.CHILDRENS : price = new ChildrensPrice (); break;
case Price.Kind.MUSIC : price = new MusicPrice (); break;
default : throw new ArgumentException ();
}
}
}
public string Title
{
get { return title; }
}
public int GetCharge(int daysRented)
{
return price.GetCharge(daysRented);
}
public int GetFrequentRenterPoints(int daysRented)
{
return price.GetFrequentRenterPoints(daysRented);
}
}
class Rental
{
private Movie movie;
private int daysRented;
public Rental(Movie movie, int daysRented)
{
this.movie = movie;
this.daysRented = daysRented;
}
public int DaysRented
{
get { return daysRented; }
}
public Movie GetMovie()
{ return movie; }
public int GetCharge()
{
return GetMovie().GetCharge(DaysRented);
}
public int GetFrequentRenterPoints()
{
return GetMovie().GetFrequentRenterPoints(DaysRented);
}
}
class Customer
{
private string name;
private ArrayList rentals = new ArrayList();
public Customer(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
public void Add(Rental rental)
{
rentals.Add(rental);
}
// レシート生成
public string Statement()
{
string result = "レンタル記録: " + Name + "\n";
foreach (Rental each in rentals)
{
// この貸し出しに関する数値の表示
result += "\t" + each.GetMovie().Title + "\t" + each.GetCharge() + "円\n";
}
// フッタ部分の追加
result += "総額 " + GetTotalCharge() + "円\n";
result += "今回の獲得レンタル ポイントは " + GetTotalFrequentRenterPoints() + " ポイントです.";
return result;
}
// レシート生成 (HTML版)
public string HtmlStatement()
{
string result = "<h1>レンタル記録: <em>" + Name + "</em></h1>\n<p>\n";
foreach (Rental each in rentals)
{
// この貸し出しに関する数値の表示
result += each.GetMovie().Title + ": " + each.GetCharge() + "円<br>\n";
}
// フッタ部分の追加
result += "<p>総額 <em>" + GetTotalCharge() + "</em>円<br>\n";
result += "今回の獲得レンタル ポイントは <em>" + GetTotalFrequentRenterPoints() + "</em> ポイントです.\n</p>\n";
return result;
}
private int GetTotalCharge()
{
int result = 0;
foreach (Rental each in rentals)
{
result += each.GetCharge();
}
return result;
}
private int GetTotalFrequentRenterPoints()
{
int result = 0;
foreach (Rental each in rentals)
{
// レンタル ポイントを加算
result += each.GetFrequentRenterPoints();
}
return result;
}
}
Copyright © 1999 Martin Fowler
Copyright © 1997-2008 Sho's Software