Вопрос по подходу к реализации паттерна стратегия c#
От: corpse56  
Дата: 05.12.19 17:43
Оценка:
Здравствуйте!
Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)
Задача такая. Есть магазин, который продаёт товары. Каждый товар должен продаваться по своему алгоритму. Было решено применить паттерн стратегия. Получилось два варианта. Какой из них более правильный я не пойму. Я приведу оба примера и опишу что смущает.
Вариант 1. Логику продажи каждого товара инкапсулируем в класс магазина, который наследуем от интерфейса:
using System;                    
public class Program
{
    public static void Main()
    {
        Shop shop = new Shop();
        var a = new A("A");
        shop.Sell(a);
        var b = new B("B");
        shop.Sell(b);
    }
}
interface IShop
{
    void Sell(A a);
    void Sell(B b);
}
class baseClass
{
    public string Name;
}
class A : baseClass
{
    public A(string s)
    {
        this.Name = s;
    }
}
class B : baseClass
{
    public B(string s)
    {
        this.Name = s;
    }    
}
class Shop : IShop
{
    public void Sell(A a)
    {
        Console.WriteLine("sell AAA"+a.Name);
    }
    public void Sell(B b)
    {
        Console.WriteLine("sell BBB"+b.Name);
    }
}

Здесь смущает то, что класс магазина будет большой, и должен описывать схему продажи (и не только) каждого товара.

Вариант 2. Логику продажи каждого товара икапсулируем в сам товар:
using System;
using System.Collections.Generic;                    
public class Program
{
    public static void Main()
    {
        List<baseClass> list = new List<baseClass> { new A("A"), new B("B"), new B("B"), new A("A") };
        Shop shop = new Shop();
        foreach(baseClass item in list)
        {
            shop.seller = item.seller;
            shop.seller.Sell(item);//это эквивалентно    item.seller.Sell(item);
        }
    }
}

class Shop
{
    public ISellable seller;
}

interface ISellable
{
    void Sell(baseClass a);
}
class baseClass
{
    public string Name;
    public ISellable seller;
}
class A : baseClass
{
    
    public A(string s)
    {
        this.Name = s;
        seller = new SellerA();
    }
    
}
class B : baseClass
{
    public B(string s)
    {
        this.Name = s;
        seller = new SellerB();
    }    
    
}
class SellerA : ISellable
{
    public void Sell(baseClass a)
    {
        Console.WriteLine("sell AAA"+a.Name);
    } 
}
class SellerB : ISellable
{
    public void Sell(baseClass b)
    {
        Console.WriteLine("sell BBB"+b.Name);
    } 
}

Здесь смущает то, что продаёт-то магазин! А не товар сам себя продаёт! shop.seller.Sell(item); === item.seller.Sell(item); Зачем тогда класс магазина вообще нужен? Нет, ну, конечно, я описываю абстрактную ситуацию, и класс магазина описывает ещё полно всякого поведения и параметров. Но в данном конкретном примере получается, что товар продаёт сам себя. И только искусственно если добавить ссылку в магазин на интервейс, то типа будет выглядеть как-будто продаёт магазин. Ещё смущает то, что нужно присваивать каждый раз нужный интерфейс перед продажей. Ну или не присваивать, а сказать товару, чтобы продал сам себя, а он ещё и ссылку на себя получает.

Я понимаю, что вопрос тот ещё. Но может всё-таки я где-то блуждаю не там?
Что можно сказать про "магазин"? Типов товаров будет немного, всего около 7-8. Ещё магазин должен будет каждый товар уметь принимать на склад, принимать бракованый товар назад, отсылать товар в ремонт и т.д.
Даже этот список дейтсвий помножить на 7 получится ~30 методов в IShop для первого примера. А для второго примера получится, что не магазин управляет товаром, а товар управляет сам собой ...
Лично мне больше нравится второй пример, если б не то обстоятельство, что товар сам себя "обслуживает". Или это нормально? Посоветуйте, пожалуйста, что-нибудь! Может другой паттерн или где-то я ошибся в реализации?
использую c#
Спасибо.
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: Carc Россия https://vk.com/gosha_mazov
Дата: 05.12.19 19:41
Оценка: 2 (1) +1
Здравствуйте, corpse56, Вы писали:

C>Здравствуйте!

C>Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)C>Спасибо.

По моему тут не через паттерн "стратегия" нужно делать, а через паттерн "визитер".

