Im studying design patterns and I got the idea of mixing Template Pattern with Observer. The idea of the observer is to quantify and accumulate a property of subclasses that inherits from the Abstract class and then notify it.
The idea is to just implement both design patterns and I had some doubts while doing it.
1) One of my properties for CoffeeWithMilk
is the same as CoffeeWithChocolateAndMilk
(AmountOfMilk
). Do I have to repeat this logic for every concrete class or is there any other way to avoid DRY?.
2) I have to cast both of these two classes as IMilkSpent
, is there any other way to change this?
3) Right now the MilkManager
is the one notifying the total amount of milk spent, is there any other way?.
public class NoMilkException : Exception
{
public NoMilkException(){}
public NoMilkException(int amount) : base(String.Format("The amount of milk must be more than 0 Cc, you chosed {0} Cc",amount)){}
}
public interface IMilkSpent
{
int InformMilkUsage();
}
public interface Subject
{
void Attach(IMilkSpent observer);
void Dettach(IMilkSpent observer);
void NotifyMilkUsageTotal();
}
public class MilkManager : Subject
{
public int MilkSpentTotal { get; set; }
private List<IMilkSpent> Observers = new List<IMilkSpent>();
public void Attach(IMilkSpent observer)
{
Observers.Add(observer);
}
public void Dettach(IMilkSpent observer)
{
Observers.Remove(observer);
}
public void NotifyMilkUsageTotal()
{
MilkSpentTotal = 0;
foreach(IMilkSpent observer in Observers)
{
MilkSpentTotal += observer.InformMilkUsage();
}
Console.WriteLine("Amount of Milk spent was: {0} ", MilkSpentTotal);
}
}
public abstract class AbstractCoffee
{
public void MakeCoffee()
{
PrepareCup();
BoilWater();
PutCoffee();
AddIngredientsBeforeServing();
ServeCoffee();
}
internal virtual void AddIngredientsBeforeServing(){}
protected void PutCoffee()
{
Console.WriteLine(@"I added Coffee");
}
protected void PrepareCup()
{
Console.WriteLine(@"I warmed up the cup");
}
protected void BoilWater()
{
Console.WriteLine(@"The water is boiled");
}
protected void ServeCoffee()
{
Console.WriteLine(@"Here is your cup of coffee");
Console.WriteLine("\n");
}
}
public class CoffeeWithMilk : AbstractCoffee, IMilkSpent
{
private int _amountOfMilk = 0;
public int AmountOfMilk
{
get
{
return _amountOfMilk;
}
set
{
if(value <= 0)
{
throw new NoMilkException(_amountOfMilk);
}
else
{
_amountOfMilk = value;
}
//value <= 0 ? _amountOfMilk = value : throw new NoMilkException(_amountOfMIlk);
}
}
public CoffeeWithMilk(int amountOfMilk)
{
this.AmountOfMilk = amountOfMilk;
}
internal override void AddIngredientsBeforeServing()
{
PutMilk();
PutSweet();
}
public int InformMilkUsage()
{
return AmountOfMilk;
}
protected void PutMilk()
{
Console.WriteLine("I put {0} Cc in the cup of coffee",_amountOfMilk);
}
protected void PutSweet()
{
Console.WriteLine(@"I put Sugar on your coffee");
}
}
public class CoffeeWithChocolate : AbstractCoffee
{
internal override void AddIngredientsBeforeServing()
{
PutChocolate();
PutSweet();
}
protected void PutChocolate()
{
Console.WriteLine(@"I put Chocolate on your coffee");
}
protected void PutSweet()
{
Console.WriteLine(@"I put Sugar on your coffee");
}
}
public class CoffeeWithChocolateAndMilk : AbstractCoffee, IMilkSpent
{
private int _amountOfMilk = 0;
public int AmountOfMilk
{
get
{
return _amountOfMilk;
}
set
{
if(value <= 0)
{
throw new NoMilkException(_amountOfMilk);
}
else
{
_amountOfMilk = value;
}
//value <= 0 ? _amountOfMilk = value : throw new NoMilkException(_amountOfMIlk);
}
}
public int InformMilkUsage()
{
return AmountOfMilk;
}
public CoffeeWithChocolateAndMilk(int amountOfMilk)
{
this.AmountOfMilk = amountOfMilk;
}
internal override void AddIngredientsBeforeServing()
{
PutMilk();
PutChocolate();
PutSweet();
}
protected void PutMilk()
{
Console.WriteLine("I put {0} Cc in the cup of coffee",_amountOfMilk);
}
protected void PutChocolate()
{
Console.WriteLine(@"I put Chocolate on your coffee");
}
protected void PutSweet()
{
Console.WriteLine(@"I put Sweetener on your coffee");
}
}
public class Program
{
public static void Main(string[] args)
{
List<AbstractCoffee> coffeesPrepared = new List<AbstractCoffee>();
MilkManager manager = new MilkManager();
AbstractCoffee coffeWithMilk = new CoffeeWithMilk(1);
AbstractCoffee coffeeWithChocolate = new CoffeeWithChocolate();
AbstractCoffee coffeeWithChocolateAndMilk = new CoffeeWithChocolateAndMilk(1);
coffeesPrepared.Add(coffeWithMilk);
coffeesPrepared.Add(coffeeWithChocolate);
coffeesPrepared.Add(coffeeWithChocolateAndMilk);
manager.Attach((IMilkSpent)coffeWithMilk);
manager.Attach((IMilkSpent)coffeeWithChocolateAndMilk);
coffeesPrepared.ForEach(c => c.MakeCoffee());
manager.NotifyMilkUsageTotal();
manager.NotifyMilkUsageTotal();
}
}
Aucun commentaire:
Enregistrer un commentaire