Я пытаюсь реализовать шаблон наблюдателя на C #, хотите знать, правильно ли я это сделал? - PullRequest
0 голосов
/ 21 мая 2018

Я очень новичок в Observer Pattern, мне показалось, что в некоторых случаях он очень полезен, поэтому я написал простой проект, я не уверен, что сделал это правильно или нет, любые предложения будут оценены.

class Program
    {
        public delegate void ProductAddedEventHandler(Object sender, ProductAddedEventArgs e);

        public class Products
        {
            private double subtotal;
            public event ProductAddedEventHandler ProductAdded;

            public void Add(Product product)
            {
                ProductModels model = new ProductModels();
                IEnumerable<Product> products = model.Products();
                IEnumerable<Product> new_Collection = products.Concat(new List<Product>() { product });

                Calculate calculate = new Calculate();
                this.subtotal = calculate.create(new_Collection);

                if (ProductAdded != null)
                {
                    ProductAddedEventArgs e = new ProductAddedEventArgs(subtotal);
                    ProductAdded(this, e);
                }

                Console.WriteLine("Subtotal Amount: {0}", subtotal);
            }
        }

        /// <summary>
        /// Calculate the Subtotal
        /// </summary>
        public class Calculate
        {
            public double create(IEnumerable<Product> products)
            {
                double result = 0;
                foreach (Product p in products)
                {
                    result += p.Price;
                }

                return result;
            }
        }

        public class ProductAddedEventArgs : EventArgs
        {
            public readonly double SubTotal;
            public ProductAddedEventArgs(double subtotal) => SubTotal = subtotal;
        }

        public class Shipping
        {
            const double Shipping_Rate = 0.05;

            public void create(Object sender, ProductAddedEventArgs e)
            {
                Console.WriteLine("Shipping Amount: {0}", e.SubTotal * Shipping_Rate);
            }
        }

        public class Discount
        {
            const double Discount_Rate = 0.2;
            public void create(Object sender, ProductAddedEventArgs e)
            {
                Console.WriteLine("Discount Amount: {0}", e.SubTotal * Discount_Rate);
            }
        }

        public class Tax
        {
            const double Tax_Rate = 0.07;

            public void create(Object sender, ProductAddedEventArgs e)
            {
                Console.WriteLine("Tax Amount: {0}", e.SubTotal * Tax_Rate);
            }
        }

        static void Main(string[] args)
        {

            Products products = new Products();
            Shipping shipping = new Shipping();
            Discount discount = new Discount();
            Tax tax = new Tax();

            products.ProductAdded += shipping.create;
            products.ProductAdded += discount.create;
            products.ProductAdded += tax.create;

            products.Add(new Product()
            {
                Id = 50,
                Name = "Watermelon",
                Price = 9.21
            });

        }
    }

Кстати, как получить общую сумму?

1 Ответ

0 голосов
/ 21 мая 2018

Хотя этот вопрос относится к https://codereview.stackexchange.com/, но я постараюсь написать краткий ответ.

Определение шаблона Observer из DoFactory (GOF),

Шаблон Observer определяет зависимость один-ко-многим между объектами, поэтому при изменении состояния одного объекта все его зависимостиуведомляется и обновляется автоматически.

В вашем примере вы не определили ни одного наблюдателя, вместо этого у вас есть события, которые изменяют состояние самого объекта.И в методе Add () слишком много ответственности или работы.

Примером Обозревателя может служить корзина покупок (электронная коммерция), например, при изменении количества товаров объект сводки заказов должен знать об этом и пересчитывать сводку (налоги, скидки, итого и т. Д.)..).Ниже приведен пример, в котором Сводка корзины и заказа обновляется как наблюдатель за элементами корзины.Он не идеален, но даст вам представление о шаблоне Observer:

class Product
{
    // Product properties
}

class ProductCollection
{
    private List<Observer> _observers = new List<Observer>();
    List<Product> _internalcol = new List<Product>();

    public void Attach(Observer observer)
    {
      _observers.Add(observer);
    }

    public void Detach(Observer observer)
    {
      _observers.Remove(observer);
    }

    public void Add(Product p)
    {
        _internalcol.Add(p)
        Notify();
    }

    public void Remove(Product p)
    {

    }

    private void Notify()
    {
      foreach (Observer o in _observers)
      {
        o.Update();
      }
    }
}

class Cart
{
    public ProductionCollection products = new ProductionCollection();
    public OrderSummary summary = new OrderSummary();

    public Cart()
    {
        products.Attach(new OrderSummary(products));
    }

    public void AddProduct(Product p, int count)
    {
        if(count > 1){
            foreach(int i in count){
                products.Add(p);
            }
        else if(count == 1){
            products.Add(p);
        }
        else if(count == 0)
        {
            products.Remove(p);
        }
    }
}

abstract class Observer()
{
    abstract void Update();
}

class OrderSummary: Observer
{
    ProductionCollection _products;

     // Constructor
    public OrderSummary(ProductionCollection products)
    {
        this._products = products;
    }

    public override void Update()
    {
      //Recalculate taxes, discount etc. here.
      // Update Summary object
    }

    public void GetSummary()
    {
        // return/print Summary object;
    }
}

class program
{
        static void Main(string[] args)
        {
            Cart c = new Cart();
            c.products.AddProduct(
                new Product()
                {
                    Id = 50,
                    Name = "Watermelon",
                    Price = 9.21
                });
        }
}

Возможно, он не скомпилируется. Я написал его в Блокноте.

...