Или же заводить еще один интерфейс "покупка" (ну или "продажа"), который завязан на два других интерфейса. "Магазин" и "товар". Через параметры, или ссылки.

Явно же напрашивается третья сущность…
Aml Pages Home
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: Qulac Россия  
Дата: 05.12.19 21:21
Оценка: +1
Здравствуйте, corpse56, Вы писали:

C>Здравствуйте!

C>Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)
C>Задача такая. Есть магазин, который продаёт товары. Каждый товар должен продаваться по своему алгоритму. Было решено применить паттерн стратегия.
C>использую c#
C>Спасибо.

Стратегия используется тогда, когда способ может меняться "динамически", т.е. товар продавался одним способом, а потом этот способ поменяли на другой. Если один тип товара всегда продается одним и тем же способом, то стратегия не нужна.
Программа – это мысли спрессованные в код
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: samius Япония http://sams-tricks.blogspot.com
Дата: 05.12.19 22:08
Оценка: 1 (1) +1
Здравствуйте, corpse56, Вы писали:

C>Здравствуйте!

C>Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)
C>Задача такая. Есть магазин, который продаёт товары. Каждый товар должен продаваться по своему алгоритму. Было решено применить паттерн стратегия. Получилось два варианта. Какой из них более правильный я не пойму. Я приведу оба примера и опишу что смущает.
Дело не в паттерне или подходе. Сперва нужно сформулировать проблему. В условии я вижу предпосылку для применения стратегии, но проблемы в нем не содержится. "Каждый товар должен продаваться по своему алгоритму". Это лишь слова, а не способ реализации. Из слов "товар должен продаваться" не следует что у товара будет метод "ПродайСебя". Включим фантазию и представим, что надо продавать 3 единицы по цене двух. У какой из 3-х единиц вызывать метод продажи? Почему это вообще метод товара?

C>Здесь смущает то, что продаёт-то магазин! А не товар сам себя продаёт! shop.seller.Sell(item); === item.seller.Sell(item); Зачем тогда класс магазина вообще нужен? Нет, ну, конечно, я описываю абстрактную ситуацию, и класс магазина описывает ещё полно всякого поведения и параметров. Но в данном конкретном примере получается, что товар продаёт сам себя. И только искусственно если добавить ссылку в магазин на интервейс, то типа будет выглядеть как-будто продаёт магазин. Ещё смущает то, что нужно присваивать каждый раз нужный интерфейс перед продажей. Ну или не присваивать, а сказать товару, чтобы продал сам себя, а он ещё и ссылку на себя получает.


Вот это хорошо, что смущает. Оно и должно смущать. Это должно привести к постановке вопросов: А что же должно продавать-то? И почему, собственно, товар должен нести в себе поведение по продаже себя? Кто будет добавлять методы в код при приеме магазином нового товара, когда программист сдал программу и отвалил?

C>Я понимаю, что вопрос тот ещё. Но может всё-таки я где-то блуждаю не там?

C>Что можно сказать про "магазин"? Типов товаров будет немного, всего около 7-8. Ещё магазин должен будет каждый товар уметь принимать на склад, принимать бракованый товар назад, отсылать товар в ремонт и т.д.
А могло бы быть 7-8 тысяч товаров. Разве должен код софта магазина быть заточен на малое кол-во товаров? И ту не понятно, почему разные алгоритмы приема на склад? Пришел и ладно.

C>Даже этот список дейтсвий помножить на 7 получится ~30 методов в IShop для первого примера. А для второго примера получится, что не магазин управляет товаром, а товар управляет сам собой ...

C>Лично мне больше нравится второй пример, если б не то обстоятельство, что товар сам себя "обслуживает". Или это нормально? Посоветуйте, пожалуйста, что-нибудь! Может другой паттерн или где-то я ошибся в реализации?
Это вообще реальная задача, или упражнение на тему "придумайте, куда присобачить стратегию в магазине"?
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: Sharov Россия  
Дата: 06.12.19 09:56
Оценка:
Здравствуйте, corpse56, Вы писали:

C>Я понимаю, что вопрос тот ещё. Но может всё-таки я где-то блуждаю не там?

