Observer circuit used with decorator pattern

I want to create a program that makes an order entry system for drinks. (I will probably make a description, cost)

I want to use the Decorator pattern and the observer pattern. I made a UML drawing and saved it as a pic for easy viewing. This site will not allow me to upload doc as a word, so I have to upload pic. I hope it is easy to view.

I need to know if I am doing UML / design templates correctly before moving on to the coding part.

A drink is my abstract component class. Espresso, houseblend, darkroast are my specific subject classes ..

I also have a class of decorators for seasoning milk, mocha, soy, whip. would be my observer? because they will be interested in changes in data in value?

Now, will espresso, home trim, etc., be my SUBJECT, and will seasonings be my observer? My theory is that value is change and that seasonings should know change?

So subject = esspresso, houseblend, darkroast, etc. // they have a cost ()

Observer = milk, mocha, soy, whip? // they have a cost ()

will there be specific ingredients and milk, mocha, soy, whip? will be a decorator!

So, following good software development practice, “design an interface, not an implementation” or “define things that change from those that don’t”

Do I need a costbehavior interface?

If you look at UML, you will see where I am going and see if I use the observer + Decorator pattern correctly? I think the decorator is right.


pic , :

( , , , )

espresso, houseblend, darkroast, decaf (, getdescription, setcost, costchanged)

()//?

costbehavior (cost)//, ?

(getdescription)

, 2 : , , , (, getdescription, ) decorator/wrapper.

..

alt text

?

+3
3

, , . .

:

  • CondimentDecorator . UML. -, . - . .
  • , , , ? .
  • # 2 getDescription... ? - , . .
  • , , ? . , (/). , - , . gung-ho -, . , . :).

, " " (, , :), ) .

, . - . ( , -). - StarBuck, , - , , , .

drink.cs, csc (C:\Windows\Microsoft.Net\Framework\v3....\csc/target: exe/out:drink.exe drink.cs ) VS - :).

using System;
using System.Collections.Generic;

public interface IBeverage
{
  string GetDescription();
  decimal GetCost();
}

public abstract class Beverage : IBeverage
{
  protected string _name;
  protected decimal _cost;

  public Beverage(string name, decimal cost)
  {
     _name = name;
     _cost = cost;
  }

  public virtual string GetDescription()
  {
    return _name;
  }

  public virtual decimal GetCost()
  {
    return _cost;
  }
}

public class Macchiato : Beverage
{
  public Macchiato() : base("Macchiato", 3.50m) {}
}

public abstract class BeverageDecorator : Beverage
{
  IBeverage _baseBeverage;

  public BeverageDecorator(IBeverage baseBeverage) : base("", 0m)
  {
    _baseBeverage = baseBeverage;
  }

  public override string GetDescription()
  {
    return _name + " " + _baseBeverage.GetDescription();
  }

  public override decimal GetCost()
  {
    return _cost + _baseBeverage.GetCost();
  }
}

public class Caramel : BeverageDecorator
{
  public Caramel(IBeverage baseBeverage) : base(baseBeverage) 
  {
     _name = "Caramel";
     _cost = 0.50m;
  }
}

public class Venti : BeverageDecorator
{
  public Venti(IBeverage baseBeverage) : base(baseBeverage)
  {
     _name = "Venti";
     _cost = 1.00m;
  }
}

public class Iced : BeverageDecorator
{
  public Iced(IBeverage baseBeverage) : base(baseBeverage)
  {
    _name = "Iced";
    _cost = 0.25m;
  }
}

public class Order
{
  IBeverage _beverage;
  IPager _pager;

  public Order(IBeverage beverage, IPager pager)
  {
    _beverage = beverage;
    _pager = pager;
  }

  public IPager Pager
  {
    get { return _pager; }
  }

  public IBeverage Beverage
  {
    get { return _beverage; }
  }
}

public class OrderProcessing
{
    Queue<Order> orders = new Queue<Order>();

    public void NewOrder(IBeverage beverage, IPager pager)
    {
      orders.Enqueue(new Order(beverage, pager));
    }

    public void ProcessOrder()
    {
      if (orders.Count > 0)
      {
        var order = orders.Dequeue();
        order.Pager.Update(order);
      }
    }
}

public interface IPager
{
  void Update(Order order);
}

public class VibratingPager : IPager
{
  string _number;

  public VibratingPager(string number)
  {
    _number = number;
  }

  public void Update(Order order)
  {
    Console.WriteLine("BUZZZ");
    Console.WriteLine("Your {0} is ready.  Please pay {1} at the cashier after picking it up.", order.Beverage.GetDescription(),order.Beverage.GetCost());
  }
}

public class Program
{
  public static void Main(string[] args)
  {  
    var orders = new OrderProcessing();
    var pager1 = new VibratingPager("1");
    var pager2 = new VibratingPager("2");    

    orders.NewOrder(new Iced(new Venti(new Caramel(new Macchiato()))), pager1);
    orders.NewOrder(new Venti(new Macchiato()), pager2);

    orders.ProcessOrder();
    orders.ProcessOrder();
  }
}
+1

, , , . , UML, ? , type/attribute, "cost-detail", .

+1

. . , . , - , . , , , , . , , , .

, , , . , , -, ( ), . , , .


:

, , . , , . . , . ( , , ) ... .

, . , , :

struct message
{
  virtual void print() = 0;
};

struct concrete_message : message
{
  void print() { std::cout << my_message << std::endl; }
};

, , . , "", :

struct tabbed_message
{
  tabbed_message(message * msg) : my_message(msg) {}
  void print() { std::cout << "\t; my_message->print(); }
};

, - ?

What you have with your coffee / seasoning is not like that. Seasonings are what you put in coffee. There is no difference in behavior between a cup of coffee with or without cream (for example). If you want to charge for cream, then you simply link it to a cup of coffee and complete the total when you ask the cup how much it is.

0
source

Source: https://habr.com/ru/post/1785565/