Jan KolΓ‘rik
Reshaping the conventional cycle
But why would we do that?
Build confidence and control
|
||
Gain a new perspective
|
||
Drive yourself to clean code
|
||
Take it as a game, challenge yourself
|
||
Beer
πΊ
Bill
π
Client
Waiter
Requirements:
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
interface IBeer
{
bool IsFull();
void Drink();
}
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
throw new NotImplementedException();
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
throw new NotImplementedException();
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
throw new NotImplementedException();
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
throw new NotImplementedException();
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
throw new NotImplementedException();
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
throw new NotImplementedException();
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β¬ New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
return true;
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
return true;
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
[Test]
public void BeerIsEmptyAfterDrinking() {
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
return true;
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
[Test]
public void BeerIsEmptyAfterDrinking() {
var beer = new Beer();
beer.Drink();
Assert.IsFalse( beer.IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
return true;
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
[Test]
public void BeerIsEmptyAfterDrinking() {
var beer = new Beer();
beer.Drink();
Assert.IsFalse( beer.IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
}
public bool IsFull() {
return true;
}
public void Drink() {
throw new NotImplementedException();
}
}
Test list:
β New beer is full
β¬ Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
[Test]
public void BeerIsEmptyAfterDrinking() {
var beer = new Beer();
beer.Drink();
Assert.IsFalse( beer.IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
this.isFull = true;
}
public bool IsFull() {
return isFull;
}
public void Drink() {
isFull = false;
}
private bool isFull;
}
Test list:
β New beer is full
β Drunk beer is empty
[TestFixture]
class BeerTest
{
[Test]
public void BeerIsFullAfterCreation() {
Assert.IsTrue( new Beer().IsFull() );
}
[Test]
public void BeerIsEmptyAfterDrinking() {
var beer = new Beer();
beer.Drink();
Assert.IsFalse( beer.IsFull() );
}
}
class Beer : IBeer
{
public Beer() {
this.isFull = true;
}
public bool IsFull() {
return isFull;
}
public void Drink() {
isFull = false;
}
private bool isFull;
}
Requirements:
Test list:
β¬ New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
interface IBill
{
void AddBeer();
void Pay( uint count );
uint GetUnpaidCount();
}
Test list:
β¬ New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
throw new NotImplementedException();
}
}
Test list:
β¬ New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, new Bill().GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
throw new NotImplementedException();
}
}
Test list:
β¬ New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
throw new NotImplementedException();
}
}
Test list:
β¬ New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
throw new NotImplementedException();
}
}
Test list:
β¬ New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
throw new NotImplementedException();
}
}
Test list:
β¬ New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return 0;
}
}
Test list:
β New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return 0;
}
}
Test list:
β New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return 0;
}
}
Test list:
β New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return 0;
}
}
Test list:
β New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return 0;
}
}
Test list:
β New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
throw new NotImplementedException();
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return 0;
}
}
Test list:
β New bill is empty
β¬ Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
beers = beers + 1;
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return beers;
}
private uint beers = 0;
}
Test list:
β New bill is empty
β Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
}
public void AddBeer() {
beers = beers + 1;
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return beers;
}
private uint beers = 0;
}
Test list:
β New bill is empty
β Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
throw new NotImplementedException();
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β¬ Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
unpaidBeers -= count;
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
unpaidBeers -= count;
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
[Test]
public void PayTooManyThrowsAnException() {
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
unpaidBeers -= count;
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
[Test]
public void PayTooManyThrowsAnException() {
Assert.Catch( () => bill.Pay( 1 ) );
bill.AddBeer();
Assert.Catch( () => bill.Pay( 2 ) );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
unpaidBeers -= count;
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
[Test]
public void PayTooManyThrowsAnException() {
Assert.Catch( () => bill.Pay( 1 ) );
bill.AddBeer();
Assert.Catch( () => bill.Pay( 2 ) );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
unpaidBeers -= count;
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β Pay beer
β¬ Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
[Test]
public void PayTooManyThrowsAnException() {
Assert.Catch( () => bill.Pay( 1 ) );
bill.AddBeer();
Assert.Catch( () => bill.Pay( 2 ) );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
if( count > unpaidBeers ) {
throw new Exception();
}
unpaidBeers -= count;
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Test list:
β New bill is empty
β Add beer
β Pay beer
β Pay too many
[TestFixture]
class BillTest
{
Bill bill;
[SetUp]
public void Init() {
bill = new Bill();
}
[Test]
public void GetUnpaidCountIsZeroByDefault() {
Assert.AreEqual( 0, bill.GetUnpaidCount() );
}
[Test]
public void AddBeerIncrementsUnpaidCount() {
bill.AddBeer();
Assert.AreEqual( 1, bill.GetUnpaidCount() );
bill.AddBeer();
Assert.AreEqual( 2, bill.GetUnpaidCount() );
}
[Test]
public void PayDecreasesUnpaidCount() {
bill.AddBeer();
bill.AddBeer();
bill.AddBeer();
bill.Pay( 2 );
Assert.AreEqual( 1, bill.GetUnpaidCount() );
}
[Test]
public void PayTooManyThrowsAnException() {
Assert.Catch( () => bill.Pay( 1 ) );
bill.AddBeer();
Assert.Catch( () => bill.Pay( 2 ) );
}
}
class Bill : IBill
{
public Bill() {
unpaidBeers = 0;
}
public void AddBeer() {
unpaidBeers++;
}
public void Pay( uint count ) {
if( count > unpaidBeers ) {
throw new Exception();
}
unpaidBeers -= count;
}
public uint GetUnpaidCount() {
return unpaidBeers;
}
private uint unpaidBeers;
}
Requirements:
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
class Client : IClient
{
public Client() {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
class Client : IClient
{
public Client() {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client() {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
}
public void OrderBeer() {
throw new NotImplementedException();
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
private IWaiter waiter;
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
this.waiter = waiter;
}
public void OrderBeer() {
waiter.Order( this );
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
private IWaiter waiter;
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
this.waiter = waiter;
}
public void OrderBeer() {
waiter.Order( this );
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
private IWaiter waiter;
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
this.waiter = waiter;
}
public void OrderBeer() {
waiter.Order( this );
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
private IWaiter waiter;
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
this.waiter = waiter;
}
public void OrderBeer() {
waiter.Order( this );
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
throw new NotImplementedException();
}
private IWaiter waiter;
}
interface IClient
{
void OrderBeer();
void ReceiveBeer( IBeer beer );
void SetBill( IBill bill );
IBill GetBill();
void PayBill();
}
interface IWaiter
{
void Order( IClient client );
void Pay( IClient client );
}
class Client : IClient
{
public Client( IWaiter waiter ) {
this.waiter = waiter;
}
public void OrderBeer() {
waiter.Order( this );
}
public void SetBill( IBill bill ) {
throw new NotImplementedException();
}
public IBill GetBill() {
throw new NotImplementedException();
}
public void PayBill() {
throw new NotImplementedException();
}
public void ReceiveBeer( IBeer beer ) {
beer.Drink();
}
private IWaiter waiter;
}
The rest is left as an exercise ...
A module should be responsible to one, and only one, actor.
interface IReportProcessor
{
IReport Parse( string text );
void Print( IReport report );
}
interface IReportParser
{
IReport Parse( string text );
}
interface IReportPrinter
{
void Print( IReport report );
}
Entities should be open for extension, but closed for modification.
Subclasses should be interchangeable with their base classes seamlessly.
Apple apple = new Orange();
apple.GetColor();
Fruit fruit = new Orange();
fruit.GetColor();
Clients should not be forced to depend on interfaces they do not use.
interface ILaundry
{
void Wash();
void Dry();
}
class ComboWashingMashine : ILaundry
{
public void Wash() {
// do the work
}
public void Dry() {
// do the work
}
}
class SimpleWashingMashine : ILaundry
{
public void Wash() {
// do the work as well
}
public void Dry() {
// whoops, can't do
throw new NotImplementedException();
}
}
interface IWashLaundry
{
void Wash();
}
interface IDryLaundry
{
void Dry();
}
class ComboWashingMashine : IWashLaundry,
IDryLaundry
{
public void Wash() {
// do the work
}
public void Dry() {
// do the work
}
}
class SimpleWashingMashine : IWashLaundry
{
public void Wash() {
// do the work
}
}
One should depend upon abstractions, not concretions.