C>Что можно сказать про "магазин"? Типов товаров будет немного, всего около 7-8. Ещё магазин должен будет каждый товар уметь принимать на склад, принимать бракованый товар назад, отсылать товар в ремонт и т.д.
C>Даже этот список дейтсвий помножить на 7 получится ~30 методов в IShop для первого примера. А для второго примера получится, что не магазин управляет товаром, а товар управляет сам собой ...
C>Лично мне больше нравится второй пример, если б не то обстоятельство, что товар сам себя "обслуживает". Или это нормально? Посоветуйте, пожалуйста, что-нибудь! Может другой паттерн или где-то я ошибся в реализации?
C>использую c#
C>Спасибо.

А почему не:

class Shop : IShop
{
    public void Sell(ISeller seller)
    {

    }
}


Товары продавать должен все-таки магазин, но у каждого товара может быть своя специфика.
Кодом людям нужно помогать!
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: Vladek Россия Github
Дата: 06.12.19 12:41
Оценка: 1 (1) -2
Здравствуйте, corpse56, Вы писали:

C>Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)

C>Задача такая. Есть магазин, который продаёт товары. Каждый товар должен продаваться по своему алгоритму. Было решено применить паттерн стратегия. Получилось два варианта. Какой из них более правильный я не пойму. Я приведу оба примера и опишу что смущает.
C>Вариант 1. Логику продажи каждого товара инкапсулируем в класс магазина, который наследуем от интерфейса:
C>Здесь смущает то, что класс магазина будет большой, и должен описывать схему продажи (и не только) каждого товара.

C>Вариант 2. Логику продажи каждого товара икапсулируем в сам товар:

C>Здесь смущает то, что продаёт-то магазин! А не товар сам себя продаёт! shop.seller.Sell(item); === item.seller.Sell(item); Зачем тогда класс магазина вообще нужен? Нет, ну, конечно, я описываю абстрактную ситуацию, и класс магазина описывает ещё полно всякого поведения и параметров. Но в данном конкретном примере получается, что товар продаёт сам себя. И только искусственно если добавить ссылку в магазин на интервейс, то типа будет выглядеть как-будто продаёт магазин. Ещё смущает то, что нужно присваивать каждый раз нужный интерфейс перед продажей. Ну или не присваивать, а сказать товару, чтобы продал сам себя, а он ещё и ссылку на себя получает.

В ООП товар продаёт сам себя, потому что только сам товар располагает всей нужной информацией о сделке. Моделировать продажу можно как угодно, но в рамках ООП поведение и состояние должны быть вместе — причём, всё определяется здравым смыслом, а не догмами и канонами. Смысл в том, чтобы писать компактный код, который решает задачу и удобен для изменений в будущем. Если абстракции нет места, то она не нужна — поэтому такого класса как Магазин может и не быть вовсе.

Выглядеть это должно так: у класса товара должен быть метод Sell, в который передаётся только необходимая информация для завершения сделки. Реализация этого метода может быть любой: например, товар знает к какой категории он относится и уже передаёт управление ей для продажи. Отдельная категория товаров реализует свой метод продажи.

C>Я понимаю, что вопрос тот ещё. Но может всё-таки я где-то блуждаю не там?

C>Что можно сказать про "магазин"? Типов товаров будет немного, всего около 7-8. Ещё магазин должен будет каждый товар уметь принимать на склад, принимать бракованый товар назад, отсылать товар в ремонт и т.д.

Абстракции не обязаны быть универсальными. Если есть класс Товара, который нужен для продаж, это не значит, что на него надо обязательно натягивать логику для ведения складского учёта. Это может быть отдельная абстракция, которая тоже называется товаром (конфликтов имён конечно лучше избегать), но содержит совсем другое поведение и состояние, имеющее смысл только в рамках управления складом. В реальности у нас одна кофемолка, но в коде у нас её могут обслуживать пять разных абстракций.

C>Даже этот список дейтсвий помножить на 7 получится ~30 методов в IShop для первого примера. А для второго примера получится, что не магазин управляет товаром, а товар управляет сам собой ...


В адекватных решаемой задаче абстракциях количество публичных методов небольшое, код становится логичным и лаконичным.
Re[2]: Вопрос по подходу к реализации паттерна стратегия c#
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.12.19 12:45
Оценка:
Здравствуйте, Vladek, Вы писали:

V>В ООП товар продаёт сам себя, потому что только сам товар располагает всей нужной информацией о сделке. Моделировать продажу можно как угодно, но в рамках ООП поведение и состояние должны быть вместе — причём, всё определяется здравым смыслом, а не догмами и канонами. Смысл в том, чтобы писать компактный код, который решает задачу и удобен для изменений в будущем. Если абстракции нет места, то она не нужна — поэтому такого класса как Магазин может и не быть вовсе.


