/// <summary> /// # Motivation /// I can now attach responsibilities to an object dynamically to add behaviour at runtime. /// /// # Structure /// Beverage /// --> base class so all objects are of same type /// CondimentDecorator : Bevarage /// --> interchangeable with Beverage /// /// # Sample Problem /// A coffee shop wants to make an ordering system for all their drinks. Ofcourse there are a lot of combination with condiments/roasts. /// We could create a base class and let all possible combinations inherit from the superclass and override their behaviour, but that would quickly become a mess. /// /// # Solution /// By creating a Decorator class which inherits from the baseclass (to effectively swap between types), I can now dynamically create composite objects at runtime. /// To add a drink to the system: /// 1. inherit from the base class, set instance fields in constructor /// 2. override the 'Cost()' method to return desired cost /// To add a condiment to the system: /// 1. inherit from 'CondimentDecorator' (indirectly from base class as well /// 2. add instance field from type Beverage /// 3. initialize in constructor /// 4. override GetDescription() and Cost() accordingly /// To create a composite object at runtime: /// 1. Create a new instance of a drink (Beverage) /// 2. To add a condiment, assign the instance to a new instance of the condiment with itself as param /// A. Beverage darkRoast = new DarkRoast(); /// B. darkRoast = new Mocha(darkRoast); /// </summary> public void Test() { Beverage beverage = new Espresso(); Console.WriteLine($"{beverage.GetDescription()} ${beverage.Cost()}"); Beverage beverage1 = new DarkRoast(); beverage1 = new Mocha(beverage1); Console.WriteLine($"{beverage1.GetDescription()} ${beverage1.Cost()}"); Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); Console.WriteLine($"{beverage2.GetDescription()} ${beverage2.Cost()}"); Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); Console.WriteLine($"{beverage3.GetDescription()} ${beverage3.Cost()}"); }
static void Main(string[] args) { #region Using ObserverPattern WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay display = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); #endregion #region Using Strategy pattern Duck duck = new Duck(); duck.setFlyBehavior(new FlyWithWings()); duck.setQuackBehavior(new Quack()); duck.performFly(); duck.performQuack(); Duck duck2 = new Duck(); duck2.setFlyBehavior(new FlyWithWings()); duck2.setQuackBehavior(new Squeakcs()); duck2.performQuack(); duck2.performFly(); #endregion #region Using Decorator pattern Beverage beverage = new Espresso(); Console.WriteLine(beverage.GetDescription() + " $" + beverage.cost()); Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); Console.WriteLine(beverage2.GetDescription() + " $" + beverage2.cost()); Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); Console.WriteLine(beverage3.GetDescription() + " $" + beverage3.cost()); #endregion // Don't close console on program end Console.ReadKey(); }
/// <summary> /// O padrão Decorator anexa responsabilidades adicionais a um objeto dinamicamente. Os decoradores fornecem uma alternativa mais flexível de /// subclasses para estender a funcionalidade. /// </summary> private static void TestDecorator() { Beverage beverage = new Espresso(); Console.WriteLine("{0}: {1}", beverage.Description, beverage.Cost()); Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); Console.WriteLine("{0}: {1}", beverage2.Description, beverage2.Cost()); Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); Console.WriteLine("{0}: {1}", beverage3.Description, beverage3.Cost()); }
private static void Decorator() { Beverage oBeverage2 = default(Beverage); oBeverage2 = new DarkRoast(); //Agrega condimentos (tecnica Composition) oBeverage2 = new Mocha(oBeverage2); oBeverage2 = new Mocha(oBeverage2); oBeverage2 = new Whip(oBeverage2); Console.WriteLine(oBeverage2.getFullDescription() + " $" + oBeverage2.getTotalCost()); Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); beverage3 = new Whip(beverage3); //Console.WriteLine(beverage3.getFullDescription() + " $" + beverage3.getTotalCost()); Console.Read(); }