Здравствуйте, Lloyd, Вы писали:
I>>Процитированая фраза это отсылка к контексту L>Фраза не была процитирована, она была вырвана из контекста и тем самым получила смысл, далекий от изначального.
Это была цитата и её цель — отсылка к контексту. То есть, предполагается, что для читателя не составляет труда подняться на два сообщения вверх по ветке и глянуть всё сообщение.
I>>Это же ты оспаривал формулировку "ООП — оно целиком про поведение" и в твоих словах "процедурный подход более ООПшен, чем ОО" это следствие. L>Вы опять переврали, Павел. Я не оспарвал, что "ООП — про поведение", учитесь читать.
Опаньки, снова русский язык "Оспаривать — объявлять спорным, заявлять своё несогласие"
Стало быть, если ты не оспаривал, следовательно, ты заявляешь о своём согласии с приведеной формулировкой ?
Вероятно, тебе нужно взять толковый словарь русского языка в редакции для технарей и пропатчить свой словарный запас
I>>а у тебя каким то чудом вышло "процедурный подход более ООПшен, чем ОО" L>Нет, у меня вышло, что приведенное определение приодит к абсурдным выводам.
Не определение, а твоё отношение к этому определению.
Абсурдный вывод это
L>В проедложеной мною реалтзации стека есть как состояние, так и "сообщения". Я присел вокруг него настольно сильно, что аж выделил в отдельную сущность.
То есть, выпятить только сообщения у тебя не получилось, но вывод ты сделал как будто получилось, понарошку так-сказать ?
Здравствуйте, samius, Вы писали:
S>У меня случилось "почем я знаю" по поводу того, что ты обсуждаешь. Лично я не вижу никаких ограничений с тем что бы в 3х структурах и 10 процедурах организовать сообщения, идентити, инкапсуляцию, полиморфизм и не только это, и назвать это определенным взаимодействием.
То ли ты чего то не видишь, то ли у тебя есть пример который покажет что этих ограничений нет. Желательно про сообщения, идентити и инкапсуляцию. Ну и про структуры и процедуры не забывай.
I>>Из трёх структур и 10 процедур никакого взаимодействия которое "квалифицировать как ООП" не получится, максимум " эмуляция ООП или ООП-стиль". S>Я так не считаю
Стало быть, пример ты легко накидаешь ?
I>>Это как например с подростками, которые любят одежду military style. такой стиль не делает их военными и даже не делает их одежду военной формой. S>Отличный съезд с темы
Здравствуйте, Ikemefula, Вы писали:
I>>>Процитированая фраза это отсылка к контексту L>>Фраза не была процитирована, она была вырвана из контекста и тем самым получила смысл, далекий от изначального.
I>Это была цитата и её цель — отсылка к контексту. То есть, предполагается, что для читателя не составляет труда подняться на два сообщения вверх по ветке и глянуть всё сообщение.
Потрудтесь впредь цитировать так, чтобы смысл не перевирался.
I>>>Это же ты оспаривал формулировку "ООП — оно целиком про поведение" и в твоих словах "процедурный подход более ООПшен, чем ОО" это следствие. L>>Вы опять переврали, Павел. Я не оспарвал, что "ООП — про поведение", учитесь читать.
I>Опаньки, снова русский язык "Оспаривать — объявлять спорным, заявлять своё несогласие" I>Стало быть, если ты не оспаривал, следовательно, ты заявляешь о своём согласии с приведеной формулировкой ?
Нет, Павел, не следует из этого, что я согласен с формулировкой.
Вот ты например, Павел, в этом своем посте не оспаривал существование макаронного монстра, но это же не значит, что ты согласен с его существованием.
I>Вероятно, тебе нужно взять толковый словарь русского языка в редакции для технарей и пропатчить свой словарный запас
Уж чья бы корова мычала, Павел.
I>>>а у тебя каким то чудом вышло "процедурный подход более ООПшен, чем ОО" L>>Нет, у меня вышло, что приведенное определение приодит к абсурдным выводам.
I>Не определение, а твоё отношение к этому определению.
Несомненно, Павел, вы в гораздо большей степени осведомлены о моем отношении к определению, чем я сам.
Не поделитесь сокровенным знанием? Заодно хотелось бы понять, что это за зверь такой — "отношение к определению". Может вы имели в виде "трактовку", Павел.
I>Абсурдный вывод это
Да, это абсурный вывод, об этом я и написал.
L>>В проедложеной мною реалтзации стека есть как состояние, так и "сообщения". Я присел вокруг него настольно сильно, что аж выделил в отдельную сущность.
I>То есть, выпятить только сообщения у тебя не получилось, но вывод ты сделал как будто получилось, понарошку так-сказать ?
Все получилось, Павел, все получилось. И сообщение выделить получилось (процедуры), и состояние (структурка). А то, что должно быть только одно — ваши это личные фантазии, Павел.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
S>>У меня случилось "почем я знаю" по поводу того, что ты обсуждаешь. Лично я не вижу никаких ограничений с тем что бы в 3х структурах и 10 процедурах организовать сообщения, идентити, инкапсуляцию, полиморфизм и не только это, и назвать это определенным взаимодействием.
I>То ли ты чего то не видишь, то ли у тебя есть пример который покажет что этих ограничений нет. Желательно про сообщения, идентити и инкапсуляцию. Ну и про структуры и процедуры не забывай.
Есть.
I>>>Из трёх структур и 10 процедур никакого взаимодействия которое "квалифицировать как ООП" не получится, максимум " эмуляция ООП или ООП-стиль". S>>Я так не считаю
I>Стало быть, пример ты легко накидаешь ?
Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь.
I>>>Это как например с подростками, которые любят одежду military style. такой стиль не делает их военными и даже не делает их одежду военной формой. S>>Отличный съезд с темы
I>Это пояснение.
А, ну тогда это меняет дело. Какие могут быть примеры, если у тебя такие убедительные пояснения
Здравствуйте, Enomay, Вы писали:
S>>>>2. Необходим ли для подсчёта стоимости заказа доступ к непубличной части его состояния? E>>>исходя из вышесказанного, ему не требуется доступ за пределы себя самого, все необходимое он имеет. S>>Вы отвечаете не на тот вопрос. Я спрашивал ровно обратное — требуется ли ему доступ "вовнутрь", к чему-то такому, что не видно снаружи.
E>он имеет доступ к внутренним коллекциям, а вот должны они быть видны из вне, или нет, зависит от задачи. E>в любом случаи не он сам их создает.
Погоди, ты сначала сказал "исходя из вышесказанного, ему не требуется доступ за пределы себя самого, все необходимое он имеет." — То есть, у Ордера есть вся информации о курсах валют, самых разных скидках, нюансах доставки и тд и тд. Т.е. эдакий монстр который хранит всё на свете
Или получается, что Ордер уже может иметь доступ к внешним сущностям, сервисам и тд и тд ?
E>Объект Order со всеми вложенностями может быть матириализован один раз, при изменении quantity у OrderLine, мы получим новую сумму заказа при вызове Order.GetTotal(), при этом мы не полезем в базу.
Это почему же ? А если сумма превысит некий порог и будет другая схема вычисления суммы и тд и тд. Стало быть надо поднять все объекты OrderLine и пропатчить.
S>>Отлично. Вы не только неправильно понимаете ООП, SRP вы тоже понимаете неверно. S>>Поясню: S>>1. Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе (покупателя, оформляюшего менеджера, и т.д). Вы засовываете в него ещё одну обязанность — подсчитывать сумму позиций. S>>Очевидно, что логика "подсчитать сумму позиций" будет применима не только к Order, но ещё много к чему. К накладной, счёт-фактуре, возвратной накладной, акту пересортицы, и прочему. Из-за того, что вы всунули эту логику внутрь заказа, вы будете вынуждены заниматься унылым Copy-Paste. Ну или мучительно думать, кого из этих классов от кого отнаследовать — в целом это изоморфно знаменитой проблеме "эллипс vs круг".
E>это кто вам сказал что "Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе"? E>вы, как и часть здешних, пихаете всё в базу, я правильно понял? тогда позиция определённо ясна. E>кто же тогда должен считать сумму заказа? и почему это должен делать кто-то, а не сам заказ, при том что у него для этого есть все необходимые данные?
Таблица курсов тоже будет в ордере ? А представь, добавление позиции в ордер преодолевает некий порог. Для этого порога новые скидки, различные пермишны, например, начинающие манагеры не имеют права работать с заказами от 1000$ .
Что ж выходит что и пермишны надо в ордер всунуть ?
E>второй абзац ересь какая-то. вы бы хоть схему нарисовали, или класс накидали. а то выдумали что-то.
Нет там никакой ереси. Подсчет суммы позиций может быть применен не только к ордерам, но и много к чему еще. Возвраты, поставки, трансферы а так же просто определенные выборки, например для того, что бы проверить, не зарабатывает ли кто из манагеров на скидках используя возвраты
E>когда ордер будет считать стоимость, он спросит все свои OrderLine о их сумме, каждый OrderLine спросит о стоимости товара и помножит её на кол-во. E>при этом, он спокойно передает это кол-во в товар, который вернет в зависимости от этого новую цену, уже со скидкой. все ж просто.
Поподробнее, как товар/ордер/позиция узнает, что скидка даётся в зависимости от
1. даты — на НГ каждый второй бесплатный
2. времени — за полчаса за закрытие -1%
3. кастомера — постоянным скидка
4. менеджера — менеджер даёт скидку что бы "купить" кастомера
5. полномочий менеджера — "новые менеджеры" не имеют некоторых скидок
6. товара — возьми два xxx получи третий бесплатно (например когда в упаковке по три)
6. товароВ — возьми два xxx получи yyy бесплатно (когда ууу никто не берет)
7. суммарной цены всех товаров (набери товаров на 1000$ )
8. массы заказа (закажи полную корзину и получи доставку бесплатно)
9. адрес доставки (доставка по району zzz бесплатна)
... — продолжать можно до бесконечности. Ты все это хочешь хранить в ордере что ли ?
E>у вас есть 5 товаров. у каждого своя стратегия расчета скидок.
Это сильное упрощение. Стратегия рассчета цены меняется в зависимости от перечисленых параметров, список сильно не полный. Т.е. на рассчет стоимости влияет целая кучка факторов а не только 5 товаров.
E>в моём случае, каждый товар сам знает свою стратегию. и мне придется изменить или 1 продукт, или добавить новый.
Не ясно, как товар узнает, что на момент оформления заказа на такие товары действовала определенная скидка.
E>в вашем. все 5 стратегий в 1м методе. на сколько-то десятков строк. добавление/изменение всегда заставит менять этот метод. а это может повлиять на другие его части.
Все стратегии будут в разных методах Выбор делается в зависимости от состава участников.
E>то есть один метод знает как считать скидки для совершенно разных объектов. E>а это очень плохой подход.
Наоборот, методов может быть сколько угодно. А тебя в ордере придется рассчитывать целый пакет скидок. А как быть со скидками, скажем, на возвраты, которые могут быть платныеми или бесплатными ? Опаньки !
S>>При этом вы почему-то думаете, что OrderService обрастёт каким-то набором "if-else" для расчёта скидки, как будто там запрещено использовать наследование, полиморфизм, и агрегацию.
E>тоесть вы будете порождать тонные объектов и наделять их не свойственной для них логикой? ради бога.
Каким правилом руководствоваться что бы выяснить, что свойственно а что не свойственно для Ордер ? Ну кроме "я так считаю" и "очевидно"
Здравствуйте, Lloyd, Вы писали:
I>>>>Это же ты оспаривал формулировку "ООП — оно целиком про поведение" и в твоих словах "процедурный подход более ООПшен, чем ОО" это следствие. L>>>Вы опять переврали, Павел. Я не оспарвал, что "ООП — про поведение", учитесь читать.
I>>Опаньки, снова русский язык "Оспаривать — объявлять спорным, заявлять своё несогласие" I>>Стало быть, если ты не оспаривал, следовательно, ты заявляешь о своём согласии с приведеной формулировкой ?
L>Нет, Павел, не следует из этого, что я согласен с формулировкой.
"L>Нет, у меня вышло, что приведенное определение приодит к абсурдным выводам."
И при этом ты утверждаешь, что ты не оспариваешь ?
L>Вот ты например, Павел, в этом своем посте не оспаривал существование макаронного монстра, но это же не значит, что ты согласен с его существованием.
"L>Нет, у меня вышло, что приведенное определение приодит к абсурдным выводам."
Ни оспариваешь, ни соглашаешься, но определение, по твоему, почему то приводит к абсурдным выводам
Здравствуйте, Ikemefula, Вы писали:
I>"L>Нет, у меня вышло, что приведенное определение приодит к абсурдным выводам."
I>Ни оспариваешь, ни соглашаешься, но определение, по твоему, почему то приводит к абсурдным выводам
Да, Павел, не оспариваю. Я демонстрирую свой ход мыслей, которые приводят к абсурдному выводу и прошу указать, где в них ошибка.
Больше смайликов, Павел. Смех без причины — вы сами знаете признак чего. Страна должна знать своих героев.
Здравствуйте, Lloyd, Вы писали:
I>>Ни оспариваешь, ни соглашаешься, но определение, по твоему, почему то приводит к абсурдным выводам
L>Да, Павел, не оспариваю. Я демонстрирую свой ход мыслей, которые приводят к абсурдному выводу и прошу указать, где в них ошибка.
Не похоже, что ты просишь указать где же ошибка, потому как на указание ошибки у тебя сносит башню и ты используешь все (полу)легальные уловки.
Здравствуйте, samius, Вы писали:
I>>То ли ты чего то не видишь, то ли у тебя есть пример который покажет что этих ограничений нет. Желательно про сообщения, идентити и инкапсуляцию. Ну и про структуры и процедуры не забывай. S>Есть.
Покажи его.
I>>Стало быть, пример ты легко накидаешь ? S>Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь.
E>>OrderLine знает кол-во этого продукта. он и передаст. I>А откуда он узнает, какую скидку применять ? А если например "возьми два ведра джек дениэлс и получи __вёдра__ бесплатно", то как OrderLine узнает про вёдра ?
ордер не знает, но продукт может знать. от типа скидок будет зависеть и реализация. опять же, возможность получить какие-то другие ведра бесплатно не относится к операции расчета стоимости текущего заказа.
E>>это уже будет в ордере. I>Т.е. выходит что ордер должен знать обо всём в программе, начиная от скидок, конверсии валют до ролей юзеров, так что ли ?
конечно нет.
I>А каким образом менять скидки ? Находить все ордеры, орделайны и тд и модифицировать их до тех пор пока ордер не будет оплачен и закрыт ?
опять нет. но зависит от типа скидок. а сами скидки вполне могут где-то хранится в виде набора правил. в базе, в хмл, в коде.
I>Теперь смотри. Внезапно оказывается, что фирме нужно включать в заказ еще и доставку, а её рассчет зависит от целой пачки факторов — дата-время доставки, адрес и тд и тд. Т.е. всунуть это в ордер не представляется возможным
доставка — это услуга, имеющая цену, и вполне отлично ложится в ордер, как и продукт. так же, как к проданному ПО может добавится услуга по его установке, настройке.
I>Т.е. логику вычисления стоимости заказа ожно модифицировать как угодно. Как быть, если вся она в классе Ордер ? Получается так, что класс Ордер будет жостко завязан на всех участников операции — скидки, доставка, валюта и тд и тд.
I>Как быть если фирма делегирует доставку другой фирме ? Опаньки, надо переписывать всё подряд. А вот в случае с сервисами нужно переписать только один сервис.
всё это вытекает из придуманных лишних сложностей. доставка ложится в заказ, с её стоимостью, в зависимости от типа доставки.
на самом деле оба подхода практически одинаковы, разница в расположении логики. кому куда она ближе или проще.
Здравствуйте, Ikemefula, Вы писали:
L>>Да, Павел, не оспариваю. Я демонстрирую свой ход мыслей, которые приводят к абсурдному выводу и прошу указать, где в них ошибка.
I>Не похоже, что ты просишь указать где же ошибка, потому как на указание ошибки у тебя сносит башню и ты используешь все (полу)легальные уловки.
Да не, когда Синклер добавил в свое определение идентичность, то его под определение ООП перестало в большей степени подходить процедурный подход.
Ты же кроме умения выдирать слова из контекста, ничего примечательного не продемонстрировал, увы.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>То ли ты чего то не видишь, то ли у тебя есть пример который покажет что этих ограничений нет. Желательно про сообщения, идентити и инкапсуляцию. Ну и про структуры и процедуры не забывай. S>>Есть.
I>Покажи его.
А то что? А то ты останешься при своем мнении? Да чихать.
I>>>Стало быть, пример ты легко накидаешь ? S>>Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь.
I>Вероятно, твой пример это "я так щитаю"
Вероятно, мне пофигу. Если ты сам не можешь написать такой пример и/или обнаружить в нем перечисленные явления — то это не мои проблемы.
I>Погоди, ты сначала сказал "исходя из вышесказанного, ему не требуется доступ за пределы себя самого, все необходимое он имеет." — То есть, у Ордера есть вся информации о курсах валют, самых разных скидках, нюансах доставки и тд и тд. Т.е. эдакий монстр который хранит всё на свете
ты передёргиваешь.
I>Или получается, что Ордер уже может иметь доступ к внешним сущностям, сервисам и тд и тд ?
ему предоставили необходимую информацию. как и сервису.
ты слишком утрируешь, доводя до крайности.
E>>Объект Order со всеми вложенностями может быть матириализован один раз, при изменении quantity у OrderLine, мы получим новую сумму заказа при вызове Order.GetTotal(), при этом мы не полезем в базу.
I>Это почему же ? А если сумма превысит некий порог и будет другая схема вычисления суммы и тд и тд. Стало быть надо поднять все объекты OrderLine и пропатчить.
все эти правила расчета могут быть получены 1 раз при создании объекта Order. а могут быть вообще закешированы на уровне приложения, и доступ к ним будет быстрым при необходимости. для каждой конкретной задачи, своё конкретное решение.
I>Таблица курсов тоже будет в ордере ? А представь, добавление позиции в ордер преодолевает некий порог. Для этого порога новые скидки, различные пермишны, например, начинающие манагеры не имеют права работать с заказами от 1000$ . I>Что ж выходит что и пермишны надо в ордер всунуть ?
очень печально, если ты так считаешь
E>>второй абзац ересь какая-то. вы бы хоть схему нарисовали, или класс накидали. а то выдумали что-то. I>Нет там никакой ереси. Подсчет суммы позиций может быть применен не только к ордерам, но и много к чему еще. Возвраты, поставки, трансферы а так же просто определенные выборки, например для того, что бы проверить, не зарабатывает ли кто из манагеров на скидках используя возвраты
мы говорим о расчете стоимости заказа конкретного пользователя, или о возвратах, поставках, трансферах? к чему они тут?
E>>когда ордер будет считать стоимость, он спросит все свои OrderLine о их сумме, каждый OrderLine спросит о стоимости товара и помножит её на кол-во. E>>при этом, он спокойно передает это кол-во в товар, который вернет в зависимости от этого новую цену, уже со скидкой. все ж просто.
I>Поподробнее, как товар/ордер/позиция узнает, что скидка даётся в зависимости от I>1. даты — на НГ каждый второй бесплатный
стратегия?
I>2. времени — за полчаса за закрытие -1%
стратегия?
I>3. кастомера — постоянным скидка
стратегия?
I>4. менеджера — менеджер даёт скидку что бы "купить" кастомера
ApplyDiscount? стратегия?
I>5. полномочий менеджера — "новые менеджеры" не имеют некоторых скидок
так он ничего и не сможет сделать. но это контролируется другим уровнем.
I>6. товара — возьми два xxx получи третий бесплатно (например когда в упаковке по три)
в товаре?
I>6. товароВ — возьми два xxx получи yyy бесплатно (когда ууу никто не берет)
это вообще отдельное полиси. мы будем считать в ордере сумму yyy только когда пользователь их добавит туда. а пока, нас это не волнует и мы это в ордере не делаем. это не его ответственность.
I>7. суммарной цены всех товаров (набери товаров на 1000$ )
стратегия?
I>8. массы заказа (закажи полную корзину и получи доставку бесплатно)
стратегия?
I>9. адрес доставки (доставка по району zzz бесплатна)
стратегия?
I>... — продолжать можно до бесконечности. Ты все это хочешь хранить в ордере что ли ?
ты сам придумал что я этого хочу. а я ведь такого не говорил.
суть реализации не сильно будет отличаться от кучи сервисов.
I>Это сильное упрощение. Стратегия рассчета цены меняется в зависимости от перечисленых параметров, список сильно не полный. Т.е. на рассчет стоимости влияет целая кучка факторов а не только 5 товаров.
суть как в сервисах.
E>>в моём случае, каждый товар сам знает свою стратегию. и мне придется изменить или 1 продукт, или добавить новый. I>Не ясно, как товар узнает, что на момент оформления заказа на такие товары действовала определенная скидка.
мы ему об этом сообщим. а возможно он и сам знает. ведь есть полиси скидок для каждого продукта? вот продукт эти полиси, логично, может видеть.
E>>в вашем. все 5 стратегий в 1м методе. на сколько-то десятков строк. добавление/изменение всегда заставит менять этот метод. а это может повлиять на другие его части. I>Все стратегии будут в разных методах Выбор делается в зависимости от состава участников.
то же самое и тут.
E>>то есть один метод знает как считать скидки для совершенно разных объектов. E>>а это очень плохой подход. I>Наоборот, методов может быть сколько угодно. А тебя в ордере придется рассчитывать целый пакет скидок. А как быть со скидками, скажем, на возвраты, которые могут быть платныеми или бесплатными ? Опаньки !
откуда в заказе возврат? возврат это возврат, заказ это заказ.
E>>тоесть вы будете порождать тонные объектов и наделять их не свойственной для них логикой? ради бога. I>Каким правилом руководствоваться что бы выяснить, что свойственно а что не свойственно для Ордер ? Ну кроме "я так считаю" и "очевидно"
правил нет. каждый волен делать так, как считает нужным. тут нет единственно верного решения. у всех свои предпочтения.
Здравствуйте, Enomay, Вы писали:
E>отклонение чего от чего?
Это такая математическая формула из области мат. статистики. E>какое это отношение имеет к текущему пользовательскому заказу?
Ну, точно такое же, как "сумма стоимостей всех позиций". Её тоже можно посчитать на основе только лишь данных заказа.
E>не говорите глупости. E>если скидка нужна от общей суммы, то мы можем её считать в методе GetTotal. если скидки высчитываются по какому-то хитрому алгоритму в зависимости от общей суммы, то используем стратегию.
Отлично. А в какой именно класс мы будем инжектировать стратегию?
E>он имеет доступ к внутренним коллекциям, а вот должны они быть видны из вне, или нет, зависит от задачи.
Вот это интересно. Если у ордера нет public ... Items { get;} — то, конечно же, единственный способ подчитать Total будет реализовать его в ордере.
E>Объект Order со всеми вложенностями может быть матириализован один раз, при изменении quantity у OrderLine, мы получим новую сумму заказа при вызове Order.GetTotal(), при этом мы не полезем в базу. E>далее, материализация вложенного объекта выполняется 1м запросом, в данном случаи с 2мя джойнами, и лишь один раз. E>тоесть, мы имеем производительность ни чем не хуже. E>при этом, реализация БЛ производится на нормальном языке, а не в базе. что имеет массу своих преимуществ, о которых в интернете полно статей.
Ну, как известно, нормальные языки позволяют описывать бизнес-логику в одном месте, а исполнять в другом. Что тоже имеет массу преимуществ, о которых в интернете полно статей.
E>>>но в данном случае для изменения расчета скидки на продукт, нам нужно будет изменить только класс конкретного продукта, а не перелопачивать весь метод сервиса, который в итоге обрастет кучей if/case. E>>>а класс Order останется неизменным. E>>>SRP как бы S>>Отлично. Вы не только неправильно понимаете ООП, SRP вы тоже понимаете неверно. S>>Поясню: S>>1. Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе (покупателя, оформляюшего менеджера, и т.д). Вы засовываете в него ещё одну обязанность — подсчитывать сумму позиций. S>>Очевидно, что логика "подсчитать сумму позиций" будет применима не только к Order, но ещё много к чему. К накладной, счёт-фактуре, возвратной накладной, акту пересортицы, и прочему. Из-за того, что вы всунули эту логику внутрь заказа, вы будете вынуждены заниматься унылым Copy-Paste. Ну или мучительно думать, кого из этих классов от кого отнаследовать — в целом это изоморфно знаменитой проблеме "эллипс vs круг".
E>это кто вам сказал что "Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе"?
Попробуйте отъять у ордера эту обязанность. Что у вас останется?
E>вы, как и часть здешних, пихаете всё в базу, я правильно понял? тогда позиция определённо ясна.
Что именно вы называете "всё"? Да, я рассчитываю хранить заказы в RDBMS.
E>кто же тогда должен считать сумму заказа?
Я же уже сказал — что-то вроде OrderUtils. E>и почему это должен делать кто-то, а не сам заказ, при том что у него для этого есть все необходимые данные? E>второй абзац ересь какая-то. вы бы хоть схему нарисовали, или класс накидали. а то выдумали что-то.
Спокойнее. Вы же не думаете, что в жизни будет ровно один класс данных с "позициями", и вы назовёте его "Order". Какую схему вы ожидаете? Схему наследования всех этих документов друг от друга? Ну так я вам и объясняю, что внятную схему наследования построить не получится.
E>когда ордер будет считать стоимость, он спросит все свои OrderLine о их сумме, каждый OrderLine спросит о стоимости товара и помножит её на кол-во. E>при этом, он спокойно передает это кол-во в товар, который вернет в зависимости от этого новую цену, уже со скидкой. все ж просто. E>а вы усложняете.
Этот момент я уже понял. Получается очень хрупкая система, с большим количеством нарушений SRP, и круговыми зависимостями. E>модель выполняет только свои обязанности. E>вышенаписанное ни чем ни лучше. но это только вершина. а как будет расчитываться все остальное в иерархии?
Что такое "всё остальное"?
S>>В пункте 2 мы понимаем, что задача "ввести в систему новую скидку" эквивалентна задаче "внести новый класс продукта". Вы думаете, что это гораздо легче, чем поменять класс типа OrderService.
E>у вас есть 5 товаров. у каждого своя стратегия расчета скидок. E>в моём случае, каждый товар сам знает свою стратегию. и мне придется изменить или 1 продукт, или добавить новый.
У меня есть, скажем 12000 товаров. Стратегия скидок обсуждается каждую неделю на комитете по ценообразованию. В основном скидки мы применяем для сегментирования рынка, т.е. они сфокусированы на покупателях, но есть и скидки, специфичные для конкретного типа товара.
Вот например — мы только что договорились с производителем DVD-плееров, что будем давать плееры бесплатно при покупке телевизора.
Вас не затруднит привести реализацию метода Product.GetDiscountedPrice(int quantity) для этого случая?
И поясните мне ещё раз — я правильно понимаю, что у вас на каждый товар свой класс? То есть для моего случая нужно написать 12000 разных классов? Если нет, то сколько всего наследников мне нужно иметь в иерархии Product?
E>в вашем. все 5 стратегий в 1м методе. на сколько-то десятков строк. добавление/изменение всегда заставит менять этот метод. а это может повлиять на другие его части.
С чего вы взяли, что в 1м методе?
S>>А у вас уже продумана схема смены класса для существуюшего объекта? Буквари ООП стыдливо обходят этот вопрос молчанием. И правильно делают — в общем случае ничего хорошего ООП не предлагает. E>существующего где?
В базе. Конечно же в базе. Мы этими DVD-плеерами уже четыре года торгуем, потому на них такая программа и пошла. Вы вообще хоть раз в жизни в магазине были? Вот у меня задача — провести распродажу обуви осенней коллекции. Как это сделать в вашей архитектуре? Все товары были и до этого.
E>когда условий станет очень много, изменения сервиса будут сложнее. гораздо сложнее. но опять же, не видя код сервиса, сложно предположить с трудностях, с которыми придется столкнутся. но их будет не меньше, чем в моем случае.
Вы зачем-то нафантазировали себе какую-то монолитную реализацию этого сервиса. Зачем?
В реальной жизни сервис был бы устроен примерно так:
public interface IDiscountService
{
IEnumerable<IDiscountLine> GetDiscounts(IOrder order);
}
public class DiscountService: IDiscountService
{
...
public IEnumerable<IDiscountLine> GetDiscounts(IOrder order)
{
foreach(var discountRule in ActiveRules)
{
if (discountRule.isApplicableTo(order))
{
yield return new DiscountLine(discountRule.Name, discountRule.getAmount(order));
if (discountRule.StopProcessingOtherRules)
yield break;
}
}
}
}
То есть во всём сервисе есть ровно два if. Вся логика возможных скидок спрятана внутри IDiscountRule — его сигнатуру легко восстановить по использованию.
Конечно же, ни в коем случае нельзя прятать применённые скидки внутрь стоимостей отдельных позиций или всего заказа. Ведь мы не сможем напечатать документ, показывающий покупателю, откуда взялась такая стоимость, особенно если применилось более 1й скидки. Надо выводить скидки в виде отдельных строчек.
Реализаций интерфейса IDiscountRule будет несколько. Вот некоторые из них:
— SingleItemQuantityDiscountRule // реализует скидки типа "каждый третий бесплатно"
— DependentItemDiscountRule // реализует скидки для зависимых товаров — вроде DVD+телевизор, или монитор+клавиатура
— OrderTotalAmountBasedDiscountRule // реализует скидки в зависимости от полной суммы заказа
— SaleItemDiscountRule // реализует скидки на товары, участвующие в распродаже
— CustomerClassDiscountRule // реализует скидки в зависимости от категории покупателя
— PromoCodeDiscountRule // реализует скидки по промо-кодам
У управляющего магазином будет редактор списка этих правил, где он сможет создавать любое их количество. Конечно же, для этого не потребуется никакая рекомпиляция и ре-деплоймент системы.
Если в требованиях к работающей системе появится какой-то новый тип скидок, то я просто заведу ещё один класс. Управляющий сможет создать и настроить экземпляры этого нового типа, а вся существующая бизнес-логика прозрачным образом "подхватит" их.
Как видите — ООП в полный рост. Просто объекты не там, где вы привыкли их искать.
E>тоесть вы будете порождать тонные объектов и наделять их не свойственной для них логикой? ради бога.
Забавно, но на мой взгляд всё ровно наоборот — это вы порождаете тонны объектов там, где вообще никаких объектов нет (а есть просто данные), и наделяете их совершенно несвойственной им логикой. Но это всё субъективно, так продолжим же объективные рассуждения.
E>только я считаю что нет необходимости порождать ненужные сущности, если у нас уже имеются конкретные объекты, которые мы можем наделить свойственными только им обязанностями. E>а если вы считаете что сумма заказа — это не обязанность заказа, ваше дело
Рано или поздно вы тоже поймёте, что сумма заказа — не обязанность заказа. Вот вы сходу бросились решать задачу со скидками и угодили в стандартную ловушку. Потому, что вам показалось, что это товар "ведёт себя так" в заказе. Нет! Это не пылесос решает "продайте меня за полцены". Это менеджер принимает решение: "пылесос мы продадим со скидкой 50%, потому что он входит в программу утилизации".
Далее видно, что менеджер принимает решение не с потолка, а на основе системы правил. В итоге, вместо того, чтобы выполнять анализ в ненужную сторону — "поведения товаров", мы продолжим копать в сторону системы правил. Постараемся выписать все действовавшие когда-либо правила, действующие сейчас, и какие правила планируется применять. Поищем между ними общее, разное. Посмотрим, какие данные нужны правилам, чтобы действовать. И применим всю мощь ООП для моделирования "менеджера", который превратится в DiscountService, и правил. А товары, ордера, строки и прочее так и останутся данными, которыми они и были всю жизнь с 16 примерно века, пока не пришёл Фаулер и не сбил всех с толку.
E>хотите предметную дискуссию, можно описать задачу, и сделать 2 реализации, на основании которых и сравнивать.
Настоящую задачу, даже миниатюрную, полностью решать — это потребуется 20 Kloc. Ни один из нас это не напишет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Ikemefula, Вы писали:
I>То ли ты чего то не видишь, то ли у тебя есть пример который покажет что этих ограничений нет. Желательно про сообщения, идентити и инкапсуляцию. Ну и про структуры и процедуры не забывай.
А чего далеко ходить. WinAPI — в значительной мере ООП. CloseHandle, к примеру, даже полиморфный. В чём вопрос-то?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Enomay, Вы писали:
E>ордер не знает, но продукт может знать. от типа скидок будет зависеть и реализация.
То есть, в обязанности продукта входит знание о всех возможных скидках ?
I>>А каким образом менять скидки ? Находить все ордеры, орделайны и тд и модифицировать их до тех пор пока ордер не будет оплачен и закрыт ?
E>опять нет. но зависит от типа скидок. а сами скидки вполне могут где-то хранится в виде набора правил. в базе, в хмл, в коде.
Они так и хранятся и как правила логика этой части меняется очень часто. Каким образом ордер или продукт будет знать, какая стратегия может к ним применяться ?
I>>Теперь смотри. Внезапно оказывается, что фирме нужно включать в заказ еще и доставку, а её рассчет зависит от целой пачки факторов — дата-время доставки, адрес и тд и тд. Т.е. всунуть это в ордер не представляется возможным
E>доставка — это услуга, имеющая цену, и вполне отлично ложится в ордер, как и продукт. так же, как к проданному ПО может добавится услуга по его установке, настройке.
Рассчет цены каким образом делать ? Ордеру придется завязываться на особенности реализации доставок, услуг и тд.
I>>Как быть если фирма делегирует доставку другой фирме ? Опаньки, надо переписывать всё подряд. А вот в случае с сервисами нужно переписать только один сервис.
E>всё это вытекает из придуманных лишних сложностей. доставка ложится в заказ, с её стоимостью, в зависимости от типа доставки.
Сложности не лишние, это требования бизнеса. Стоимость доставки может зависеть от качественного и количественного состава заказа, а стоимость заказа в свою очередь зависит от стоимости доставки Опаньки !
Здравствуйте, Lloyd, Вы писали:
I>>Не похоже, что ты просишь указать где же ошибка, потому как на указание ошибки у тебя сносит башню и ты используешь все (полу)легальные уловки.
L>Да не, когда Синклер добавил в свое определение идентичность, то его под определение ООП перестало в большей степени подходить процедурный подход.
Вообще говоря идентичность уже включено в понятие messaging
Здравствуйте, Ikemefula, Вы писали:
L>>Да не, когда Синклер добавил в свое определение идентичность, то его под определение ООП перестало в большей степени подходить процедурный подход.
I>Вообще говоря идентичность уже включено в понятие messaging
Здравствуйте, samius, Вы писали:
I>>Покажи его. S>А то что? А то ты останешься при своем мнении? Да чихать.
Ты что, пишешь в форум что бы поменять чьё то мнение ?
I>>Вероятно, твой пример это "я так щитаю" S>Вероятно, мне пофигу. Если ты сам не можешь написать такой пример и/или обнаружить в нем перечисленные явления — то это не мои проблемы.
Очевдино, это уже обсуждавшаясь ранее тема "эталонов"
Здравствуйте, Enomay, Вы писали:
I>>Погоди, ты сначала сказал "исходя из вышесказанного, ему не требуется доступ за пределы себя самого, все необходимое он имеет." — То есть, у Ордера есть вся информации о курсах валют, самых разных скидках, нюансах доставки и тд и тд. Т.е. эдакий монстр который хранит всё на свете
E>ты передёргиваешь.
Ты объясни, откуда Ордер будет знать про таблицы валют, скидки, доставки, услуги и тд и тд. Как узнать при оплате заказа, что на момент составления действовала определенная система скидок ?
E>ему предоставили необходимую информацию. как и сервису. E>ты слишком утрируешь, доводя до крайности.
Где и как эта информация будет храниться, в каокм виде ? Ну, таблица курсов та же или система скидок которая действовала на момент оформления заказа ?
>все эти правила расчета могут быть получены 1 раз при создании объекта Order. а могут быть вообще закешированы на уровне приложения, и доступ к ним будет быстрым при необходимости. для каждой конкретной задачи, своё конкретное решение.
Как это будет храниться в базе ? Позиции могут добавляться, удаляться, изменять цену и тд и тд. Как это оформить один раз при создании объекта ордер ?
I>>Таблица курсов тоже будет в ордере ? А представь, добавление позиции в ордер преодолевает некий порог. Для этого порога новые скидки, различные пермишны, например, начинающие манагеры не имеют права работать с заказами от 1000$ . I>>Что ж выходит что и пермишны надо в ордер всунуть ?
E>очень печально, если ты так считаешь
Ты же не даёшь внятного ответа.
I>>Нет там никакой ереси. Подсчет суммы позиций может быть применен не только к ордерам, но и много к чему еще. Возвраты, поставки, трансферы а так же просто определенные выборки, например для того, что бы проверить, не зарабатывает ли кто из манагеров на скидках используя возвраты
E>мы говорим о расчете стоимости заказа конкретного пользователя, или о возвратах, поставках, трансферах? к чему они тут?
Мы вообще то говорим об ООП, в данном случае про такую вещь как дублирование функционала из за неправильного применения принципов ООП. А стоимость заказа это просто хороший пример.
I>>Поподробнее, как товар/ордер/позиция узнает, что скидка даётся в зависимости от I>>1. даты — на НГ каждый второй бесплатный
E>стратегия?
Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
I>>2. времени — за полчаса за закрытие -1%
E>стратегия?
Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
I>>3. кастомера — постоянным скидка
E>стратегия?
Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
I>>4. менеджера — менеджер даёт скидку что бы "купить" кастомера
E>ApplyDiscount? стратегия?
Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
I>>5. полномочий менеджера — "новые менеджеры" не имеют некоторых скидок
E>так он ничего и не сможет сделать. но это контролируется другим уровнем.
То есть, за подсчет цены отвечает какой то другой уровень что ли ?
I>>6. товара — возьми два xxx получи третий бесплатно (например когда в упаковке по три)
E>в товаре?
Я не представляю реализации этой скидки в товаре. Ну
I>>6. товароВ — возьми два xxx получи yyy бесплатно (когда ууу никто не берет)
E>это вообще отдельное полиси. мы будем считать в ордере сумму yyy только когда пользователь их добавит туда. а пока, нас это не волнует и мы это в ордере не делаем. это не его ответственность.
Где будет код этой полиси и где будут храниться параметры ?
I>>7. суммарной цены всех товаров (набери товаров на 1000$ )
E>стратегия?
Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
I>>8. массы заказа (закажи полную корзину и получи доставку бесплатно)
E>стратегия?
Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
I>>9. адрес доставки (доставка по району zzz бесплатна)
E>стратегия?
Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
I>>... — продолжать можно до бесконечности. Ты все это хочешь хранить в ордере что ли ?
E>ты сам придумал что я этого хочу. а я ведь такого не говорил.
Я привел тебе реальный пример. Это не я придумал, а требования бизнеса.
И совсем не ясно,как ты предлагаешь реализовывать эти самые скидки. Итого, у тебя места для реализации кода и хранения данных варьируются
ордер,
товар,
позиция,
какой то "другой уровень",
какая то полиси,
"не его ответственность" — про ордер
Для того, что бы хотя бы разобраться с тем как работают скидки и внести изменения, придется мотаться по совершенно разным частям приложеня
Между тем код этих скидок меняется очень часто, потому логично хранить его в одном месте, скажем DiscountService или наборе таких сервисов, а параметры подтягивать из базы.
E>мы ему об этом сообщим. а возможно он и сам знает. ведь есть полиси скидок для каждого продукта? вот продукт эти полиси, логично, может видеть.
То есть, GetTotal у Order будет видеть все классы участников и все полиси всех классов участников ?
I>>Все стратегии будут в разных методах Выбор делается в зависимости от состава участников.
E>то же самое и тут.
А что делать при изменении детализации, например в случае изменений той части базы про товары, доставки придется перепахивать код ордеров
I>>Наоборот, методов может быть сколько угодно. А тебя в ордере придется рассчитывать целый пакет скидок. А как быть со скидками, скажем, на возвраты, которые могут быть платныеми или бесплатными ? Опаньки !
E>откуда в заказе возврат? возврат это возврат, заказ это заказ.
Я говорю о том, скидки могут быть применены гораздо шире, чем только с заказами. С возвратами что, придется выписывать специальную логику которая аналогично заказам ? Или наследовать возврат от заказа ?
I>>Каким правилом руководствоваться что бы выяснить, что свойственно а что не свойственно для Ордер ? Ну кроме "я так считаю" и "очевидно"
E>правил нет. каждый волен делать так, как считает нужным. тут нет единственно верного решения. у всех свои предпочтения.
Предпочтения разные, зато разные варианты дизайна имеют совершенно разную стоимость разработки, сопровождения и внедрения, при чем это всё измеряемо. Потому правила есть, хотя они и не полностью формализуемы.