V>Выглядеть это должно так: у класса товара должен быть метод Sell, в который передаётся только необходимая информация для завершения сделки. Реализация этого метода может быть любой: например, товар знает к какой категории он относится и уже передаёт управление ей для продажи. Отдельная категория товаров реализует свой метод продажи.


Если нужно продать 3 товара по цене двух, то у какого из них вызывать метод Sell?
Re[3]: Вопрос по подходу к реализации паттерна стратегия c#
От: Vladek Россия Github
Дата: 06.12.19 13:08
Оценка: -1
Здравствуйте, samius, Вы писали:

S>Если нужно продать 3 товара по цене двух, то у какого из них вызывать метод Sell?


Один объект, один вызов. Разумно предположить, что этот объект представляет сразу сам товар, и его количество, и все дополнительные правила продажи.
Re[4]: Вопрос по подходу к реализации паттерна стратегия c#
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.12.19 13:49
Оценка: 1 (1)
Здравствуйте, Vladek, Вы писали:

V>Здравствуйте, samius, Вы писали:


S>>Если нужно продать 3 товара по цене двух, то у какого из них вызывать метод Sell?


V>Один объект, один вызов. Разумно предположить, что этот объект представляет сразу сам товар, и его количество, и все дополнительные правила продажи.

А если акция распространяется не на товар, а на подмножество товаров? За веревку и мыло туалетная бумага в подарок Разумно предположить, что вызывая метод Sell у веревки, мыла и бумаги по отдельности, условия акции мы не сможем проверить. Да и какой из товаров должен будет знать о наличии акции на все 3?
Re[5]: Вопрос по подходу к реализации паттерна стратегия c#
От: Vladek Россия Github
Дата: 06.12.19 13:58
Оценка: -1
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Vladek, Вы писали:


V>>Здравствуйте, samius, Вы писали:


S>>>Если нужно продать 3 товара по цене двух, то у какого из них вызывать метод Sell?


V>>Один объект, один вызов. Разумно предположить, что этот объект представляет сразу сам товар, и его количество, и все дополнительные правила продажи.

S>А если акция распространяется не на товар, а на подмножество товаров? За веревку и мыло туалетная бумага в подарок Разумно предположить, что вызывая метод Sell у веревки, мыла и бумаги по отдельности, условия акции мы не сможем проверить. Да и какой из товаров должен будет знать о наличии акции на все 3?

Значит надо моделировать корзину товаров, которая умеет выбирать нужную акцию в зависимости от сочетания товаров. Абстракция должна быть адекватной, а не универсальной.
Re[6]: Вопрос по подходу к реализации паттерна стратегия c#
От: Carc Россия https://vk.com/gosha_mazov
Дата: 06.12.19 14:21
Оценка: 1 (1) +1
Здравствуйте, Vladek, Вы писали:



S>>А если акция распространяется не на товар, а на подмножество товаров? За веревку и мыло туалетная бумага в подарок Разумно предположить, что вызывая метод Sell у веревки, мыла и бумаги по отдельности, условия акции мы не сможем проверить. Да и какой из товаров должен будет знать о наличии акции на все 3?


V>Значит надо моделировать корзину товаров, которая умеет выбирать нужную акцию в зависимости от сочетания товаров. Абстракция должна быть адекватной, а не универсальной.

samius Вам дело говорит… Ни к чему здесь всё тащить в товар! Тут явно есть третья сущность, как уже писал выше.
Ну не может товар знать на складе он, или уже как списанка на помойке лежит — ибо ему это не нужно. Опять же как себя продать — товар не должен знать, не его ответственность — у него только набор характеристик: чего, сколько, вес в храммах, толщина, ширина, срок годности ну и цена само собой.

Третья сущность (объект, интерфейс)
Условно назовем ее "сделка" (дабы не спорить "продажа" или "покупка").

Вот к ней, к третьей сущности, и применимы все другие параметры.

Например:
1) Была скидка или нет.
2) Товар с доставкой или нет.
3) "Сделка" (продажа) отменена или нет (товар не доставлен, клиент отказался и.т.д.)

А пихать все в "товар" это просто нарушение абстракции.
Товар не может знать как себя продать, потому как сам себя товар не продает.

