This picture inspired a contest between a few of my friends to rewrite this code in more proper OO style.
This is what I have come up with. Any thoughts:
public enum CoffeeKind
{
Black = 1,
Cappuccino,
Espresso
}
public class Coffee
{
//Measured in celcius
public int Temprature { get; set; } = 30;
public bool HasMilk { get; set; }
public int Sugar { get; set; }
public CoffeeKind Kind { get; set; }
public bool Cold => Temprature < 24;
}
public enum CupSize
{
Small = 1,
Medium,
Large,
ExtraLarge
}
public class Cup
{
public static Cup SMALL = new Cup(CupSize.Small);
public static Cup MEDIUM = new Cup(CupSize.Medium);
public static Cup LARGE = new Cup(CupSize.Large);
public static Cup EXTRA_LARGE = new Cup(CupSize.ExtraLarge);
public static Dictionary<CupSize, Cup> Cups = new Dictionary<CupSize, Cup>
{
[CupSize.Small] = SMALL,
[CupSize.Medium] = MEDIUM,
[CupSize.Large] = LARGE,
[CupSize.ExtraLarge] = EXTRA_LARGE
};
public CupSize Size { get; }
public int Amount { get; set; }
public bool Empty => Amount == 0;
public Coffee Coffee { get; set; }
private Cup() : this(CupSize.Medium) { }
private Cup(CupSize size)
{
Size = size;
}
public void Fill(CoffeeKind kind)
{
if (Empty)
{
Coffee = new Coffee { Kind = kind };
Amount = SetAmountBySize(Size);
}
}
private static int SetAmountBySize(CupSize size)
{
switch (size)
{
case CupSize.Small:
return 100;
case CupSize.Large:
return 300;
case CupSize.ExtraLarge:
return 400;
case CupSize.Medium:
default:
return 200;
}
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name => $"{FirstName} {LastName}";
public Cup Cup { get; set; }
public Person() { }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public void GetCoffee(CupSize size, CoffeeKind kind)
{
Cup = Cup.Cups[size];
Cup.Fill(kind);
}
public void Drink()
{
if (Cup?.Empty == false && Cup?.Coffee?.Cold == false)
{
Cup.Amount = 0;
}
}
public void Drink(int amount)
{
if (Cup?.Empty == false && Cup?.Coffee?.Cold == false)
{
Cup.Amount -= amount;
}
}
}
class Program
{
const int EXIT = -1;
const int GET_COFFEE = 1;
const int DRINK_COFFEE = 2;
const int DRINK_AMOUNT = 3;
//TODO change these to use values of enum - or just change the calls to them
const int SMALL = 1;
const int MEDIUM = 2;
const int LARGE = 3;
const int EXTRA_LARGE = 4;
const int BLACK = 1;
const int CAPPUCCINO = 2;
const int ESPRESSO = 3;
static Person person;
static void Main(string[] args)
{
Console.WriteLine("Enter first name:");
string firstName = Console.ReadLine();
Console.WriteLine("Enter last name:");
string lastName = Console.ReadLine();
person = new Person(firstName, lastName);
var choice = GetUserAction();
while (choice != EXIT)
{
if (choice == GET_COFFEE)
{
if (person?.Cup?.Empty == false)
{
Console.WriteLine("Old coffee will be thrown out");
}
int cupSize = GetCupSize();
int coffeeKind = GetCoffeKind();
person.GetCoffee((CupSize)cupSize, (CoffeeKind)coffeeKind);
Console.WriteLine($"Got a {person.Cup.Size.ToString()} size {person.Cup.Coffee.Kind.ToString()} coffee");
}
else if (choice == DRINK_COFFEE)
{
if (person?.Cup?.Empty == false)
{
person.Drink();
}
else
{
Console.WriteLine("Can not drink without coffee!");
}
}
choice = GetUserAction();
}
}
private static int GetCoffeKind()
{
Console.WriteLine($"{BLACK}: Black");
Console.WriteLine($"{CAPPUCCINO}: Cappuccino");
Console.WriteLine($"{ESPRESSO}: Espresso");
var result = int.Parse(Console.ReadLine());
if (result < BLACK || result > ESPRESSO)
{
return GetCoffeKind();
}
return result;
}
private static int GetCupSize()
{
Console.WriteLine($"{SMALL}: {nameof(SMALL)}");
Console.WriteLine($"{MEDIUM}: Medium");
Console.WriteLine($"{LARGE}: Large");
Console.WriteLine($"{EXTRA_LARGE}: Extra Large");
var result = int.Parse(Console.ReadLine());
if (result < SMALL || result > EXTRA_LARGE)
{
return GetCupSize();
}
return result;
}
private static int GetUserAction()
{
Console.WriteLine("What would you like to do:");
Console.WriteLine($"{GET_COFFEE}: Get coffee");
// You can't drink coffee without a cup
if (person?.Cup != null)
{
Console.WriteLine($"{DRINK_COFFEE}: Drink coffee");
Console.WriteLine($"{DRINK_AMOUNT}: Drink some coffee");
}
Console.WriteLine($"{EXIT}: Exit");
return int.Parse(Console.ReadLine());
}
}