Товар вообще всего лишь сущность описывающая сам товар: что это? Диван? Лицензионный ключик для софта? Жратва из Яндекс-Кушать?
Т.е. набор атрибутов, в том числе и цена.

А все остальное уже разруливает эта самая третья сущность — "сделка"

Наример
1) Есть ли скидка (проверяет где-то там в объекте "магазин".
2) Можно ли вообще продать? (к примеру, есть ли на складе).
3) Статус сделки. Например: "товар доставлен", "нет на складе", "в обработке" и.т.д.

Иначе действительно вермишель получается — все в одну кучу.
А эта самая "сделка" по сути своей композит — всё увязывает в единое целое. Дергая другие объекты ("склад" есть ли вообще), "акции" (давать ли скидку), способ оплаты (принимаем монгольские тугры, или берем только мешками репчатого лука)…
Aml Pages Home
Отредактировано 06.12.2019 14:22 Carc . Предыдущая версия .
Re[6]: Вопрос по подходу к реализации паттерна стратегия c#
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.12.19 15:43
Оценка:
Здравствуйте, Vladek, Вы писали:

V>Здравствуйте, samius, Вы писали:


S>>А если акция распространяется не на товар, а на подмножество товаров? За веревку и мыло туалетная бумага в подарок Разумно предположить, что вызывая метод Sell у веревки, мыла и бумаги по отдельности, условия акции мы не сможем проверить. Да и какой из товаров должен будет знать о наличии акции на все 3?


V>Значит надо моделировать корзину товаров, которая умеет выбирать нужную акцию в зависимости от сочетания товаров. Абстракция должна быть адекватной, а не универсальной.


Согласен. Так гораздо гибче, чем товар.Продайся().
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: Слава  
Дата: 06.12.19 17:25
Оценка: 9 (1) +1 :)
Здравствуйте, corpse56, Вы писали:

C>Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)


Потому что по-факту, когда анализ бизнес-процессов показывает, что процессов нет — у тебя ДОКУМЕНТ НИ О ЧЁМ.
А когда ты имеешь документ ни о чём — ты спокойно называешь его "СТРАТЕГИЯ".

  источник
https://sapforum.pro/forum/viewtopic.php?f=18&amp;t=15784&amp;start=1725
https://youtu.be/KF4g_Ks3d4I

Извините, музыкой навеяло. Может вы вообще не тот путь выбрали, в 2019 году какие-то "стратегии" вспоминать из дремучих С++ начала 90х? Это при наличии Action и Func, и при том, что "стратегии" продаж будут конфигурироваться в конфигурации, в GUI. И вам скорее всего потребуется нечто вроде интерпретатора правил.
Отредактировано 06.12.2019 17:27 Слава . Предыдущая версия .
Re[7]: Вопрос по подходу к реализации паттерна стратегия c#
От: Vladek Россия Github
Дата: 06.12.19 18:37
Оценка: 1 (1)
Здравствуйте, Carc, Вы писали:

C>Здравствуйте, Vladek, Вы писали:




S>>>А если акция распространяется не на товар, а на подмножество товаров? За веревку и мыло туалетная бумага в подарок Разумно предположить, что вызывая метод Sell у веревки, мыла и бумаги по отдельности, условия акции мы не сможем проверить. Да и какой из товаров должен будет знать о наличии акции на все 3?


V>>Значит надо моделировать корзину товаров, которая умеет выбирать нужную акцию в зависимости от сочетания товаров. Абстракция должна быть адекватной, а не универсальной.

C>samius Вам дело говорит… Ни к чему здесь всё тащить в товар! Тут явно есть третья сущность, как уже писал выше.

C>Ну не может товар знать на складе он, или уже как списанка на помойке лежит — ибо ему это не нужно.

Откуда это утверждение?
C>Опять же как себя продать — товар не должен знать, не его ответственность — у него только набор характеристик: чего, сколько, вес в храммах, толщина, ширина, срок годности ну и цена само собой.

Я уже написал, что поведение и состояние в ООП должны быть вместе. А во всём остальном — никто никому ничего не должен. Абстракция должна быть удобной, от этого зависит лаконичность и выразительность кода, который обслуживает эту абстракцию.

C>Третья сущность (объект, интерфейс)

C>Условно назовем ее "сделка" (дабы не спорить "продажа" или "покупка").
Что повлекло её добавление?

C>Вот к ней, к третьей сущности, и применимы все другие параметры.


C>Например:

C>1) Была скидка или нет.
C>2) Товар с доставкой или нет.
C>3) "Сделка" (продажа) отменена или нет (товар не доставлен, клиент отказался и.т.д.)

Что значит применимы параметры? Это какая-то деталь, выточенная на станке по шаблону, что к ней можно применять какие-то параметры?

C>А пихать все в "товар" это просто нарушение абстракции.


Абстракция — чистая идея, выраженная в коде. Что такое нарушение абстракции, если она может быть любой, а её критерии отбора я уже указал: адекватность решаемой задачи, удобство использования.

C>Товар не может знать как себя продать, потому как сам себя товар не продает.


Откуда это ограничение проистекает?

C>Товар вообще всего лишь сущность описывающая сам товар: что это? Диван? Лицензионный ключик для софта? Жратва из Яндекс-Кушать?

C>Т.е. набор атрибутов, в том числе и цена.

C>А все остальное уже разруливает эта самая третья сущность — "сделка"


C>Наример

C>1) Есть ли скидка (проверяет где-то там в объекте "магазин".
C>2) Можно ли вообще продать? (к примеру, есть ли на складе).
C>3) Статус сделки. Например: "товар доставлен", "нет на складе", "в обработке" и.т.д.

C>Иначе действительно вермишель получается — все в одну кучу.

C>А эта самая "сделка" по сути своей композит — всё увязывает в единое целое. Дергая другие объекты ("склад" есть ли вообще), "акции" (давать ли скидку), способ оплаты (принимаем монгольские тугры, или берем только мешками репчатого лука)…

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

Ещё раз: универсальность не нужна, нужна адекватность. Универсальность абстракций ведёт к росту спонтанной сложности программы.

Brooks distinguishes between two different types of complexity: accidental complexity and essential complexity. Accidental complexity relates to problems which engineers create and can fix; for example, the details of writing and optimizing assembly code or the delays caused by batch processing. Essential complexity is caused by the problem to be solved, and nothing can remove it; if users want a program to do 30 different things, then those 30 things are essential and the program must do those 30 different things.

Re[8]: Вопрос по подходу к реализации паттерна стратегия c#
От: Carc Россия https://vk.com/gosha_mazov
Дата: 06.12.19 19:09
Оценка:
Здравствуйте, Vladek, Вы писали:


C>>Ну не может товар знать на складе он, или уже как списанка на помойке лежит — ибо ему это не нужно.

V>Откуда это утверждение?

Потому что "на складе", "не на складе" это не свойство объекта "товар".
Здесь типичная композиция — HasIs.
В данном случае это как раз свойство объекта "склад".
Т.е. это "склад" владеет "товаром", а не свойство "товара" — "на складе" или "нет".
Aml Pages Home
Re[8]: Вопрос по подходу к реализации паттерна стратегия c#
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.12.19 19:19
Оценка: 1 (1) +1
Здравствуйте, Vladek, Вы писали:

V>Я уже написал, что поведение и состояние в ООП должны быть вместе.

Что именно значит "вместе"? И откуда это следует?
Re[8]: Вопрос по подходу к реализации паттерна стратегия c#
От: Carc Россия https://vk.com/gosha_mazov
Дата: 06.12.19 19:21
Оценка: 1 (1) +2
Здравствуйте, Vladek, Вы писали:

V>Здравствуйте, Carc, Вы писали:


C>>Третья сущность (объект, интерфейс)

C>>Условно назовем ее "сделка" (дабы не спорить "продажа" или "покупка").
V>Что повлекло её добавление?

Потому что у "сделки" ("продажи", "покупки" или как там назовем) есть свои собственное свойства. Которых нет у других (магазин, товар).

Тот же состояние "сделки" (завершена, в обработке, отменена).
Те же скидки применяются именно к "сделке", а не к товару. Потому что условие "скидки" может быть значительно с более сложной логикой.

Например, сегодня скидки есть, завтра нет. Скидка есть если товаров больше икс заказано, или у покупателя есть код купона. Или это старинный клиент и него по жизни "скидка". И.т.д.

И куда все это вкладывать хотите? В товар?
С какого? В случае тех же скидок сегодня\завтра\больше 3-х заказанных — каким боком это относится к "товару"? Никаким.

Тогда, допустим сделаем эти скидки свойством "магазина"… Тоже каким боком?
А если, скидка для старинного клиента (да та же скидка для продления лицензии на софт к примеру).
Причем тут весь объект\интерфейс "магазин"?

Все подобные вещи координируются не одним объектом\интерфейсом, а отношениями между несколькими объектами\интерфейсами.

Вот эти взаимоотношения и может инкапсулировать отдельная сущность — "сделка"
Aml Pages Home
Re[8]: Вопрос по подходу к реализации паттерна стратегия c#
От: Carc Россия https://vk.com/gosha_mazov
Дата: 06.12.19 19:39
Оценка: +1
Здравствуйте, Vladek, Вы писали:
V>Абстракция — чистая идея, выраженная в коде.

Абстракция должна быть абстрактной. А удобной она быть и вовсе не обязана.
Удобным должен быть интерфейс к ее свойствам.

Главное в абстрации ничего лишнего. А то это как раз и будет взрывной рост сложности.

Про тот же пример: что значит метод "Товар.ПродайСебя"?

А цена (со скидками или без)? Откуда "Товар…" Знает про скидки?
А есть ли товар в наличии? (на складе или отсутствует). Откуда сущность "товар" может знать на складе она или нет.

V>Что такое нарушение абстракции, если она может быть любой, а её критерии отбора я уже указал: адекватность решаемой задачи, удобство использования.

Где тут в обсуждении было "любая абстракция"?

Была только третья сущность — "сделка".

А "удобство использования" это и вовсе "в огороде бузина, а в Киеве дядька".
Чтобы скрыть детали, и сделать более удобным использование используют другие паттерны: Facade, Slice.
Но они не части самой абстракции..

В общем, Вам тут хорошо посоветовали. Пока Вы будете пытаться моделировать объекты, а не бизнес-процессы — у Вас будет получаться все эта муть.

Если приглядеться, процессы и так торчат отовсюду в вашем изначальном варианте. Только криво и сбоку: "Товар.ПродайСебя", "Корзина.ПримениСкидку" .

Имхо, здесь нужно моделировать процессы, а "товары", "скидки", "магазины", "скады" будут их аргументами. Аргументами сущности, которая моделирует процесс. В моем примере, это может быть сущность "сделка".

А не наоборот. Тогда все начнет более-менее вставать на свои места.
Aml Pages Home
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: Cyberax Марс  
Дата: 07.12.19 08:41
Оценка: +5
Здравствуйте, corpse56, Вы писали:

C>Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия.

Это вопрос чисто теоретический или практический?

Если практический, то не используем никаких нафиг там стратегий, а пишем тупой код с if'ами для разных типов товаров. После того, как будут написаны (как минимум) продажи для 3 типов товаров, то смотрим, что можно объединить и абстрагировать.
Sapienti sat!
Re: Вопрос по подходу к реализации паттерна стратегия c#
От: v.a.v СССР  
Дата: 07.12.19 10:19
Оценка: 2 (2)
Здравствуйте, corpse56, Вы писали:

C>Здравствуйте!

C>Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)
C>Задача такая. Есть магазин, который продаёт товары. Каждый товар должен продаваться по своему алгоритму. Было решено применить паттерн стратегия. Получилось два варианта. Какой из них более правильный я не пойму.

Возможно стоит применить таблицу правил.
Если у вас именно "магазин, который продаёт товары", то есть каждый товар подается отдельно, тогда применяем таблицу правил продажи к "товар"("товар" далее называем "контекст продажи").
Если предусмотрен некий контекст (корзина покупателя, сделка ..),тогда применяем таблицу правил продажи к "корзина покупателя"("корзина покупателя" далее называем "контекст продажи").
Таблица правил в простой реализации, это список состоящий из экземпляров класса "правило".
При продаже проходим по таблице правил и применяем первое, которые удовлетворяет текущему "контекст продажи".
Класс "правило" содержит поля "предикат" и "действие".
"предикат" принимает на вход "контекст продажи", и возвращает результат (bool), как необходимость применения правила.
"действие" также принимает на вход "контекст продажи" и выполняет действие(например формирует или изменяет объект класса "товарная накладная"), которое необходимо выполнить в случае применения правила.
Возможны более сложные и гибкие варианты. Например можно выполнить не только первое а все правила в которых предикат вернул true. Правило может иметь возможность указывать номер следующего правила для сравнения. Таблиц правил может быть несколько, и так далее.
Этот принцип применяется в том числе при реализации firewall(например в linux).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.