Здравствуйте, Lloyd, Вы писали: L>Понимаешь в чем цимес, если выпячивать только эту сторону, то выходит, что процедурный подход более ООПшен, чем ОО, ибо в процедурах кроме поведения нет вообще ничего.
Нет. В процедурном подходе нет идентичности, что ещё более приоритетно, чем поведение.
L>В ветке, где обсуждается процедурность vs объектная-ориентированность более логично подчеркивать тот аспект которые отличает эти две парадигмы, а не тот, что их сближает. L>В этом отношении определение ООП из википедии вполне корректно, а цитаты Алана Кея — совсем неуместны.
В ветке происходит странная борьба между неправильным пониманием ООП и неправильным пониманием процедурного подхода.
Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
Постулат номер 1: ООП — оно не про моделирование задачи. Оно про моделирование решения.
Пример, который я уже приводил: чтобы управлять лампочкой, не нужно моделировать лампочку. Нужно моделировать выключатель.
Точно так же и в документообороте. Не нужно моделировать сам документ — нужно моделировать бюрократа, который выполняет workflow.
Точно так же в бухгалтерии — не надо моделировать "проводку". Надо моделировать "сведение баланса".
Постулат номер 2: ООП не про данные, ООП про поведение.
Поэтому не надо радоваться, увидев похожие реквизиты у товарной накладной и у приходного ордера, и бежать наследовать их друг от друга. В соответствии с постулатом номер 1 мы уже выяснили, что у накладных собственного поведения, в общем-то, нет. Их структура меняется крайне редко, зато вот правила обращения с ними — чуть ли не каждый день.
Вот тут и оказывается, что анемика предлагает размещать логику в "сервисах" — решателях задачи. Если там есть сервисы с похожим поведением — то весь арсенал ООП вам в помощь. Надо — наследуйтесь, не надо — агрегируйте. Если есть действие, в котором участвует три разных объекта предметной области — значит, будет такое действие.
А рич-модель бесплодно пытается приделать офицерской вдове метод "высечь". Или вместо того, чтобы породить экскаватор, пишет земля.копайся().
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Ikemefula, Вы писали:
I>>>ООП как раз никуда не девалось
L>>У вас видимо свое понимание о том, что такое ООП, отличное от распространненной трактовки: L>>
L>>Object-oriented programming (OOP) is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs.
I>Это слишком общая формулировка. Разве здесь сказано, что "все структуры данных должны иметь хотя бы один метод для работы с этими данными" ?
Конечно общая. ООП — это вообще довольно мутное понятие.
L>>А вот собственно отличие от процедурного программирования: L>>
L>>The most important distinction is whereas procedural programming uses procedures to operate on data structures, object-oriented programming bundles the two together so an "object", which is an instance of a class, operates on its "own" data structure.
I>И это слишком общая формулировка. Ты их из википедии что ли надёргал ? Класс спокойно может выполнять операции над своими членами, каждый из которых м.б. простой структурой данных.
И что?
L>>Вы все еще уверены, что anemic — это ООП?
I>Вот пример про анемик из соседнего форум. Есть бизнес сущность Account, необходимо сделать трансфер средств из одного на второй. I>
Здравствуйте, licedey, Вы писали:
L>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
Лично мне в последние лет пять редко приходится делать что-то "с нуля", обычно речь идёт о том, чтобы "залезть внутрь и доработать под капотом не выключая двигатель"
И вот чему учит первый проект на 50M строк -- кодить просто, кодить мало, кодить только то, что нужно. Самый лучший дизайн у той программы, которая никогда не была написана, потому что удалось доказать, что писать её не надо. Именно это -- идеал. Если вы нарисовали иерархию классов и видите, что один можно выкинуть -- сделайте это. Если можно выкинуть все классы и написать на C -- сделайте это. Язык С лучше для чтения чем С++, в C вы всегда знаете, что у вас сегодня утром делает операция "+". Если можно вообще ничего не кодить а просто прикутить готовую библиотеку -- сделайте это. Из любой точки А в любую Б может и должна вести прямая. Я сам этого не понимал ещё несколько лет назад. Мы программисты, и способны получать удовольствие от разработки как таковой, а значит часто бываем увлечены процессом, не результатом. Это надо про себя понимать и в себе контролировать. Постоянно держите перед глазами результат и прокладывайте кратчайший, простейший маршрут.
Но не вздумайте сделать проще чем надо.
Во-первых есть решения и инструменты которые кажутся простыми, таковыми не являясь. Я не буду подробно останавливаться -- копипаст, макросы (в обоих смыслах), goto, volatile в многопоточном окружении, продолжайте сами. Самое главное, когда речь идёт о простоте -- не надо экономить свои усилия к написанию кода. Вместо этого вы экономите чужие усилия к его прочтению и переиспользованию. И этим сберегаются ваши усилия.
Во-вторых есть минутные слабости, которые кажутся незначительными. Завести в функции статическую переменную, ведь она никогда не будет использована в многопоточном окружении. А вот в эту функцию на три экрана я всегда могу добавить ещё одно условие в case, всего двадцать строк. А вот здесь я один разок нажму ctrl-v и никто не заметит. Бейте себя по рукам линейкой за каждую такую минутную слабость.
Путь к решению задачи это баланс между излишней простотой, которая приводит к громоздкости и излишней сложностью, которая приводит к громоздкости. Между лапшой дурного спагетти с goto и копипастом и лапшой дурных паттернов с архитектурой, UML и переопределением операторов. Баланс между этими двумя опасностями называется решением задачи.
Здравствуйте, Lloyd, Вы писали:
L>Эта формулировка все-таки существенно отличается от "ООП — оно целиком про поведение".
Ну так я и не статью в рецензируемый журнал пишу.
L>И это как-то отличается от того, как трактуют ООП "Эвансы, Фаулеры, Бучи"? Кей в приведенной фразе не говорит ничего кардинально отличающегося, про инкапсуляцию не пишет разве ленивый.
Для начала, это отличается от того, как трактуют ООП те, кто трактует Эвансов, Фаулеров, и Бучей, в стиле приведённого вами "определения" ООП.
Потому, что несмотря на математическую эквивалентность утверждений "объекты — это данные с приделанным к ним поведением", и "объекты — это поведение, использующее внутренние данные", подходы в результате они дают совершенно разные.
Я напомню проигнорированный вами аргумент про то, что попытки начать конструировать Круги и Эллипсы от данных приводит к значительным затруднениям при попытке приделать к ним осмысленное поведение.
Зато если начать с требуемого поведения, то не слишком трудно понять, какие данные могут ему потребоваться.
Когда я проектирую решение какой-то задачи в стиле ООП, я определяю поведение. Черновик модели можно построить, вообще не упоминая данные никак. В терминах одного лишь поведения. Именно в этом смысле ООП "целиком про поведение".
Вот у нас один объект что-то послал другому, вот как другой обязан отреагировать. Какие там у них внутри поля, отнаследована ли структура Круга от Эллипса или наоборот — всё это малосущественные в ООП детали.
Именно это отличает ООП от, скажем, реляционной алгебры, где как раз поведения, в общем-то, нет. Зато на передний план выпячены данные.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Enomay, Вы писали:
E> эта методология, как и всё остальное, не является серебряной пулей, и не может решать всех задач.
Вот это пожалуй единственная здравая мысль за всю дискуссию. Осталось сделать небольшой шажок и понять — для каких именно задач DDD более-менее подходит. hint: класс этих задач весьма ограничен.
E>преимущество применения DDD методологии в более красивом и структурированном объектно-ориентированном коде, который собой отражает проблему и её решение. E>это же очевидно.
Вы тут уже съехали с ООП головного мозга на полный DDD головного мозга. К сожалению это почти не лечится. )
Здравствуйте, abibok, Вы писали:
A>Вы так говорите как будто запрограммировать в не-ООП стиле получится быстрее. Это то же самое что говорить что без юнит-тестов получится быстрее.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, abibok, Вы писали:
L>>>Задачу на неделю для фриланса?! Конечно быстрее.
A>>Что именно — первое или второе? По поводу второго еще можно поспорить, а с первым-то как? Вы давно писали что-нибудь в не-ООП стиле? Мне пришлось бы заставлять писать себя так, и это было бы явно медленнее, не говоря уже об отладке и сопровождении.
L>А вы уверены, что вы вообще хоть когда нибудь писали в ООП-стиле?
полностью поддерживаю. многие языки (не плюсы) имеют ооп чисто для галочки. и ведь живут. к тому же, если мы в плюсах создадим класс "сортировка" (с кучей разных алгосов сортировки), то это будет не ооп, а модульное программирование, потому что "сортировка" это не сущность. это действие, выполняемое над некоторыми сущностями (массивами, списками...). загнать разные методы сортировки в один класс можно, но что мы получим в результате? обыкновенный модуль, но не объект.
и потом, если взять два достаточно крупных проекта -- например, Spider Monkey (си) и Google V8 (плюсы), то в первом легко разобраться и с ходу начать дотачивать код под свои нужды. нужно прикрутить логгер -- берем и прикручиваем. а теперь смотрим на приплюснутый код. вообще-то он не совсем приплюснутый. он даже хуже. половина движка java script написана на спец-реализации самого java-script и взаимодействует с приплюснутым кодом очень нетривиальными путями. просто воткнуть fopen/fprintf не получается. и приходится в одном месте создавать новый интерфейс, а в другом месте его юзать. причем данные имеют жутко сложную структуру. итераторы всякие везде... да еще и с разными типами... хосподи. записать аргументы функции в файл -- это кошмар на улице вязов.
L> Более того, очень многими неглупыми людьми ставится под сомнение его полезность.
про все ооп не скажу, но вот никак не могу понять -- действительно ли язык программирования должен быть таким сложным, как плюсы? действительно ли у программиста должна болеть голова за виртуальные деструкторы? говорят, что плюсы обеспечивают высокую производительность. и где же она? куча программ на жабе не сильно уступает аналогичным программам на плюсах. хваленный сверхбыстрый движок гугла написан не только на плюсах, но и на жаба скрипте, причем там такие критические фрагменты кода, как, например, операции с массивами. вероятно, на этот шаг пошли по соображениям безопасности. чтобы память не текла и буфера нежиданно не переполнялись.
вот я и думаю -- а что мне дадут плюсы, если их выучить? питон мне дал высокую продуктивность и учить его не пришлось (так, полистал книжку на выходных), java script дала высокую портабельность (работает _везде_, включая мобилки и опять без затрат на обучение), чистый си дает производительность, но нам нем пишутся только самые низкоуровневые компоненты, а обвязка -- жаба, питон, руби или скала.
у плюсов же -- производительность только в теории, на практике оно тормозит и отжирает память (если, конечно, пользоваться приплюснутыми фичами на полную). программы сложно писать и еще сложнее понимать. с компиляторами и платформами сплошная чехарда. даже плагин для популярных программ обычно нужно писать на том компиляторе, которым собиралась сама программа.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, Ikemefula, Вы писали:
L>>Нет. Просто прочитайте определение и примерьте к своему примеру, все встанет на свои места.
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. Ни один из нас это не напишет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, abibok, Вы писали:
L>>Задачу на неделю для фриланса?! Конечно быстрее.
A>Что именно — первое или второе? По поводу второго еще можно поспорить, а с первым-то как? Вы давно писали что-нибудь в не-ООП стиле? Мне пришлось бы заставлять писать себя так, и это было бы явно медленнее, не говоря уже об отладке и сопровождении.
А вы уверены, что вы вообще хоть когда нибудь писали в ООП-стиле?
Вот я чем дольше работаю, тем меньше вижу ентое ООП.
Более того, очень многими неглупыми людьми ставится под сомнение его полезность. Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
Здравствуйте, -VaS-, Вы писали:
VD>>Позволь полюбопытствовать, а "нормальная архитектура" и ООП — это одно и то же?
VS>Вопрос с подвохом
Вопрос без малейшего подвоха. ООП и хорошая архитектура вещи никак не связанные. И с ООП может быть никакая архитектура, и без него может быть как хорошая, так и плохая архитектура.
В ООП нет ничего такого, что нельзя было бы сделать без него. Как, в прочем и в любой другой парадигме.
VS>Нормальный OOD — как минимум, соблюдение SOLID. Получаем поддерживаемую систему, могущую изменяться под новые требования без переписывания половины кода с последующим трехмесячным дебагом. Что такое говнокод на ОО-языке?
Говногод он по любому говнокод. Он парадигм он не зависит.
VS>Номер раз — процедурщина.
О, как? А ничего, что самые объемные и не простые программные продукты вроде Винды и Линукса в основном написаны на С в самоно, то ни на есть процедурном стиле?
VS>Этого добра так много, что номер два (нездоровое увлечение фп) на ее фоне почти незаметен. Немного фп внутри класса — ок, упрощает рутинные операции, но когда пытаются строить на этом архитектуру — это даже не смешно.
А я вот знаю людей пишуших на Хаскеле и считающих, что этот язык позволяет им сделать архитектуру их ПО очень красивой и правильной. Что они делают не так?
В прочем, это вопрос тоже с подвохом. Точнее — это вопрос риторический, потому как от наличия или отсутствия ООП грамотность архитектуры никак не зависит.
ООП — это не более чем метод. При его правильном применении можно добиваться неплохих результатов. И то не всегда. Например, для написания парсеров или компиляторов ООП вообще ничего полезного не предлагает.
Так что не надо делать из ООП очередную панацею. То что кто-то освоил в основном только ООП не означает, что за пределами ООП нет жизни.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, licedey, Вы писали:
L>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
Дык разбивать на классы, функции и т.п. нужно не ради причастности к модному движению, а для того чтобы код было легко развивать и поддерживать.
По сему классы нужно вводить только когда другие пути дают худший результат. В прочем, есть задачи которые классами описываются лучше. Это задачи симуляции, т.е. когда нужно построить некоторую модель, "запустить" ее и наблюдать за тем как она себя поведет под воздействием входных данных. Но таких задач не так уж и много. И зачастую ООП-ом начинают решать задачи ему не свойственные. Вот это и есть ООП головного мозга.
Чтобы такого не случалось нужно кроме ООП познать и другие парадигмы. Как минимум имеет смысл освоить ФП, МП/DSL.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Ikemefula, Вы писали:
I>>>Почему это анемик процедурный ?
L>>Потому что имеем разнесение данных и способов работы с ними. Может "процедурный" и не самое удачное слово, но вот "ООП" уж тут точно ни в какие ворота.
I>ООП как раз никуда не девалось
У вас видимо свое понимание о том, что такое ООП, отличное от распространненной трактовки:
Object-oriented programming (OOP) is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs.
А вот собственно отличие от процедурного программирования:
The most important distinction is whereas procedural programming uses procedures to operate on data structures, object-oriented programming bundles the two together so an "object", which is an instance of a class, operates on its "own" data structure.
Здравствуйте, -VaS-, Вы писали:
VS>Критерий простой — если программа будет в дальнейшем модифицироваться (изменение и уточнение требований в будущем, либо банальная инкрементальная разработка), то без нормальной архитектуры и хороших тестов это сделать будет невозможно.
Позволь полюбопытствовать, а "нормальная архитектура" и ООП — это одно и то же?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Lloyd, Вы писали:
L>Это какой-то новый совершенно выбивающий из колеи прием — я отвечаю на ваш пост, а вы в ответ приводите набор банальностей, на который и возразить вроде нечего.
Эти банальности, судя по содержанию постов, для многих участников топика являются откровением.
Связь очень простая — вы мне пишете, что важно для обсуждения процедурности vs объектно-ориентированности.
А я вам отвечаю, что этого обсуждения здесь нет. Я не могу считать полемику с использованием ереси типа "анемик — это процедурный подход" или "ООП — это данные с методами" реальным обсуждением ООП и процедурности.
Как если бы вы пытались выяснить, к зверям или птице относить сазана.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
L>Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions").
Это не определение. Это чушь, которой забивают мозг неопытным разработчикам. Потом их очень трудно лечить от заблуждений.
Для начала, нужно твёрдо усвоить, что ООП — оно целиком про поведение. А не про структуру полей и методов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
A consequence of this situation is if two objects are identical, a change to one will always affect the other.
S>>И? Я вижу здесь только подтверждение моим словам. Нет никаких упоминаний "логической идентичности" vs "физической идентичности".
S>Отвечу сначала на это, потому как это быстро. S>
S>class Monostate
S>{
S> static int a;
S> public int A { get { return a; } set { a = value; } }
S>}
S>var a = new Monostate();
S>var b = new Monostate();
S>a.A = 42;
S>Assert(42 == b.A);
S>
S>Нет способа изменить лишь один из них. Они удовлетворяют процитированному. Т.е. согласно процитированному являются идентичными.
Нет, не являются.
Исходое выражение : если А, то Б, где А — идентичность двух объектов, Б — изменение свойств отражающееся на обоих.
В логике "если x, то y" называют импликацией.
Она верна в том числе когда А — ложно и Б — истинно. В коде выше именно Б истинно, но А ложно.
Но импликация ложна, когда посылка истинна, а следствие ложно. То есть выражение вида "если изменения одного объекта влияют на другой, то они эквивалентны" ложно.
Здравствуйте, samius, Вы писали:
S>Там, где ты выделил жирным, ты описал свойство identity через понятие одинаковых и разных объектов. Я пишу что наоборот, identity определяет где разные, а где одинаковые (same) объекты.
Теория требует, чтобы identity и, э-м-м, "самоэквивалентность" объекта были одним и тем же. Не задавая какого-то конкретного "направления" эквивалентности.
Проводим простой эксперимент: определяем функцию ID(obj) == 0.
Эта функция вводит вполне нормальное с точки зрения математики отношение эквивалентности. Наша идентити успешно определила все объекты, как одинаковые. Подходит ли она под определение identity из OOP или всё-таки нет?
Если не подходит, то почему?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Enomay, Вы писали: E>возможно. но мне почему-то казалось что подсчетом стоимости заказов должен заниматься объект Order, а не OrderService.
А можно пояснить, почему вам так казалось?
1. Является ли подсчёт стоимости неотъемлемой частью поведения заказа?
2. Необходим ли для подсчёта стоимости заказа доступ к непубличной части его состояния?
3. Есть ли причины полагать, что для разных наследников класса Order будут реализованы разные способы подсчёта стоимости? (Реализацию моков в расчёт не берём — это артефакты процесса производства)
Вообще, в целом, какие конкретные преимущества даст внесение метода подсчёта стоимости заказа внутрь Order, по сравнению с размещением его снаружи? Желательно — конкретно. Ну там, если преимущество "гибкость" — то в чём именно, если "масштабируемость" — то каким образом она достигнется и т.д.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
I>>Здесь Account наделили методами и стало ООП ? Всего то изменились классы и обязанности и теперь класс придется модифицировать по любому поводу.
L>Да, именно. Стало более в ОО-духе.
Разница всего лишь в количестве сущностей которыми моделируется решение задачи. Т.е. разница в детализации.
Здравствуйте, Lloyd, Вы писали:
L>Для того, чтобы показать, что какое-то явление возможно, достаточно привести 1 пример. "какое-то явление" тут — это наличие бизнес-логики в сущностях.
Это означает ровно одно. Что Эванс демонстрирует DDD на примерах c rich model.
Доказательства того, что DDD и anemic несовместимы здесь нет. Есть доказательство совместимости с rich model, при этом, возможна совместимость и с anemic. Основной постулат DDD — максимальное приближение модели данных к естественным сущностям в бизнесе. Я совершенно не понимаю хайпа вокруг этой аббревиатуры.
...
POJOs and POCOs
POJOs and POCOs are technical implementation concepts, specific to the Java and .NET framework respectively. However, the emergence of the terms POJO and POCO, reflect a growing view that, within the context of either of those technical platforms, domain objects should be defined purely to implement the business behaviour of the corresponding domain concept, rather than be defined by the requirements of a more specific technology framework.
Здравствуйте, Ikemefula, Вы писали:
L>>Более того, очень многими неглупыми людьми ставится под сомнение его полезность. Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
I>Почему это анемик процедурный ?
Потому что имеем разнесение данных и способов работы с ними. Может "процедурный" и не самое удачное слово, но вот "ООП" уж тут точно ни в какие ворота.
I>Если смтореть про инкапсуляцию как у Скота Мейерса, то ООПшность это именно переход от рич к анемик.
Здравствуйте, Lloyd, Вы писали:
I>>ООП как раз никуда не девалось
L>У вас видимо свое понимание о том, что такое ООП, отличное от распространненной трактовки: L>
L>Object-oriented programming (OOP) is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs.
Это слишком общая формулировка. Разве здесь сказано, что "все структуры данных должны иметь хотя бы один метод для работы с этими данными" ?
L>А вот собственно отличие от процедурного программирования: L>
L>The most important distinction is whereas procedural programming uses procedures to operate on data structures, object-oriented programming bundles the two together so an "object", which is an instance of a class, operates on its "own" data structure.
И это слишком общая формулировка. Ты их из википедии что ли надёргал ? Класс спокойно может выполнять операции над своими членами, каждый из которых м.б. простой структурой данных.
L>Вы все еще уверены, что anemic — это ООП?
Вот пример про анемик из соседнего форум. Есть бизнес сущность Account, необходимо сделать трансфер средств из одного на второй.
var rep = new AccountRepository(Application.Db);
var account1 = rep.LookUpFor(id_1);
var account2 = rep.LookUpFor(id_2);
var svc = new TransferService(account1, account2, Application.CurrencyRates);
svc.Transfer(100,Currency.USD);
Ты хочешь сказать, что если класс Account это простая структура вообще без всяких методов, то код выше перестаёт быть ООП ?
Для сравнения, рич
var rep = new AccountRepository(Application.Db);
var account1 = rep.LookUpFor(id_1);
var account2 = rep.LookUpFor(id_2);
account1.TransferTo(account2, 100, Currency.USD); // опаньки, нарушение инкапсуляции
Здесь Account наделили методами и стало ООП ? Всего то изменились классы и обязанности и теперь класс придется модифицировать по любому поводу.
Главное, что бы тебе было удобно. Все зависит от задачи, но в большинстве случаев ООП оправдано, говорю как 1С ник, часто хочется применить ООП а неззя.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Ikemefula, Вы писали:
L>>Или если мы делаем проект, про который мы гарантированно знаем, что модель данных не будет меняться, то что ООП начнет "блистать во всей красе"?
I>Нужно всего лишь отделять модель данных от модели операций над этими данными. В простейшем случае это можно объединить и в приведеном примере будет I>
Здравствуйте, Ikemefula, Вы писали:
L>>ты сейчас с кем разговаривал? причем тут все это?
I>"модель данных меняется намного реже модели обработки этих данных" @
I>Вроде как очевидная фраза а тебя понесло непойми куда
Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions").
L>Вы увели разговор в сторону частного случая, когда в опреации учавствует более одной сущности. Почему я не могу его увести в другую сторону?
Потому что ваш частный случай не интересен с точки зрения архитектуры. Единственный объект с состоянием эквивалентен программе с несколькими глобальными переменными. ОО подход здесь вырождается в процедурный. Не имеет никакого значения, в каком пространстве имён будут размещены процедуры, работающие с состоянием этого объекта. Тут абсолютно нечего обсуждать, и дальше в этом направлении разговор я поддерживать не буду.
Здравствуйте, Baudolino, Вы писали:
L>>Я и не предлагаю такой случай обсуждать. Прочтите внимательнее, речь не об одном объекте, а об операции, в которой учавствиет один объект. B>У меня есть привычка внимательно читать, что мне пишут. Цитирую ваши же слова: Откуда взялись "несколько сущностей"?
Я бы процитировал другие слова:
Преимущества какие-нибудь есть в "не-вынесении"?
Таки да, я все еще жду ответа на этот вопрос.
B>Если подразумевалась операция, надо было об этом сказать сразу.
Т.е. когда вы писали про "несколько сущностей", вы поняли все правильно. А когда я спросил про вариант с одной сущностью, то вы почему-то решили, что речь идет об экземпляре?
Как-то не вяжется.
B>Впрочем, я бы ответил то же самое. Это вырожденный случай и он не интересен.
Нет, это не вырожденный случай. Откройте Эванса и убедитесь, что эта "вырожденность" — на каждой второй диаграмме с сущностями.
Или понятие "вырожденность" вы тоже как-то индивидуально трактуете и оно меняется от поста к посту?
B>Если у вас данные из предметной области никак не взаимодействуют между собой и не связаны отношениями, то всё, опять же, сводится к процедурному подходу, и, опять же, не имеет никакого значения, в каком пространстве имён расположены операции над этими данными. Как только появляется отношение и/или взаимодействие — всё, уже можно рассматривать контекст и возможность/необходимость выноса в сервисный слой.
"Сервисный слой" — это и есть "поцедурный" подход.
Здравствуйте, Lloyd, Вы писали: L>Ваш пост был очень глубок и убедтелен, он в корне перевернул представления всей индустрии о то, что такое ооп. Аргумент "чушь" мне показался особенно блистательным.
Простите, но этот пост ничего не переворачивает. Это всего лишь констатация достаточно широко известного факта. L>Пишите исчо.
Я постараюсь. S>>Для начала, нужно твёрдо усвоить, что ООП — оно целиком про поведение. А не про структуру полей и методов. L>Несомненно, Антон из Новосиборска туфты не напишет.
Спасибо за доверие, но я тут ни при чём. Читайте изобретателя ООП — Алана Кея.
Кроме того, имеет смысл применять критическое мышление. К примеру, если вы видите, что предлагаемые кем-то правила неизменно приводят к плохому результату, то эти правила сами плохи. Особенно если есть альтернативные правила, которые приводят к более понятным и предсказуемым результатам.
Например, трактовка ООП как механизма по конструированию объектов из данных и методов приводит к бесплодным спорам вроде того, наследовать ли эллипс от круга или наоборот. При этом моделирование от поведения моментально приводит к правильному ответу.
Поскольку мы занимаемся инженерной дисциплиной, практика является основным критерием истины. Неудобные теории бесполезны, даже если они являются формально непротиворечивыми.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
G>Да, при помощи сервиса, а сущность "покупателя" будет DTO. Это уже похоже на нормальный дизайн. G>А он соотвествует DDD?
сущность покупателя будет иметь поведение. это соответствует DDD.
G>>>Или ты предложишь циклом ходить по orders, загружая всю историю заказов в память? и выполняя SELECT N+1
G>Значит DDD позволяет делать только тормозящее говно G>Что и требовалось доказать. G>Шучу конечно, но ощущение складывается именно такое.
DDD не предназначено для хоумпейджей, форумов, и в принципе, интернет магазинов. эта методология, как и всё остальное, не является серебряной пулей, и не может решать всех задач. но там, где это необходимо, DDD себя отлично показывает.
Эванс, между прочим, об этом говорил.
E>>нужно исходить из задачи. а не абстрактного выдуманного примера. G>Расчет скидки — не выдуманный пример.
в этом нет ничего сложного даже применяя DDD методологию.
E>>и эффективная модель в каждом отдельном случаи будет различаться. G>Представь что такой же код находится внутри CRM, где для каждого кастомера сотни заказов и десятки тысяч позиций.
не представляю, потому что нет ни условий, ни задачи. значит представлять нечего.
а для каждой конкретно задачи, существует отдельное, и не одно, решение.
G>Так в чем это преимущество? G>Ты сейчас пытаешься мне показать в случая с бухгалтерией построение слоя бизнес-логики, который как раз действительные проблемы не отражает.
преимущество применения DDD методологии в более красивом и структурированном объектно-ориентированном коде, который собой отражает проблему и её решение.
это же очевидно.
но я тебе уже советовал не заморачиваться, а продолжать использовать процедурный подход. он больше тебе подходит.
E>>тебе так кажется. G>Ну конечно, только мне кажется что сделать успешный продукт можно только учитывая пожелания пользователей.
DDD методология совершенно не обходит стороной пожелания пользователей. а наоборот. работает с ними на одном языке.
а ты что-то опять путаешь.
E>>отображение отчета какого либо отчета, совершенно никак не влияет на алгоритм расчета зарплат, под который мы делаем доменную модель, а значит, в данном случае, это нас не интересует. G>А я не говорю про отображение, я говорю про получение данных. Баланс может и не отображаться, а сразу отправляться в налоговую.
получение данных — это лишь запрос в базу. сами данные при этом не меняются. а значит никакой логики в этом действии нет.
E>>бизнесу нужна логика расчета данных, а их получение и отображение — это лишь следствие, и к логике никакого отношения уже не имеет. G>Так я с этого и начал. Вот есть у бухгалтеров баланс, это не балансовая ведомость, а некоторые данные, соотвествующие определенным правилам. еще есть обороты, остатки — тоже наборы данных, формирующиеся по определенным правилам. Как и правильно отражать в программе с точки зрения DDD? G>По сути они все являются выборками определенного вида.
они могут быть чем угодно.
как выборками, в твоём случаи,
так и просто полем объекта, которое изменяется каждый раз с приходом/уходом денег. соответственно нам нет необходимости пересчитывать баланс каждый раз. мы можем использовать готовое значение в нашей модели. проще говоря, для примера, это будет состояние объекта "баланс".
Здравствуйте, Ikemefula, Вы писали: I>Тогда что означает слово "oriented" ?
"ориентированный", нет?
Поймите, что есть языки с поддержкой OOP. Это не означает, что без них ООП невозможно.
Точно так же, как можно писать в процедурном стиле даже на ассемблерах без инструкции call. Просто это значительно более болезненно
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Flem1234, Вы писали:
F>Это потому что на одинаковые сообщения сервис в праве реагировать по разному?
Конечно. Когда вы заказываете доставку майки с принтом "металлика" через сервис веб-магазина, рано или поздно сервис станет реагировать на эти сообщения ошибкой "out of stock".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Формально тут есть некоторая сложность, связанная с тем, что мы делаем всеобщее утверждение, которое невозможно доказать никаким количеством примеров. Неформально мы поступим наоборот — выполним акт веры, примем утверждение за истинное, и подождём опровержения .
Т.е. понятие ООП вдобавок еще и не фальсифицируемо и без веру сторонникам оного ну никак не обойтись?
Куда я попал? Вы хоть жертвоприношения не практикуете?
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Ну, я как бы, думал, что ты что-то своё под этим понимаешь. Я тут у многих заметил склонность к изобретению своих трактовок терминов и их ниспровержению. То примитивный мапер лёгким ОРМ обзовут, то еще что. Даже ссылку дал, дабы прояснить горизонты. И любому здравомыслящему человеку сразу видно, что описанное по ссылке не ОО-подход
Ага. При этом старина Мартин пользуется известным маркетинговым приёмом — сначала приводит вполне себе внятное описание Service Objects, а затем пишет "а, ну так это — практически то же самое, что и Transaction Script". А раз Transaction Script — чисто процедурное овно, значит такова же и Anemic Model.
Внятного доказательства эквивалентности Service Objects и Transaction Sctript не приведено, оно подразумевается очевидным.
Примерно так же Свидетели Иеговы обосновывают креационизм: "наш мир такой классный и красивый, ну разве же не очевидно, что это оттого, что кто-то его придумал?"
А реально изо всех фатальных недостатков Anemic Model приведён только один: затраты на модель предметной области и на ORM без бенефитов.
Тут я склонен частично согласиться, а частично нет:
— в современных системах, затраты на поддержание маппинга вполне себе приемлемые. Особено если не пытаться вдуть в domain model сложные иерархии наследования.
— бенефит по сравнению с прямой манипуляцией RDBMS в том, что у нас есть богатые метаданные. В частности, можно привязывать внятные правила по валидации данных и иметь сквозные гарантии по всему стеку — от UI до базы данных. При этом выносить эти правила в уровень сервисов как раз неудобно.
В остальном, в принципе, объекты для "предметной области" действительно не нужны. Объекты нужны для того, чтобы манипулировать элементами предметной области, а про это Фаулер напрямую врёт.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
G>>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm A>>Хорошая ссылка. G>Конечно, прочитай внимательно все три определения. Все три верны и отражают разные аспекты одного и того же.
Кстати, а чем ты руководствуешься, утверждая, что эти определения верны, а, например, приведенные в википедии — нет; что выступает в качестве критерия их верности?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Ты просил функцию MyIdEquals, я записал. G>Она не является она не выполняет сравнение identity ни в одной известной мне ООП системе.
Это не является критерием identity.
G>Ты определяешь функцию только для строки (опираешься на поведение), а QueryIntrerface(IUnknown) работает для любого COM-объекта.
Для каждого по-своему. И как именно — определяется реализацией IUnknown той сущности, у которой ты вызваешь QI.
G>>>В принципе ничто не мешает при работе с COM всегда держать ссылку на IUnknown и выполнять запрос нужного интерфейса при вызове метода. Тогда идентичность сведется к простому сравнению ссылок. S>>Ничего не мешает для строк держать ссылку на интернированную строку G>да, и тогда сравнение строк всегда можно заменить сравнением ссылок. Но так не делают по соображениям быстродействия.
Соображения быстродействия не являются определяющими в критериях принадлежности идентити ООП.
G>>>Поэтому все случаи приводимости к сравнению ссылок можно считать эквивалентными. S>>Это делает разные строки идентичными по ECMA? G>Нет. Потому что идентичность в ECMA уже определена по-другому. Хотя если на уровне реализации сделать интернирование каждой строки, то таки да, любые эквивалентные строки будут идентичными.
Что-то я не понял. Есть функция f, которая RefEquals(f(a), f(b)) возвращает true. И ты считаешь строки не идентичными?
G>>>Требование ООП — умения стороннему наблюдателю различать разные объекты. S>>Идентичность говорит где разные объекты, а где нет. G>Она позволяет стороннему наблюдателю различить разные объекты. Но не является критерием разных объектов. G>То есть чтобы объекты были разными достаточно разных identity, но это не является необходимым условием.
т.е. same id => same object но не same id <= same object? Т.е.один объект дает разные identity?
Ты только что сломал детерминированность и рефлексивность id.
G>>>Метафора из жизни: близнецы — ты как сторонний наблюдатель не можешь отличить одного от другого, но это разные люди. S>>Метафора ничего не доказывает в отношении идентичности. И COM твою метафору опровергает. Ты видишь двух разных людей IUnknown*, а они — одно целое. G>Наоборот, если ты видишь два объекта у которых QueryIntrerface(IUnknown) совпадают, то это один объект, не совпадают — разные. COM как раз подтверждает.
COM как раз учит различать свои объекты, дополняя location identity, т.е. ослабляя его. G>Ты видишь двух людей (не одновременно), спрашиваешь у них СНИЛС\SSN — не совпадают, значит люди разные, а совпадают — это один человек.
Я больше поверю тому что вижу, а не тому что они ответят
G>>>Кроме того функция f, как и сама идентичность должна не опираться на состояние и поведение (конкретные типы). Что у тебя явно нарушается. S>>реализация QueryInterface типонезависима? G>Это зависит от самого компонента, но поведение, то есть то что ты можешь видеть снаружи — да, не зависит от типа.
Возможно я понял, о чем ты. Но где в определении идентити ООП сказано об этом?
G>>>Ты вообще сам не заметил, что постоянно пытаешься "расширить" эквивалентность до идентичности, только все время приплетая состояние и\или поведение. S>>Как в COM G>Нет, там таких проблем нет.
Без состояния не вернуть QI(IID_IUnknown).
G>Вообще читай спеку, ты опять пытаешься спорить с фактами: G>http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf
G>
G>3 . 3 . 1 . 1 IUnknown:
G>HRESULT IUnknown::QueryInterface(iid, ppv)
G>Return a pointer within this object instance that implements the indicated interface. Answer NULL if the receiver does not contain an implementation of the interface.
G>It is required that any query for the specific interface IUnknown always returns the same
G>actual pointer value, no matter through which interface derived from IUnknown it is called.
G>This enables the following identity test algorithm to determine whether two pointers in
G>fact point to the same object: call QueryInterface(IID_IUnknown, ...) on both and compare the results.
G>
G>...
G>This requirement isthe basis for what is called COM identity.
G>Явно черным по английскому сказано что это и есть identity.
Которая опирается на состояние и поведение (это не сказано, но это очевидно).
S>>>>Идентичность не должна изменяться с изменением состояния и поведения. G>>>Это уже твои домыслы. В определении написано "независимо", то есть вообще никак. S>>Но в COM приходится обращаться к полиморфным функциям и ты это считаешь независимым G>Наблюдаемое поведение не зависит от конкретного типа.
Зависит от конкретной сущности по указателю.
S>>Берем C++ и два указателя на IUnknown*. Они указывают на один объект? G>Если не совпадают, то нет.
Не угадал. Объект один, указатели разные. Вот когда ты у каждого спросишь QI(IID_IUnknown), то они вернут равные указатели (возможно). Но это опрос состояний сущностей, скрывающимися за указателями. COM identity завязана на состояния и поведение, хочешь ты этого или нет.
G>>>Вообще бывают разные объекты, даже если ты их не умеешь различать (то есть у них нет identity). S>>Слушай, если уж value-типы с identity ты назвал не ООП, то объекты без identity-то, уж наверняка не ООП? Или как? G>Да, требование ООП чтобы у разных объектов были разные identity. Про разные объекты см выше.
А где смотреть про объекты без identity?
S>>>>Что бы получить результат QueryInterface(IUnknown), нужно воспользоваться состоянием и поведением, притом полиморфным. G>>>Каким состоянием? Каким поведением? S>>QI это полиморфная функция. взять результат она может только обращаясь к состоянию. Обеспечить детерминированность она может только обращаясь к состоянию. Или ты знаешь другие варианты? G>Реализация не важна (ты же по сути не знаешь что внутри делает object.ReferenceEquals), важно наблюдаемое снаружи поведение, так во оно в случае QueryInterface(IUnknown) совпадает у всех COM объектов.
О, ну тогда ты же не знаешь что внутри делает MyIdEquals, главное наблюдаемое снаружи Подаешь две ссылки, он отвечает, да или нет.
G>>>Типы — поведение (или состояние, если рассматривать как ссылку на VMT). в COM QueryInterface имеет одни и те же правила работы, независимо то типа. S>>И что? Разве это где-то упомянуто в определении идентити, а я не заметил? G>Типы — поведение (или состояние, если рассматривать как ссылку на VMT\type), ты именно их используешь в своем коде/
Они же используются при QI
G>>>В ECMA это не нужно, там уже можно ссылки сравнивать. Хотя твои размышления натолкнули на мысль что f таки должна быть обратима. Надо более точно сформулировать. S>>Про обратимость f я тебе уже свои размышления показывал. Они привели к противоречию существования такой обратимой f. G>Я еще не сформулировал в каком смысле нужна обратимость.
я знаю обратимость только в одном смысле
G>>>Еще раз: такое поведение у любого объекта. Это особенность самого COM. как сравнение ссылок в CLR. S>>Ну и что? MyIdEquals определяет identity для любого объекта. Это особенность MyIdEquals. G>Нет, внутрь MyIdEquals заложено знание о конкретных классах, в отличие от QueryInterface.
В QI заложено знание о конкретной реализации IUnknown грани.
Здравствуйте, gandjustas, Вы писали: G>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта. Что, нетривиальная штука — COM?
Это всё сделано на случай агрегации. G>Это не получится также, как иметь разные ссылки на один объект в CLR. Ты по второму кругу попадаешь в одну и ту же ошибку.
Увы — получится. Надо просто отличать два понятия:
1. Просто указатель на IUnknown — любой указатель в COM является также и указателем на IUnknown. По причине наследования интерфейсов.
2. Указатель на IUnknown, полученный в ответ на QI(IID_IUnknown).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Enomay, Вы писали:
S>>Это очень хорошо. Осталось только отбросить заблуждения вроде того, что анемик != ООП. или что анемик = функциональный подход.
E>хотите отбросить — отбрасывайте. тот подход к реализации, что пропагандирует большинство, при работе с анемик моделью, лично я не считаю true OOP. но это ведь мое мнение, и я его никому не собираюсь навязывать.
Господа Фаулер и Эванс тоже считают что анемик != тру ООП, полагая что в тру ООП методы кладут рядом с данными. При этом Эванс пишет что иногда все-таки надо класть методы отдельно.
Когда я говорю что анемик отходит от тру-ООП, я подразумеваю именно тру-ООП в трактовке Фаулера и Эванса. И этим самым я ставлю себя в позицию, противоположную позиции Синклера, который под тру-ООП подразумевает нечто другое.
Но вместо того, что бы отделять тру-ООП от не тру-ООП, предлагаю сфокусировать внимание на том, что на самом деле мы тут обсуждаем лишь один аспект ООП, который даже напрямую нельзя отнести к ООП, т.к. непонятно откуда он взялся вообще. Это способ определения местонахождения метода по данным, которыми он пользуется.
Мало того, что он не дает однозначный ответ в случае, когда методу нужны данные, расположенные в разных местах, так он еще и может сломает то, из чего он якобы вытекает — инкапсуляцию. Тот же пример, где добавление очередного вида скидки ломает Order.GetTotalPrice().
В данном конкретном примере нет противостояния анемика и ООП. Как только мы придем к тому что ценообразование это не только и не столько сложение цен продуктов, сразу станет очевидно, что вычисление стоимости заказа не обязанность набора продуктов, но это функция от набора продуктов. Так же как и то что вычисление центра масс — не обязанность набора векторов, а функция от набора векторов.
E>я стараюсь использовать другой подход, по возможности, там где это уместно, либо третий, если не работают предыдущие два.
Есть отличный подход, который работает всегда, но к сожалению, плохо формализуем. Здравый смысл. В конкретном примере он мне подсказывает что класть GetTotalPrice в Order — плохая идея. Как и в покупателя или скидку. Даже если бы тру-ООП говорило что других вариантов нет, все равно это было бы плохой идеей в перспективе прогнозируемых изменений в правилах ценообразования. А тру ООП как раз такого не утверждает. Это утверждают несколько тру господ вроде Фаулера и Эванса. Причем, Эванс (повторюсь) сам предлагает отступать от такого тру-ООП.
E>но зачем меня в чем-то убеждать, ума не приложу.
Разубеждать. E>это больше похоже на то, что вы сами не уверенны, но если удастся убедить меня, то вы одержите победу над собой, и ваши сомнения развеятся. но увы, я останусь при своём
Вы останетесь при своем, даже если вас удастся убедить?
Вам сейчас не навязывают анемик. Спич, как я понимаю, лишь о выборе места для расположения метода и о том что анемик != OOP не истинно. Хотя последнее зависит от того, что подразумевать под тру-ООП и на кого ссылаться.
Здравствуйте, gandjustas, Вы писали:
G>Если рассматривать ООП с точки зрения Кея, то и erlang с процессами более чем соответствует. Это упрощение. Ты из акцента на messaging (подразумевается наличие чего-то еще), оставил *только* messaging. А ведь была еще и концепция "только объект", которая подразумевает "рекурсивный дизайн", когда объекты состоят из объектов на макро и микро уровне. В Erlang процессы (как единица хранения состояния) и сообщения есть только на макро уровне.
Здравствуйте, samius, Вы писали:
S>>И пытаешься углядеть в вики скрытый смысл, которого там нет. S>Еще как минимум один источник говорит о наличии логической идентичности. AFAIR, вы на него ссылались весной.
Логическая идентичность — термин, выдуманный лично вами.
Больше им не пользуется никто. Все остальные отличают идентичность от иных видов эквивалентности.
Идентичность — это такое отношение эквивалентности, при котором объект эквивалентен себе и не эквивалентен больше никакому другому объекту.
S>ок, COM особый случай.
И именно для него и изоморфных ему случаев введена оговорка в Wiki о том, что ссылочная эквивалентность достаточное, но не необходимое условие для идентичности.
Ещё раз повторю банальые истины:
1. эквивалентность объектов и эквивалентность ссылок — разные вещи, т.к. ссылка не есть объект. Именно поэтому две различных ссылки могут указывать на один и тот же объект.
2. для любого отношения эквивалентности, заданного для объектов, идентичность ==> эта эквивалентность. В силу рефлексивности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, enji, Вы писали:
E>Здравствуйте, мыщъх, Вы писали:
М>>я цейтон использую.
E>А как он правильно называется? Что-то не получается нагуглить http://cython.org/
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, samius, Вы писали:
S>С этим согласен. Но я не вижу, что я понял неправильно. Я показал как можно доказать неидентичность объектов, исходя из этого свойства идентичности.
Нет. S>Это не относится к OO идентичности.
Относится. Плоха была бы ОО-модель, если бы работала только для одного адресного пространства.
S>Для определения физической идентичности можно (не в COM). S>На COM предлагаю забить, потому как с ним явно оговорено, что ссылочная эквивалентность у него по IUnknown. Учитывая это он ведет В себя вполне ожидаемо и соответственно объеткам в других популярных языках/платформах.
В ответ предлагаю забить на понятие логической идентичности.
S>Ссылочная эквивалентность налагает дополнительное требование к концепции — существование ссылок и возможность проверить их эквивалентность, из которой должно следовать что объекты находятся по одному адресу и не могут обладать свойствами, отличающими их друг от друга. Слишком много допущений.
Смотря где. В чистой теории — да. Но в чистой теории словосочетание "свойство идентичности" означает всего лишь наличие функции ID(o:object), которая возвращает значение из некоторого множества, на котором определено отношение эквивалентности.
При этом ID(o1) == ID(o2) тогда и только тогда, когда o1 и o2 обозначают один и тот же объект.
В чистой теории можно "обозначить" объект как o1 или как o2, никак не оперируя ссылками.
На практике же ОО-систем без ссылок не бывает — понятие ссылки и разыменования необходимо для того, чтобы писать сколь-нибудь полезные программы. В программе нельзя сказать "отправить сообщение объекту, обозначенному как о1".
Поэтому этих допущений не "слишком много", а как раз нормально. Далее, про находимость "по одному адресу" я бы упоминать не рекомендовал — адрес в программировании является значительно более сильным понятием, чем ссылка, и, в отличие от последней, допускает значительно больше операций.
Кроме того, употреблять "объекты находятся" во множественном числе здесь не имеет смысла, даже отвлекаясь от понятия адреса.
Правильно говорить так: "из ссылочной эквивалентности следует то, что ссылки ссылаются на один и тот же объект".
S>>То есть у двух разных объектов гарантированно разные ссылки. S>Это верно. Но это не вытекает из определения идентичности.
Это вытекает из определения ссылки.
S>Не знал. Не буду проверять, но они могли бы вернуть один int. И что тогда?
Да, в общем-то, ничего.
S>Можно определение, которое бы гарантировало идентичность через ссылочную экивалентность напрямую, а не через серию уточнений?
Конечно http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf, секция 8.2.5.1, стр. 30.
Otherwise, if their exact type is a reference type, then they are identical if and only if the locations of the values are the same.
value-типы в .Net выходят за рамки чистого ООП, поэтому для них идентичность определена по-другому.
Секция 8.2.5 там же описывает ваш пример со строками с точки зрения стандарта.
Thus, the values of variables A and B are identical, the values of variables A and C as well as B and C are not identical, and the values of all three of A, B, and C are equal
S>Окей, я согласен заменить логическую идентичность на эквивалентность поведения. Этот термин хорошо отражает суть. Но надо заметить что формально "эквивалентность поведения" подпадает под определение идентичности. Иначе — мы будем подразумевать что-то разное.
Нет, не попадает. Два различимых объекта могут демонстрировать одинаковое поведение, находясь в одинаковом состоянии.
S>>Два объекта будут поведенчески эквивалентны, если их реакция на любое сообщение будет одинаковой. S>Это определение не годится. Нужно такое: если невозможно найти свойства, отличающие их
Нет.
1. Что вы называете "свойствами"?
2. Зачем вы их пихаете в понятие "эквивалентного поведения"? Очевидно, что эквивалентность поведения должна определяться в терминах поведения, и ничего больше. Пример на пальцах: "цветовая эквивалентность" для предметов не должна подразумевать одинаковость их формы.
S>Другое чем физическая идентичность — согласен. Но оно вытекает из определения идентичности.
Что откуда вытекает?
S>Но по-моему налицо повсеместное неправильное толкования определения идентичности.
Нет, неправильное толкование определения идентичности сосредоточено ровно в одном человеке.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Tilir, Вы писали:
T>Здравствуйте, licedey, Вы писали:
T>Но не вздумайте сделать проще чем надо.
+100500
если нужно просверлить одну дырку (например, в печатной плате), то это можно сделать и дрелью. если нужно просверлить сто дырок -- лучше воспользоваться сверлильным станком. если нужно просверлить 100500 дырок -- тут нужен сверлильный станок с токарным управлением, тьфу, с программным управлением...
и вот что интересно. просверлить 100500 дырок дрелью -- вероятность ошибится существенно выше, чем на программном станке. а вот если нужно просверлить одну дырку, то вероятность ошибки управления станком выше, чем если сверлить дрелью. так что самое главное -- выбор адекватных инструментов.
собствнно у меня есть только одно возражение к вашему посту. вы пишите "вот я тут заведу статическую переменную и никто не заметит -- бейте себя по рукам". по моему глубокому убеждению проблемы нужно решать по мере их возникновения. писать программы на вырост нужно лишь хорошо подумав, ибо это из серии: "почему сегодня не делают корабли, летающие к звездам?! ответ: потому что корабль, построенный завтра, прибудет быстрее. а корабль, построенный послезавтра, еще быстрее. и их обоих обгонит корбаль построенный лет через пятьдесят, но когда он вернется обратно, то обнаружит, что у человечества совсем другие проблемы".
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, Flem1234, Вы писали:
F>Здравствуйте, Lloyd, Вы писали:
S>>>>>Вообще-то нет. Кей напрямую идентичность не упоминает, но его messaging подразумевает возможность послать сообщение конкретному объекту, вне зависимости от его состояния. Так что без identity messaging не работает.
F>>>Как в SOA же нет состояния. F>>>Нет состояния — нет ООП.
L>>О том и речь, что утверждение "идентичность уже включено в понятие messaging", мягко говоря, сомнительно.
F>А как возможно отослать сообщение без адресата?
Адрес не есть Identity. За одним адресом может быть много identity, как в одной квартире могут проживать много человек.
Здравствуйте, Sinclair, Вы писали:
S>Более точным переводом identity является "идентифицируемость", но обычно переводят "идентичность". S>У вас есть какие-то сомнения в том, что в SOA каждое обращение идёт к какому-то конкретному сервису?
У меня есть сомнение, что можно говорить об идентичности в случае когда речь идет об одном экземпляре.
L>>Почему нет? В чем собственно отличие сервиса от очереди сообщений, если не принимать во внимание асинхронности, S>Очередь — всего лишь механизм доставки. Кто разгребает очередь?
А какое это имеет значение?
L>>Поведение с предысторий — можно. S>Можно, но получится собственно эмуляция ООП при помощи процедурного программирования (CFront помните?)
Здравствуйте, Vaako, Вы писали:
S>>Посоветуйте, что почитать, чтобы асилить этот МП/DSL? Желательно "для чайников", ибо раньше никогда не пробовал
V>Внутренние языки, специфичные для предметной области: V>здесь
Поглядел... Эта статья описывает одну из разновидностей подходов, так называемый fluent-интерфейс. По сути это DSL-ем не является. Это эмуляция средствами языков не имеющих более приличных средств для реализации DSL-е.
Меж тем ДСЛ-и бывают внешними, внутренними и вообще разными. А fluent-интерфейс — это самый простой и беззубый подход.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Ikemefula, Вы писали:
L>>Да, и отход от ООП в его классическом определении очень способствует этому.
I>Я считаю что SOLID == OOP. Потому можно разделять сколько угодно и как угодно.
SOLID не имеет никакого отношения к OOP. SOLID — достаточно общие принципы дизайна, применимые к любым парадигмам программирования (и не только программирования).
Здравствуйте, Enomay, Вы писали:
G>>Хранить ты его не можешь, как как нужна сумма за месяц с текущего момента. E>в сиквеле, нет, в документной базе, без проблем в общем-то.
Каким образом? Покажи как по изменяющемуся критерию хранить значение?
G>>>>Какая-то фейерическая глупость чтобы оправдать проблемы.
E>>>какие проблемы? у меня нет проблем. для меня DDD вполне эффективная методология. G>>В чем её эффективность? Есть выражение этой эффективности в цифрах? Я пока вижу проблемы с быстродейтсвием. E>это от того, что ты не понимаешь как это можно применять. E>на деле же, это можно развернуть как в масштабируемое приложение, так и пожертвовать быстродействием, если оно нас не волнует.
За счет чего? Что ты в DDD масштабировать будешь?
E>>>для тебя нет. но ты пытаешься, пыжишься. для чего только, не ясно. G>>Эффективность или есть или её нет, не бывает что для кого-то она есть, а для другого нет.
E>человек умеет работать каким-то инструментом. E>есть другой инструмент, более высокотехнологический, который позволяет повысить эффективность в 2 раза. E>но человек не умеет им пользоваться, и получает производительность в 2 раза ниже, от производительности своего более простого инструмента. E>ясно?
Человек может научиться, а могие чем больше узнают DDD, тем больше понимают его неэффективность. Какая обратная зависимость в отличие от "инструмента".
G>>То есть ты не знаешь в чем заключается методология DDD? E>ты волен считать так, как тебе больше нравится
Ты скажи. Мне интересно твое мнение, а то ты говоришь "методология DDD", но не можешь её описать.
G>>>>Каким образом? G>>>>Покажи его, чтобы оно было DDD и при этом достаточно эффективно. E>>>я уже приводил пару возможных примеров. G>>Оба гораздо менее эффективны чем могли бы быть. E>они достаточно эффективны с точки зрения реализации бизнес логики. остальное — технические детали.
То есть тормозное говно, и ты с этим согласен.
G>>Я не про масштабирование ресурсов, я про масштабрирование задачи. SOA-подход работает как на простой задаче, выполняющийся на одной машине, так и в сильно распределенной среде. В отличие от ООП. Объекты распределять крайне неэффективно. E>объекты распределять и не требуется.
А что будет распределяться?
E>более того, в реализацию SOA вполне может лечь ООП. а это значит, что там может быть использован DDD.
Не может, ООП как подход проектированию не совместим с SOA, а вот сделать сервисы SOA из классов, вполне может быть, только не ООП это.
И где там может быть использован DDD? Покажешь пример?
G>>В среднем anemic кода получается меньше, чем rich при той же задаче. О какой простоте поддержки ты говоришь? E>а говорил строками код не меряешь. E>но меньше кода, не значит лучше.
Да, лучше больше функционала, вот anemic и позволяет получить больше функционала за меньше строк (почему-то сходу написал "денег").
А что для тебя "лучше"?
E>>>ты опять говоришь глупости и перевираешь мои слова. перечитай еще раз про дистилляцию. G>>Читал, и что? Дистиллируй сколько хочешь, но если эксперт говорит что-то, то это надо или учитывать в модели или переучивать эксперта. E>я уже давно понял почему DDD методология для тебя не эффективна, но ты в очередной раз доказываешь мою правоту.
Каждый человек по-своему прав, и ты тоже. По-настоящему он прав, когда другие соглашаются. Ты неправ
G>>Думаешь если не слушать все вероятность ошибок уменьшится? Думаешь если ты при построении модели для бухгалтерии отбросишь обороты и потом совершенно случайно не сделаешь их, то пользователи останутся довольны? E>ты мешаешь всё подряд. у тебя каша в голове.
Это я пытаюсь из твоей каши хоть какую-то информацию достать, а то ты вещаешь лозунги с первой страницы domaindrivendesign.org и других сайентологов, не особо вникая о чем они.
E>>>у тебя получится anemic, у меня будет домен. G>>Приведи пример, посмотрим. E>ты слишком много хочешь. E>примеров, полный гугл.
Дай ссылку чтоли.
E>>>это в данном случае не важно. мы можем передать признак, можем передать число, равняющееся сумме предыдущих покупок, на основании которого будем делать скидку. G>>Это как раз важно, откуда мы передадим это число? E>ты в 10 раз задаешь один и тот же вопрос. перечитай тред, ответ там есть.
да, ответ там есть: мы число получим в сервисе, а потом передадим в объект, это менее эффективно чем считать скидку в сервисе. Ведь можно получить ту же скидку, не материализуя объект. ты не согласен и сам продолжаешь ходить по-кругу, пытаясь найти преимущества материализации объектов.
Вот только нет этих преимуществ.
E>>>проще говоря, добавь покупателю поле с суммой покупок, и получай её сразу с покупателем. G>>Нельзя, потому что требуется сумма покупок за последний месяц, то есть вычисление на момент покупки, хранить значение ты не сможешь. E>смогу.
Ок, покажи как.
E>>>хуже для тебя. потому что процедурный стиль программирования тебе ближе. E>>>в целом же, с точки зрения ООП, это правильная реализация. а DDD как раз более чем придерживается ООП парадигмы. G>>То есть единственная цель "придерживаться ООП парадигмы" чего бы оно не стоило? E>цель — использовать преимущества ООП парадигмы при решении задач. а так же DDD методологии. E>но для кого-то функциональное программирование кажется лучшим решением. это его право. и это 2 совершенно разных подхода.
Какие это преимущества, ты так и не ответил. У тебя получается преимущество ООП в использовании ООП. Остальное только недостатки.
E>>>верно и обратное, что в DDD не всегда и всё необходимо материализовывать. при необходимости, мы без проблем можем вызвать сервис, который сделает update с условием. G>>Да, и это уже будет anemic, потому что есть сервис и нет "доменных объектов". E>ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать.
Каким образом решают? Пример кода приведешь?
E>>>насчет размазывания логики по нескольки объектам, ну так это ж банальный принцип "ответственности" из SOLID, да и ООП в целом. так что это правильная реализация. G>>В SOLID куча других принципов, да и за пределами SOLID тоже, и DDD, как его описывает эванс, многое нарушает.
E>нет, DDD это классическое ООП, и ничего не нарушает.
Само по себе конечно не нарушает. Но если следовать фаулеру, то нарушает. Domain Model нарушает SRP как минимум.А если выносить из доменных объектов всю логику в "доменные сервисы", то нарушает принцип бритвы оккама.
E>а вот anemic, в общем-то, не является ООП подходом.
Почему не является? Там есть классы, есть поведение, инкапсулированное в классах, там есть полиморфизм, основанный на реализации интерфейсов. Вот и докажи что ООП нет? Может быть там нет ОО-дизайна, описанного Бучем и Мейером, так уже давно известно что они довольно плохой дизайн описали по куче формальных признаков.
E>разные реализации. ты используешь процедурный подход, мы ООП.
От повторения это правдой не станет.
E>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно.
Не очевидно, докажи.
Здравствуйте, licedey, Вы писали:
L>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
Пошли нафиг всех теоретиков и сделай проще-понятнее-удобнее для расширения. По-моему это и есть "внутренняя красивость".
Может там действительно процедурное программирование будет самым простым решением.
Здравствуйте, licedey, Вы писали:
L>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
Да, ты угадал. ООП совсем не подходит для проектирования программ.
Здравствуйте, Lloyd, Вы писали:
L>От того, что мы замесим в один класс и хранимые поля, и методы работы с ними, что от этого модель данных начнет меняться чаще?
Да. Ведь теперь она — одно целое с методами обработки.
L>Или если мы делаем проект, про который мы гарантированно знаем, что модель данных не будет меняться, то что ООП начнет "блистать во всей красе"?
Не понял вопроса.
L>Я могу еще понять аппеляцию к SRP, но не эту же мутную фразу приводить в кач-ве аргумента.
Фраза кристалльно прозрачная. Просто понимать ее нужно буквально и не искать скрытый смысл.
L>По моему мнению, с "процедурным" подходом получается все как-то проще, чем в тру-риче. Уже за это стоит его любить.
Еще раз — дело не в процедурный vs ООП. Дело в правильном построении объектной модели. Грамотному выбору соотношения coupling и cohesion. Т.е. все как обычно в ООП.
Точно та же ситуация, для примера, в SOA — контракты сервисов нужно менять реже просто в силу исходных требований. Отсюда — переход от OORPC к SOA. При этом за границами контрактов сервисов нам резать связи так сильно уже не нужно — ответные части менять намного проще.
... << RSDN@Home 1.2.0 alpha 5 rev. 1530 on Windows 7 6.1.7601.65536>>
L>Более того, очень многими неглупыми людьми ставится под сомнение его полезность. Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
Вас кто-то обманул. DDD и anemic model — перпендикулярные концепции. Вполне могут жить друг с другом, хотя бы потому, что DDD — не "насквозь оопшный" подход. Более того, они часто живут друг с другом — для этого в DDD придуман слой бизнес-логики.
Здравствуйте, Baudolino, Вы писали:
L>>Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions"). B>Вообще-то никакого ухода от ООП здесь нет. Логика, затрагивающая несколько сущностей, не обязательно должна быть инкапсулирована в одной из них. Вполне нормально, когда она инкапуслирована в каком-то контексте.
Откуда взялись "несколько сущностей"?
Еще немного, еще чуть-чуть и вы сами зададите вопрос о том, а в чем вообще смысл держать логику рядом с объектом. Где бенефиты?
Здравствуйте, Baudolino, Вы писали:
L>>Нет, это не вырожденный случай. Откройте Эванса и убедитесь, что эта "вырожденность" — на каждой второй диаграмме с сущностями. B>У вас какой-то особый навык делать могучие логические выводы из картинок в книжке. В данном конкретном случае не имеет никакого значения, что там нарисовал Эванс.
То вы просите цитаты, а как вам их дают, то сразу они оказываются не нужны.
B>Думайте своей головой.
Мои опасения про "список" только подтверждаются — вы умело продемонстриовали прием "Переход на личности".
L>>Или понятие "вырожденность" вы тоже как-то индивидуально трактуете и оно меняется от поста к посту? B>Меняется только у вас в голове, потому что вы не хотите внимательно прочитать, что я писал, и подумать над этим.
Вы не ответили на вопрос, как у вас так получилось, что слово "сущность" когда об этом говорите вы и ваш собеседник обозначает для вас не одно и то же.
Это ли не показатель, у кого что и где меняется.
И таки-да, еще вы не ответили на вопрос по поводу преимуществ рекомендуемого вами подхода.
L>>"Сервисный слой" — это и есть "поцедурный" подход. B>Ну это просто растиражированный здесь бред, который легко опровергается мной же приведенным примером, в котором сервис имеет состояние.
А где я писал, что сервим не может иметь состояния? Опять "подмена тезиса"?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали:
L>>Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions"). S>Это не определение. Это чушь, которой забивают мозг неопытным разработчикам. Потом их очень трудно лечить от заблуждений.
Ваш пост был очень глубок и убедтелен, он в корне перевернул представления всей индустрии о то, что такое ооп. Аргумент "чушь" мне показался особенно блистательным.
Пишите исчо.
S>Для начала, нужно твёрдо усвоить, что ООП — оно целиком про поведение. А не про структуру полей и методов.
Несомненно, Антон из Новосиборска туфты не напишет.
Здравствуйте, Lloyd, Вы писали:
L>С удовольствием почитаю. Но раз уж вы его рекомендуете, то вам несомненно не составит труда привести цитату автора, опровергающую формулировку из википедии.
Для начала можно взять более вменяемую формулировку из той же Википедии:
В центре ООП находится понятие объекта. Объект — это сущность которой можно посылать сообщения, и которая может на них реагировать, используя свои данные. Данные объекта скрыты от остальной программы
L>Факт 1: применение ООП (по википедии) приводит к " бесплодным спорам". L>Факт 2: моделирование от поведения приводит к правильному ответу. L>Вывод: ООП — целиком про поведение.
L>Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан.
Меня просто утомляет каждый раз приводить эту, достаточно банальную, цепочку аргументов, всякий раз, как в форум прибегает очередной знаток ООП, начитавшийся Авторитетов.
L>А так да, я согласен, "имеет смысл применять критическое мышление", причем прежде всего имеет смысл применять его к себе же.
Ну так я его к себе и применил. Я ООП начал изучать ещё по Turbo Pascal 6.0, примерно 20 лет назад. И все заблуждения, упорно насаждаемые недалёкими объясняльщиками, я честно разделял. Ровно до тех пор, пока не накопилась критическая масса фактов, противоречащих большинству мифов об ООП. Ну там, типа — "в ООП производится моделирование объектов предметной области при помощи экземпляров классов" и прочего.
Помимо мифов, существует также некоторое количество малоконструктивных подходов. В их числе и попытки моделировать иерархию классов, исходя из структуры данных. Несмотря на то, что иногда этот подход даёт более-менее приемлемые результаты, в целом он значительно чаще оставляет программиста наедине с неразрешимыми в рамках этого подхода вопросами.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Да, при помощи сервиса, а сущность "покупателя" будет DTO. Это уже похоже на нормальный дизайн. G>А он соотвествует DDD?
Абсолютно.
E>>и да, вероятно будет select n+1. E>>это криминально? в бизнес приложениях — нет. в высоконагруженном сайте? возможно. G> G>Значит DDD позволяет делать только тормозящее говно G>Что и требовалось доказать. G>Шучу конечно, но ощущение складывается именно такое.
select n+1 это проблема не ДДД, а предметной области. Ты никуда от неё не денешься.
E>>преимущества в организации слоя бизнес логики, который отражает действительную проблему. G>Так в чем это преимущество?
Преимущество заключается в том, что все операции которые зависят от домена, становятся предельно простыми.
E>>>>мы и говорим на одном языке с экспертами. о тех вещах, которые нас интересуют. и не говорим о тех, которые нас не интересуют. G>>>Тогда вы делаете программу, которая нужна вам, а не пользователям. G>>>А обычно наоборот, слушают заказчиков\экспертов\пользователей. E>>тебе так кажется. G>Ну конечно, только мне кажется что сделать успешный продукт можно только учитывая пожелания пользователей.
С таким подходом можно делать только хилые продукты. Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг
G>Так я с этого и начал. Вот есть у бухгалтеров баланс, это не балансовая ведомость, а некоторые данные, соотвествующие определенным правилам. еще есть обороты, остатки — тоже наборы данных, формирующиеся по определенным правилам. Как и правильно отражать в программе с точки зрения DDD?
Тебе покажется странным, но ДДД очень сильно похоже на то, что на этом форуме называется "функциональный дизайн".
Здравствуйте, Ikemefula, Вы писали:
E>>>и да, вероятно будет select n+1. E>>>это криминально? в бизнес приложениях — нет. в высоконагруженном сайте? возможно. G>> G>>Значит DDD позволяет делать только тормозящее говно G>>Что и требовалось доказать. G>>Шучу конечно, но ощущение складывается именно такое.
I>select n+1 это проблема не ДДД, а предметной области. Ты никуда от неё не денешься.
Полнейший бред. select n+1 это проблема реализации, когда для получения дочерних сущностей необходимо выполнять по одному запросу в базу (удаленному вызову) для каждой родительской. Если написать один запрос, который получает все данные, то это работает на порядок эффективнее.
Причем domain model по фаулеру и lazy load (как раз то что показывает эванс и другие апологеты DDD) подталкивают писать код, который делает select N+1
E>>>преимущества в организации слоя бизнес логики, который отражает действительную проблему. G>>Так в чем это преимущество? I>Преимущество заключается в том, что все операции которые зависят от домена, становятся предельно простыми.
За счет чего? Приведи пример.
E>>>>>мы и говорим на одном языке с экспертами. о тех вещах, которые нас интересуют. и не говорим о тех, которые нас не интересуют. G>>>>Тогда вы делаете программу, которая нужна вам, а не пользователям. G>>>>А обычно наоборот, слушают заказчиков\экспертов\пользователей. E>>>тебе так кажется. G>>Ну конечно, только мне кажется что сделать успешный продукт можно только учитывая пожелания пользователей. I>С таким подходом можно делать только хилые продукты. Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг
Ты хочешь сказать что можно сделать хороший продукт не учитывая пожелания пользователей?
G>>Так я с этого и начал. Вот есть у бухгалтеров баланс, это не балансовая ведомость, а некоторые данные, соотвествующие определенным правилам. еще есть обороты, остатки — тоже наборы данных, формирующиеся по определенным правилам. Как и правильно отражать в программе с точки зрения DDD? I>Тебе покажется странным, но ДДД очень сильно похоже на то, что на этом форуме называется "функциональный дизайн".
Вполне может быть что это так, вот только об этом никто не говорит. Или у тебя есть ссылки на подобные высказывания со стороны апологетов DDD?
Здравствуйте, Enomay, Вы писали:
E>>>Эванс, между прочим, об этом говорил. G>>Да, но они и другие не говорят для чего предназначен DDD. Потому что чем сложнее предметная область, там больше будет в ней выборок, для которых DDD не предназначен. Бухгалтерия — хороший пример.
E>выборка не есть логика.
То есть логика только в изменении данных?
Тогда задача получения суммы покупок для расчета скидки не является логикой, а сам расчет скидки является?
Какая-то фейерическая глупость чтобы оправдать проблемы.
E>проблема совершенно не в DDD, а в непонимании тобой это методологии.
Ну так попытайся объяснить в чем состоит методология DDD.
E>>>в этом нет ничего сложного даже применяя DDD методологию. G>>Ну ты уже показал что сделать это по DDD и эффективно нельзя? Или можно? E>конечно можно.
Каким образом?
E>>>не представляю, потому что нет ни условий, ни задачи. значит представлять нечего. E>>>а для каждой конкретно задачи, существует отдельное, и не одно, решение. G>>Так задача простая: для расчета скидки покупателя надо получить сумму покупок без скидок за последний месяц. E>решение не менее простое.
Покажи его, чтобы оно было DDD и при этом достаточно эффективно.
E>>>преимущество применения DDD методологии в более красивом и структурированном объектно-ориентированном коде, который собой отражает проблему и её решение. E>>>это же очевидно. E>>>но я тебе уже советовал не заморачиваться, а продолжать использовать процедурный подход. он больше тебе подходит. G>>Что значит "красивом и структурированом"? Это в каких цифрах выражается, хотябы косвенно? E>не все можно выразить цифрами.
Если ты не можешь выразить цифрами значит в этом нет реального value.
G>>Кроме того "красивый и структурированный" ОО-код может вести к проблемам быстродейтсвия, это ты и сам показал. E>иногда. но в большинстве случаев он легче масштабируется, что решает проблемы быстродействия.
Как раз в большинстве случаев ОО-код хуже масштабируется. Потому что:
1) Надо таскать identity
2) Надо материализовывать объекты потому что поведение внутри объектов
Очень хорошо масштабируется SOA, причем как вверх, так и вниз. Там как раз отказ от identity и создания объектов, там только сервисы и данные (DTO).
G>>Тогда в чем преимущество "красивости и структурированности"?
E>в том же, в чем и любого другого хорошего кода, конечно же. E>неужели это так не очевидно?
Совсем не очевидно, потому что понятие "красивости" у каждого сильно свое и никак не коррелирует с качеством кода (объемом, плотностью багов, сложностью поддержки итп).
E>>>DDD методология совершенно не обходит стороной пожелания пользователей. а наоборот. работает с ними на одном языке. E>>>а ты что-то опять путаешь. G>>Так ты мне доказывал что не надо учитывать "неудобные для DDD" требования пользователей. Как учесть требования получения в программе остатков и оборов по счетам для бухгалтерии? Ведь остатки и обороты это не сущности, а наборы данных.
E>ты глупости говоришь.
E>>>эксперты говорят на языке объектов.
G>>Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд.
E>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели.
Ты сказал что то что говорят эксперты не надо рассматривать при построении модели.
E>я не доказывал, но пытался дать понять, что те вещи, которые не требуются при разработке модели, нужно опускать.
Если о чем-то говорит эксперт, то это должно быть в модели, потому что иначе не будет Ubiquitous Language, к которому стремится DDD.
Иначе вам придется переучивать эксперта, а это сложно.
E>и остатки и обороты можно представить сущностями, пользуясь DDD методологией. но ты идешь от обратного, потому для тебя это наборы данных, и DDD скорее всего, как и ООП в целом, ты понять не сможешь, так как мыслишь с "процедурной" точки зрения.
Ну покажи как их представить сущностями и как с ними работать в программе. (у тебя получится anemic)
E>>>получение данных — это лишь запрос в базу. сами данные при этом не меняются. а значит никакой логики в этом действии нет. G>>То есть "логика" это изменение данных? А если частью логики являются такие запросы? G>>Например те же самые скидки.
E>для расчета скидки, нам нужно знать, делать её, или нет. как мы получим этот признак, нас не итересует.
Нам важна величина скидки, а не вопрос делать её или нет.
E>>>они могут быть чем угодно. E>>>как выборками, в твоём случаи, E>>>так и просто полем объекта, которое изменяется каждый раз с приходом/уходом денег. соответственно нам нет необходимости пересчитывать баланс каждый раз. мы можем использовать готовое значение в нашей модели. проще говоря, для примера, это будет состояние объекта "баланс". G>>Это понятно, а как это будет выражаться в коде с точки зрения DDD?
E>так, как ты это реализуешь. E>самые простые 2 варианта, на которые собственно должно было натолкнуть предыдущее предложение. E>а) сервис расчитывает баланс и передает его доменному объекту при его создании, после чего тот выполняет свою логику с учетом этих данных
Браво, расчет скидки размазан по двум объектам.
E>б) загружаем доменный объект из базы при помощи ORM и передаем ему управление.
Какой объект, нет объекта "скидка", потому что она требует расчета на момент покупки.
E>оба варианта очень похожи, и по сути одинаковы, различия лишь в реализации.
И оба они хуже, чем помещение всего алгоритма расчета в сервис.
E>и того имеем все данные и логику в доменной модели, что не противоречит DDD.
Она становится размазанной по нескольким объектам. Материализация объектов избыточна получается в данном случае, она нужна только чтобы вызывать логику. Тогда логику лучше поместить вне этих объектов.
Здравствуйте, Enomay, Вы писали:
G>>Да, и это уже будет anemic, потому что есть сервис и нет "доменных объектов".
E>ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать.
Ваши доменные объекты занимаются делами вовсе не предметной области.
E>>>насчет размазывания логики по нескольки объектам, ну так это ж банальный принцип "ответственности" из SOLID, да и ООП в целом. так что это правильная реализация. G>>В SOLID куча других принципов, да и за пределами SOLID тоже, и DDD, как его описывает эванс, многое нарушает.
E>нет, DDD это классическое ООП, и ничего не нарушает.
Эванс пишет что есть такие аспекты домена, которые являются отступлением от традиционного ООП. Цитату я приводил.
E>а вот anemic, в общем-то, не является ООП подходом.
С этого и начали этот флейм. Не согласен с категоричностью. Анемик он лишь о сущностях домена а не вцелом о подходе.
E>разные реализации. ты используешь процедурный подход, мы ООП.
Выглядит как гипноз
E>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно.
очевидно — в знач. сказуемого совершенно ясно, не вызывает сомнений
Я не первый, у кого вышеописанное вызывает сомнения.
Здравствуйте, Ikemefula, Вы писали:
L>>Сам осилишь: cтруктурка с указателем на вершину стека + пачка методов.
I>И где же здесь "более ООПшен, чем ОО" ? Ни по одной версии, Симула или Кея, это не будет ООП. Для Симуловской классики инкапсуляция отсутствует начисто, полиморфизм невозможен в принципе(разве что через void**). Для Кеевской нужна мессагинг + идентити.
I>
Павел, читайте пост, на который отвечаете. Не в первый раз уже советуют.
Здравствуйте, Lloyd, Вы писали:
I>>И где же здесь "более ООПшен, чем ОО" ? Ни по одной версии, Симула или Кея, это не будет ООП. Для Симуловской классики инкапсуляция отсутствует начисто, полиморфизм невозможен в принципе(разве что через void**). Для Кеевской нужна мессагинг + идентити.
I>>
L>Павел, читайте пост, на который отвечаете. Не в первый раз уже советуют.
Ты слишком часто забываешь про что шла речь.
Ты сказал "процедурный подход более ООПшен, чем ОО" и я попопросил тебя продемонстрировать это на примере процедурного стека. Ты привел пример который даже с натягом не может считать ОО.
Потому снова та же просьба — покажи таки стек в процедурном подходе, что бы было очевидно, что он "более ООПшен? чем ОО"
Здравствуйте, Enomay, Вы писали:
E>я считаю что стоимость заказа — это свойство самого заказа, и логично если оно будет находится в нем.
Это достаточно неожиданное предположение, которое, вообще говоря, нужно аргументировать.
Не всё, что можно рассчитать о заказе, стоит считать его свойством. Вот, скажем, среднеквадратичное отклонение количеств товарных позиций — это тоже "свойство самого заказа". Логично ли, если оно будет находиться в нём?
E>расчет же этой стоимости происходит, грубо говоря, суммированием всех продуктов в заказе.
Хм. Это очень интересный момент, вот это "грубо говоря". Сразу возникает вопрос — а когда это может быть не так?
Стоимость, о которой мы говорим, это уже с учётом скидок или нет? Если с учётом, то мы потенциально имеем циклическую зависимость — стоимость зависит от скидки, которая зависит от стоимости.
S>>2. Необходим ли для подсчёта стоимости заказа доступ к непубличной части его состояния? E>исходя из вышесказанного, ему не требуется доступ за пределы себя самого, все необходимое он имеет.
Вы отвечаете не на тот вопрос. Я спрашивал ровно обратное — требуется ли ему доступ "вовнутрь", к чему-то такому, что не видно снаружи.
S>>3. Есть ли причины полагать, что для разных наследников класса Order будут реализованы разные способы подсчёта стоимости? (Реализацию моков в расчёт не берём — это артефакты процесса производства)
E>нет, ордер есть и будет оставаться всегда одним. он не содержит хитрых алгоритмов, он лишь суммирует кол-во записей внутри себя. а вот какую цифру вернут эти записи, зависит исключительно от них. и это уже зависит от внутренней реализации.
Отлично. То есть производительность у нас тут гарантированно хреновая. Поясню на примере: если мы влезаем в один из OrderLine и меняем его quantity, то при сохранении нам нужно пересчитать OrderTotal. А для этого, в свою очередь, нужно материализовать все OrderLine, а не только ту, которая изменялась, и повызывать у каждой из них GetTotal(), который, в свою очередь, потребует материализовать Product(), чтобы позвать у него GetPrice(). То есть мы имеем как бы O(N) обращений к DAO на ровном месте.
Что характерно, никакой "логики" (то есть нетривиального поведения) ни у каких объектов здесь нет. Вся их работа сводится к тому, чтобы запретить программисту получать тот же результат через
select sum(quanity * p.price) from orderLine ol inner join product p on ol.productId = p.Id where orderLine.orderId = @orderID
S>>Вообще, в целом, какие конкретные преимущества даст внесение метода подсчёта стоимости заказа внутрь Order, по сравнению с размещением его снаружи? Желательно — конкретно. Ну там, если преимущество "гибкость" — то в чём именно, если "масштабируемость" — то каким образом она достигнется и т.д.
E>тем, что мы имеем иерархию классов, приблизительно такую
E>Order — OrderLine — Product
E>каждое звено в цепочке несет ответственность за себя. продукт знает свою цену. он же может вернуть свою цену со скидкой, если его взяли более 2х штук. например. или потому что сегодня вторник. все зависит от условий.
E>но в данном случае для изменения расчета скидки на продукт, нам нужно будет изменить только класс конкретного продукта, а не перелопачивать весь метод сервиса, который в итоге обрастет кучей if/case. E>а класс Order останется неизменным. E>SRP как бы
Отлично. Вы не только неправильно понимаете ООП, SRP вы тоже понимаете неверно.
Поясню:
1. Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе (покупателя, оформляюшего менеджера, и т.д). Вы засовываете в него ещё одну обязанность — подсчитывать сумму позиций.
Очевидно, что логика "подсчитать сумму позиций" будет применима не только к Order, но ещё много к чему. К накладной, счёт-фактуре, возвратной накладной, акту пересортицы, и прочему. Из-за того, что вы всунули эту логику внутрь заказа, вы будете вынуждены заниматься унылым Copy-Paste. Ну или мучительно думать, кого из этих классов от кого отнаследовать — в целом это изоморфно знаменитой проблеме "эллипс vs круг".
2. Продукт у вас, помимо обязанности "предоставлять информацию о продукте", стал внезапно обязан рассчитывать собственную стоимость.
Такой продукт крайне сложно реализовать.
Ваше предложение "вернуть свою цену со скидкой, если его взяли более 2х штук" просто прекрасно — тем, что непонятно как его реализовать. В продукте нет информации о том, сколько его взяли. Банальная схема "взявшему два третий бесплатно" в принципе нереализуема при такой иерархии объектов.
Уже пункта 1 достаточно для того, чтобы даже оставаясь в рамках заведомо тормозной и плохомасштабируемой Rich-ORM модели захотелось сделать что-то вроде
public interface IAccountableItem
{
decimal Total { get; }
}
public static class OrderUtils
{
public static GetTotal(this IEnumerable<IAccountableItem> items)
{
return items.Sum(item => item.Total);
}
}
То есть тут даже OrderService не нужен — это, вообще говоря, настолько банальная арифметика, что вставлять её в модель вообще пахнет оверархитектингом.
В пункте 2 мы понимаем, что задача "ввести в систему новую скидку" эквивалентна задаче "внести новый класс продукта". Вы думаете, что это гораздо легче, чем поменять класс типа OrderService.
А у вас уже продумана схема смены класса для существуюшего объекта? Буквари ООП стыдливо обходят этот вопрос молчанием. И правильно делают — в общем случае ничего хорошего ООП не предлагает.
OrderService имеет замечательную особенность — он Stateless. То есть мы можем его в любой момент заменить. Мы можем позволить старому и новому OrderService работать одновременно, до окончания всех транзакций, обрабатываемых OrderService. Поэтому любые изменения туда стоят значительно меньше, чем изменения в классе Product.
При этом вы почему-то думаете, что OrderService обрастёт каким-то набором "if-else" для расчёта скидки, как будто там запрещено использовать наследование, полиморфизм, и агрегацию.
На мой взгляд, всё как раз наоборот — в DiscountService у нас доступно всё. И история заказов конкретного кастомера, на основе которой мы можем перевести его в класс "ВИП клиентов" со своим набором скидок. И данные о количестве товаров каждого вида в данном заказе, чтобы реализовать "взявшему два по 0.5 Старого Мельника третья кружка бесплатно".
И данные о том, в какое время заказ был сделан и оплачен, чтобы реализовать happy hour.
А использовать эти данные при помощи if-else совершенно необязательно. Ведь есть же ООП. Десятки паттернов — визитор, стратегия, и прочее. Можно строить произвольные цепочки из бизнес-правил при помощи совсем небольшого набора правил по композиции их друг с другом. Это значительно удобее, чем писать всё в топорном стиле хранимых процедур.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Ikemefula, Вы писали:
I>Я собственно и ждал похожего примера. Хочется узнать что такое "в значительной мере ООП", т.к. этой фразой подразумевается, что ООП не совсем полноценный.
Не все вызовы из WinAPI ведут себя как методы объектов.
I>В данном случае квази-OOP достигается не за счет языковых средств, а за счет возможностей/особенностей операционной системы. А хотелось бы примерно так как было обещано на Object Pascal.
А какая разница, на Object Pascal или нет? Залудить CreateFile/FileRead/FileWrite/CloseHandle можно хоть на Visual Basic, хоть на виртовском паскале.
Дело же не в языке, а в том, как устроено решение.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
L>Ошибаешься
Вообще-то нет. Кей напрямую идентичность не упоминает, но его messaging подразумевает возможность послать сообщение конкретному объекту, вне зависимости от его состояния. Так что без identity messaging не работает.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Flem1234, Вы писали:
S>>>Вообще-то нет. Кей напрямую идентичность не упоминает, но его messaging подразумевает возможность послать сообщение конкретному объекту, вне зависимости от его состояния. Так что без identity messaging не работает.
L>>т.е. SOA — это ООП? Или SOA — это не messaging?
F>Как в SOA же нет состояния. F>Нет состояния — нет ООП. F>Нет ножек — нет мультиков.
О том и речь, что утверждение "идентичность уже включено в понятие messaging", мягко говоря, сомнительно.
Здравствуйте, Lloyd, Вы писали: L>Идентичность чего с чем?
Более точным переводом identity является "идентифицируемость", но обычно переводят "идентичность".
У вас есть какие-то сомнения в том, что в SOA каждое обращение идёт к какому-то конкретному сервису?
L>Почему нет? В чем собственно отличие сервиса от очереди сообщений, если не принимать во внимание асинхронности,
Очередь — всего лишь механизм доставки. Кто разгребает очередь?
L>Поведение с предысторий — можно.
Можно, но получится собственно эмуляция ООП при помощи процедурного программирования (CFront помните?)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Снаружи нет возможности идентифицировать конкретный сервис, вернее экземпляр сервиса.
Зато есть возможность идентифицировать эндпоинт. И совершенно пофигу, сколько там за фасадом экземпляров реализации — на уровне контрактов этого не видно.
G>Снаружи мы можем говорить только об эквивалентности. И с точки зрения SOA все сервисы с одинаковым контрактом эквивалентны.
Если есть внутренний стейт — нет, не эквивалентны.
... << RSDN@Home 1.2.0 alpha 5 rev. 1530 on Windows 7 6.1.7601.65536>>
Здравствуйте, Enomay, Вы писали:
E>это отличается лишь местоположением, от моего подхода. и еще тем, что я работаю с теми данными, которые имею, а вы работаете с внешними.
Совершенно верно. Местоположение, в свою очередь, определяет нефункциональные характеристики решения.
E>если у вас другое мнение, вы в праве делать иначе
Вы можете считать, что аппараты тяжелее воздуха не могут летать. Это не означает, что мы должны решать этот вопрос голосованием.
E>но увеличиваем сложность и площадь сервиса. закон сохранения энергии, да. если что-то где-то пропало, то что-то появится в другом месте )
Нет. 2O(N^2) не то же самое, что O(2N^2).
E>у меня логика лежит ближе к данным, на которые она распространяется. у вас наоборот, как я писал, данные отдельно, логика отдельно. E>я не против такого решения, и там, где оно уместно, применяю. но если можно вырисовать красивую и функциональную рич модель, я это сделаю.
Я бы тоже не отказался. К сожалению, случаев уместного применения рич-модели я за 19 лет работы не встречал.
E>ну и про тестирование совершенно не аргумент. и тут и там метод. тестируются одинаково. как минимум. более того, у меня еще и разделено все на запчасти, каждая из частей может быть протестирована отдельно от общей инфраструктуры. сервисы обычно все же жощще завязаны.
Вы почему-то сравниваете "хорошую" реализацию рич-модели с "плохой". Я точно так же могу обвинить рич в том, что там вся логика расчёта скидок с километровыми if-ами и подтягиванием 99% содержимого базы в память засунута в несчастный Order. Но зачем?
E>масло масленое какое-то. методы которые работают с данными остаются снаружи, а что же тогда считает сумму заказа, если все данные с другой стороны.
Я же показал вам код — что именно вам непонятно?
Поймите, бывают методы, которые требуют доступа к внутренним данным. И бывают все остальные методы. Гуру ООП советуют вытаскивать все остальные методы наружу — это улучшает инкапсуляцию и cohesion, уменьшает coupling.
E>не всегда это так. это скорее некая копия продукта. ведь мы хотим хранить историю заказов? если будем хранить ссылку на оригинал, то при изменении его цены, у нас изменятся все заказы. а этого быть не должно.
S>>Вопрос повышенной сложности: а что, если мы добавили в ордер сначала плеер, а потом телевизор?
E>да, это правда очень хороший вопрос. и я с ходу не готов дать на него ответ. E>могу предположить, что при возрастающей сложности системы расчета заказа, всё это будет обрастать неимоверным кол-вом вспомогательных сервисов.
Я вам привёл код сервиса, который корректно обрабатывает все эти случаи. Никакого "неимоверного" количества не потребуется. Всё, что будет нужно — горсть наследников DiscountRule. Возможно, DiscountRule будут распилены на ещё более мелкие запчасти для уменьшения общего количества кода. Всё это живёт в пространстве имён DiscountService.
Это и есть простая и понятная объектно-ориентированная модель. А то, что вы предлагаете — это городить костыли, искусственно запихивая в объекты несвойственную им функциональность.
E>и он очень близко к вашему решению на основе сервисов.
Это будет по-прежнему далеко от моего решения на основе сервисов. В частности, граф зависимостей будет выглядеть радикально по-иному. Даже если вы скопируете моё решение 1-в-1, только разместив код внутри класса Order.
E>некоторые вопросы на столько абстрактны и каверзны, что несколько отдаляются от действительности, а посему, и ответ на них найти не просто, а часто, и бессмысленно. мы рисуем схему к совершенно абстрактному магазину, требования к которому меняются ежесекундно. у вас есть готовое решение, я за вас рад.
У меня нет готового решения. У меня есть подход, который позволяет легко и непринуждённо генерировать решения к произвольным требованиям. А у вас есть только желание "засунуть логику поближе к данным", которое в жизни будет приводить к постоянному редизайну уже готовой системы.
E>ну вот, еще один человек требует код. E>но кода не будет. приведи я его вам, вы скажете "ага! а вот эта фишка в нем работать не будет", и будете совершенно правы, так как я не учел её, но лишь потому, что вы заранее её не упомянули. E>именно по этой причине сие бессмысленно.
Ну а вы как хотели? Это жизнь; водопадная модель не работает. Ваша архитектура должна быть устойчива к изменению требований. Мою модель легко расширять, не трогая готовый функционал. Ваша потребует нудных проверок процедур апгрейдов — потому что вам придётся всё время вносить изменения в существуюший код классов. E>но, как я уже было предлогал, мы можем поставить задачу и представить 2 разных решения, а дальше вести обсуждении на основе их.
E>если вы вернетесь на пару постов назад, увидите, какие-то остатки, возвраты и прочую ерунду.
Это не ерунда. Речь не об Order, а о других классах той же модели. Вам трижды уже написали, что помимо "чеков", в магазине фигурирует ещё много похожих объектов. И внешний метод расчёта суммы ордера можно повторно использовать. А ваш метод — нельзя.
E>а скидки не участвуют в подсчете суммы товаров заказа?
Участвуют. Просто тогда получается, что ордер не только "суммирует".
E>конечно он может общаться с окружающим миром. разве я это запрещал? или говорил что кто-то другой запрещает? E>но основная логика класса сконцентрирована на внутренних объектах. E>возьмите объект Window в .NET. он ведь отрисовывает только свои контролы, а не чужие, правда?
Теперь вы приплетаете сюда ещё и концепцию владения. Давайте не будем об этом разговаривать, а то мне придётся ещё 30 постов объяснять, чем отличается обязанность по контролю за временем жизни от visibility и access control?
E>в восприятии окружающего мира? )
А, ну да.
E>там другая задача, это далеко не интернет магазин, это тонны разнородных данных, которые нужно было агреггировать) но к делу это мало относится.
Ну почему же — очень интересно. Неужели вы приделали к этим данным методы, вместо того, чтобы написать иерархию агрегаторов?
E>хотите отбросить — отбрасывайте. тот подход к реализации, что пропагандирует большинство, при работе с анемик моделью, лично я не считаю true OOP. но это ведь мое мнение, и я его никому не собираюсь навязывать.
Ок, это позиция. Она некорректна, но это нестрашно — достаточно поменять термины. Если переименовать то, что вы называете true OOP, в rich model, то станет намного меньше разногласий.
Также не ожидайте того, что сама по себе rich-ness даст вам какие-то реальные преимущества — ну, кроме морального удовлетворения от Исполнения Заповедей. То есть я и так вижу, что конкретно это преимущество для вас на первом месте, но это со временем пройдёт.
E>это больше похоже на то, что вы сами не уверенны, но если удастся убедить меня, то вы одержите победу над собой, и ваши сомнения развеятся. но увы, я останусь при своём
Не, у меня просто нетерпимость к заблуждениям.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Enomay, Вы писали:
S>>Давайте всё же добавим в систему ещё одно реалистичное требование. Давайте сделаем так, чтобы на большинство товаров распространялась накопительная скидка, привязанная к покупателю (скажем, 10%), но для некоторых особо популярных товаров этой скидки не было. S>>Как это отразится в вашей красивой архитектуре? E>товар вернет цену с учетом накопительной скидки?
Как хотите — пусть товар возвращает цену с учётом накопительной скидки. Приведите код в студию. Может быть это несложное упражнение поможет вам понять, почему ваша идея не заслуживает права на применение.
E>товар занимается определением собственной цены, с учетом вероятной скидки. для этого у него есть всё необходимое.
Ну откуда же? У товара ничего этого нет. Вот вам для первой же рассмотренной категории скидок потребовалось срочно внести в товар то, чего в нём не было. Вы добавили атрибут "количество_без_скидки", добавили аргумент "количество" в метод GetPrice().
Для следующей скидки вам придётся снова переделать класс товара.
При этом придётся думать, каким образом реализовать процедуру апгрейда — ведь у вас уже 12000 экземпляров того, старого класса "товар". Структура нового со старым не совпадает. Попробуйте найти в учебниках по ООП ответ на вопрос "как сменить класс у существующего объекта с сохранением его идентичности".
Я смотрю, идея иметь несколько разных потомков для класса Product, в зависимости от стратегии
E>это может быть реализовано как связка товаров, так и другим образом. E>а вы все время почему-то пытаетесь использовать одну и ту же реализацию для разных случаев скидок. и это плохо получается. что не удивительно.
Почему? Получается прекрасно — я вам в четвёртый раз напомню, что скетч архитектуры, закрывающей вопрос для крайне широкого набора случаев, я привёл ещё вчера. Просто я пользуюсь ООП для решения задачи, а вы — нет.
E>какое имеет значение, нравится оно мне или нет? я ведь не пытаюсь тут кому-то доказать или навязать какое-то решение, в отличии от вас.
Я не навязываю решение. Я показываю, что ваш подход заводит вас в тупик на каждом шаге. А мой приводит к корректным решениям.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
S>>>Я как-то плохо себе представляю вот эту "эквивалентность". Вот есть у меня, допустим, контракт на OrderTracking. S>>>Он типа весь стандартный. И что, мне должно быть пофигу, вызывать его для Fedex, UPS, или DHL?
G>>Судя по тому что UDDI не пошел в массы скорее всего так и предполагалось. Но не получилось. S>Не, я не про UDDI. Я про то, что если моя посылка отправлена федексом, то ДХЛ можно хоть заспрашиваться о ней.
UDDI как раз долежн позволять скрыть разные сервисы. Мы ему интерфейс — он нам эндпоинт. С этой точки зрения должны быть все сервисы эквивалентны. На практике такое не работает.
S>То есть — имеем state. Клиентский код для общения с сервисами может быть одним и тем же, но вызов мы отправляем конкретному сервису. Что, очевидно, изоморфно ООПу.
Если рассматривать ООП с точки зрения Кея, то и erlang с процессами более чем соответствует. Если же рассматривать ооп с точки зрения Буча, то нет.
Вообще свойство identity в программе выражается в том что для пары объектов можно проверить идентичны они или нет. Для сервисов в общем случае это нельзя сделать. За разнымb эндпоинтами может скрываться один сервис, за одyим эндпоинтам может быть много сервисов (например внутри существлять дисптчеризацию по IP), а может вообще не быть сервиса по указанному эндпоинту.
Поэтому endpoint на роль identity не подходит никак.
Здравствуйте, Ikemefula, Вы писали:
I>Не льсти себе, персонально для тебя у меня нет никаких приёмов Потому я жду ровно столько же как и от любого другого. Более того, скажу страшное, я даже не всегда замечаю кому именно пишу ответ В данном топике я например не сразу заметил что разговариваю с Lloyd
Что, Павел, в лишний раз подтверждает факт, что вы не читаете не только пост, на который отвечаете, но и даже то, что вы сами пишете.
Иначе как понять, что вы не заметили "Здравствуйте, Lloyd, Вы писали:" в каждом своем ответе?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
I>>>Так ведь исходная посылка у Flem1234 — "если нет состояния, то ООП тоже нет"
G>>Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
L>А identity совсем без состояния реализуема?
Если к отсутствию состояния добавить требование детерминированности, то у однотипных объектов поведение будет неотличимо, т.е. их идентичность не может быть опровергнута. А раз так — нет оснований их считать неидентичными. Это абсолютная аналогия объектам, расшаривающим общее состояние. Разница может быть выявлена лишь с помощью сравнения ссылок, что нельзя отнести к поведению объекта.
детерминированность достаточное требование, но не необходимое. Объект-обертку(без состояния) над статическим методом Console.ReadLine() можно считать идентичным другому такому же объекту.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>В этом и заключается свойство identity. При этом если a == b, то a.Equals(b) == true. S>>>Тут мы получили равенство ссылок, а не отличие в поведении объектов. G>>Это и есть идентичность в отличие от эквивалентности. S>Не согласен. S>Сравнение ссылок (при отсутствии оператора сравнения) дает нам ссылочную эквивалентность; вызов Equals дает нам эквивалентность по умолчанию; Comparison<T> дает нам любую другую эквивалентность. В то время как идентичность обусловлена идентичным поведением. S>Объекты a и b не идентичны, т.к. по разному реагируют на x.Equals(b). Но их можно сделать таковыми, переопределив Equals соответствующим образом.
Ссылочная эквивалентность — реализация идентифицируемости (не идентичности, в данном случае слово наталкивает тебя на неверные размышления) в большинстве языков. Вот идентифицируемость в БД осуществляется по ключу, из за этого и возникают проблемы объектно-реляционного отображения.
S>два объекта с одинаковым поведением и без состояния отличить невозможно. Но можно отличить ссылки на них.
Что значит отличить?
S>Это не одно и то же, т.к. адрес объекта или ссылка на объект — это не внутренний атрибут объекта и он не имеет отношения к поведению объекта в общем случае.
Да ну? Покажи как в C# получить ссылку отдельно от самого объекта?
S>Верно то, что получив положительный результат сравнения ссылок на равенство, можно делать вывод об идентичности объектов. Обратное не верно (из идентичности поведения равенство ссылок не вытекает). S>Наоборот, получив отрицательный результат сравнения ссылок на равенство, можно делать вывод лишь о том что мы имеем разные экземпляры. Но идентичность этим самым не опровергнута.
Еще раз, не идентичность, а идентифицируемость. В C# для объектов reference-типов идентифицируемость по ссылке.
Метафора identity — паспорт. Если два человека выглядят и ведут себя одинаково, но у них разные паспорта, то это разные люди. Если один паспорт — то это один человек.
В "мире" SOA вместо "паспорта", используется "адрес проживания". Что скрывается за этим адресом и кто получает сообщения снаружи не видно.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Вот идентифицируемость в БД осуществляется по ключу, из за этого и возникают проблемы объектно-реляционного отображения. S>Верно, а в ООП объекты идентифицируются по поведению.
Нет, идентифицируемость объекта ортогонально поведению. Фактически возможность узнать являются ли два объекта идентичными (не путать с эквивалентностью). Свойство идентичности нельзя нарушить, в отличие от эквивалентности, которое может зависеть от состояния.
S>>>Это не одно и то же, т.к. адрес объекта или ссылка на объект — это не внутренний атрибут объекта и он не имеет отношения к поведению объекта в общем случае. G>>Да ну? Покажи как в C# получить ссылку отдельно от самого объекта? S>Не получить, но это не делает ссылку атрибутом объекта. Тем более, что объект без ссылки в дотнете существовать может (недетерминированное время).
Нет, может существовать память объекта, но не сам объект, потому что объект — identity+поведение. Если на объект нет ссылок, то фактически у него нет ни identity и нету способов получить поведение.
Не стоит путать концептуальные вещи с деталями реализации. Ведь в .NET value-типы наследуются от Object, но это не значит что для каждого value-типа есть указатель на VMT.
S>>>Наоборот, получив отрицательный результат сравнения ссылок на равенство, можно делать вывод лишь о том что мы имеем разные экземпляры. Но идентичность этим самым не опровергнута. G>>Еще раз, не идентичность, а идентифицируемость. В C# для объектов reference-типов идентифицируемость по ссылке. S>
S>Identity allows comparison of references. Two references can be compared whether they are equal or not. Due to the identity property, this comparison has special properties. If the comparison of references indicates that the references are equal, then it's clear that the two objects pointed by the references are the same object. If the references do not compare equal, then it's not necessarily guaranteed that the identity of the objects behind those references is different.The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>(http://en.wikipedia.org/wiki/Identity_%28object-oriented_programming%29)
S>т.е. согласно выделенному — из отсутствия равенства ссылок не следует различная идентифицируемость.
Да, потому что это деталь реализации.
S>В том числе в C#.
Нет, ты не можешь в C# получить пару объектов reference типа для которых object.ReferenceEquals(a,b) == true, но a.Equals(b) == false, если нормально реализован Equals. Более того гайдлайн требует чтобы реализация equals была такова что идентичные объекты будут эквивалентны. На это и опирается ООП.
G>>Метафора identity — паспорт. Если два человека выглядят и ведут себя одинаково, но у них разные паспорта, то это разные люди. Если один паспорт — то это один человек. S>Если identity принимается за паспорт, то при разных паспортах мы получим разное identity. Из этого следует что экземпляры разные. Верно. Но из того что паспорта одинаковы не будет следовать что экземпляр один.
Ну возьми SSN\СНИЛС, он не меняется.
S>Это как если в дотнете взять две строки с одинаковым содержимым (пусть будут получены разным способом, что бы избежать скидки на интернирование). Поведение одинаково. о них говорят same identity, даже если ссылки будут отличаться.
Где говорят? Ссылку дай что ли. То что на equal string говорят same identity не делает чести тому кто говорит. И уж точно никак не влияет на соотношение identity и equal в ООП.
G>>В "мире" SOA вместо "паспорта", используется "адрес проживания". Что скрывается за этим адресом и кто получает сообщения снаружи не видно. S>Это не имеет значения, пока сервис не начнет вести себя в зависимости от накопленной в своем внутреннем состоянии истории. А пока поведение конкретных получателей за этим адресом неотличимо, какая разница, кто из них получит сообщение? S>Даже если история копится в БД, но различные экземпляры сервиса реагируют на нее одинаковым образом (шарят это состояние), это позволяет говорить об их same identity (см выделенное курсивом в цитате с википедии).
Нет, ты опять подменяешь понятия. Ты говоришь об эквивалентности (взаимозаменяемости) сервисов, а не об идентичности. Хотя тут ты даже доказать ничего не сможешь, потому что нарываешь на проблему тотальности.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
L>>>Более того, очень многими неглупыми людьми ставится под сомнение его полезность. Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
I>>Почему это анемик процедурный ?
L>Потому что имеем разнесение данных и способов работы с ними. Может "процедурный" и не самое удачное слово, но вот "ООП" уж тут точно ни в какие ворота.
ООП — это только поведение. Данные там вообще ортогональны.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: S>>Если к отсутствию состояния добавить требование детерминированности, то у однотипных объектов поведение будет неотличимо, т.е. их идентичность не может быть опровергнута. А раз так — нет оснований их считать неидентичными. Это абсолютная аналогия объектам, расшаривающим общее состояние. Разница может быть выявлена лишь с помощью сравнения ссылок, что нельзя отнести к поведению объекта.
S>>детерминированность достаточное требование, но не необходимое. Объект-обертку(без состояния) над статическим методом Console.ReadLine() можно считать идентичным другому такому же объекту. S>Нет. Можно считать его эквивалентным. Идентичным считать его не получится — по определению идентичности. Идентичность позволяет всегда отличить объект от других объектов. Независимо от наличия или отсутствия состояния. И даже поведения.
Следствия идентичности в вики допускают наличие объектов с same identity.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали:
L>>Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить? S>Да, благодаря наличию identity. S>Пример привели по соседству. На самом деле не нужен даже специальный класс:
S>
S>var a = new object();
S>var b = new object();
S>var c = a;
S>Debug.Assert(a == c);
S>Debug.Assert(a != b);
S>
S>Одинаковость контракта обеспечивается тем, что все объекты — одного класса. S>Состояния у объектов нет. Проверить это утверждение можно следующим образом: S>1. состояние объекта в ООП определяется по его поведению. S>2. т.е. о различиях в состоянии объекта можно судить по различиям его реакции на различные сообщения
получается что a и b имеют различные состояния, что неверно. Но неверно это потому, что некоторые методы (Equals) заточены не на состояние, а на ссылку на объект.
S>3. Какие бы вызовы мы ни выполняли на объектах a и b, их результаты всегда будут оставаться одними и теми же.
a.Equals(b) != a.Equals(a)
S>Формально тут есть некоторая сложность, связанная с тем, что мы делаем всеобщее утверждение, которое невозможно доказать никаким количеством примеров. Неформально мы поступим наоборот — выполним акт веры, примем утверждение за истинное, и подождём опровержения .
Тремя строчками выше.
Но еще раз, это все потому, что реализация Equals имеет зависимость не от состояния объекта, а от ссылки на него, которую мы договорились не считать состоянием.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Они эквивалентны, но не идентичны. S>>Можешь это доказать? Строго, делая верифицируемые выкладки из определения. Только без догадок о том что физический адрес это атрибут объекта.
G>Да
G>
G>var a = "string";
G>var b = "string"
G>Debug.Assert((object)a != (object)b); //(1)
G>Debug.Assert(Object.Equals(a,b)); //(2)
G>
G>Очевидно что приведение типа не изменяет объект, таким образом a и b разные объекты (1), то есть не идентичны, но они эквивалентны (2)
Ты показал отличие ссылочной эквивалентности от эквивалентности, определенной для строки по умолчанию. К логической идентичности ни то ни другое не имеет отношения.
Давай так. Ты допускаешь существование понятия "логическая идентичность" или ты будешь все время игнорировать "логическая" и подразумевать при этом "физическую идентичность"? Если для тебя нет понятия логической идентичности, то мы просто обсуждаем разные понятия и наши доказательства ни к чему не приведут.
S>>Я не придумываю определения, я ими пользуюсь. G>В википедии определение откровенно слабое, неформальное. http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
По ссылке выше три формальных определения. Допускают ли они трактовку, в которой логическая эквивалентность имеет место? Если нет, почему бы там сразу не написано "один и тот же объект"?
S>>>>логическая идентичность и эквивалентность — это разные термины. G>>>Чем разные? S>>Обозначают разные вещи. G>Ну так приведи определения. Я не понимаю что ты имеешь ввиду под этими разными вещами.
Ссылку на определения идентичности я дал, отношение эквивалентности — вот
G>>>В данном случае Object.ReferenceEquals(a,b) == false и a.Equals(b) == false. Других формальных утверждений про данный код ты сделать не можешь. G>>>Ты ничего не доказал. S>>Я показал что эквивалентность и идентичность могут обозначать разные вещи. G>В данном случае ты показал два объекта, которые не эквивалентны и не идентичны.
Следует добавить в пример реализацию отношения эквивалентности? Я могу это сделать. G>То есть ничего не доказал.
S>>>>Для строк доказать их логическую неидентичность невозможно. G>>>Я не понимаю уже что такое логическая идентичность. Как она в языке выражается? S>>Никак G>То есть его просто нет, его нельзя на доказать\ни опровергнуть\и выразить в программе.
Опровергнуть можно, я показал как. Доказать — нельзя. Так же нельзя доказать логическую идентичность объекта самому себе.
G>>>Для любого другого языка с возможность переопределить equals можно найти подобные правила. S>>Эти правила требуют формального соответствия вводимому отношению эквивалентности математическому понятию отношения эквивалентности, т.к. фреймворк в своей работе полагается на свойства отношения эквивалентности (рефлексивность, транзитивности, симметричность + кое-что из floating-point специфики). Рефлексивность требует что бы объект был эквивалентен самому себе. Но ни слова об идентичности. G>Выделенное есть идентичность.
Физическая но не логическая. Перестань игнорировать термины, описание которых я приводил неоднократно. Или мы обсуждаем одну и ту же вещь, либо не обсуждаем вовсе за бессмысленностью.
G>"Эквивалентен самому себе" формально записывается как Object.ReferenceEquals(a, b) == true => a.Equals(b)
Object.ReferenceEquals(a,b) не факт что выполняется для логической идентичности. G>Ты только что упоминул то что я тебе уже раз 10 написал.
Мы говорим не об одном и том же.
G>Прочитай, там явное требование чтобы x.Equals(x) == true, но внутри Equals у тебя две ссылки this и obj. И единственная реализация данного требования делать Object.ReferenceEquals(this, obj), то есть опираться на совпадение ссылок. Причем такое можно найти и для java.
x.Equals(x) — требование рефлексивности. Оно будет удовлетворено и для логической идентичности. Я забыл, о что мы доказывали.
S>>Докажи что логически не идентичны. G>Я не знаю что такое "логически идентичны", ты не привел определение.
Определения идентичности я приводил. Нужно еще формально показать что из него вытекает лишь физическая идентичность и никак не логическая. Покуда это не сделано строго и формально, я считаю что понятие логической идентичности вытекает из определения идентичности. Описание того, что такое логическая идентичность я приводил.
допустим
"object identity — identity is that property of an object that distinguishes each object from all others" [Khos-86]
Откуда тут следует что под that property подразумевается физическая уникальность экземпляра? Для меня это не очевидно. А значит могут существовать другие свойства объекта. Наблюдаемое поведение объекта — вполне одно из таких свойств.
Если ты отбрасываешь понятие логической идентичности потому как не видишь, как оно может вытечь из определения идентичности, давай на этом закончим. Ну или по крайней мере приостановим доказательства друг-другу своих утверждений до тех пор, пока не разберемся с определением идентичности и не найдем общее понимание его.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Ты показал отличие ссылочной эквивалентности от эквивалентности, определенной для строки по умолчанию. G>То что ты называешь ссылочной эквивалентностью является по идентичностью.
Тебе недостаточно различных определений, ты продолжаешь настаивать, но не приводишь ссылки на то что это одно и то же.
S>>К логической идентичности ни то ни другое не имеет отношения. G>К логической идентичности ничего не имеет отношения как так ты её выразить не можешь, ни словами ни кодом, ни доказать её отсутствие или присутствие.
Словами: идентичность — это такое свойство объекта, которое позволяет отличать его от остальных.
Опровергнуть идентичность можно следующими способами — сравнить поведение объектов. Если изменение состояния одного объекта не приводит к изменению состояния другого — объекты не идентичны. Если такие отличия не могут быть найдены, то это свидетельствует об идентичности, но быть уверенным что они идентичны нельзя.
Ссылка на объект не является атрибутом объекта и не может быть наблюдаема через его поведение концептуально, а не в С#.
Описать кодом?
S>>Давай так. Ты допускаешь существование понятия "логическая идентичность" или ты будешь все время игнорировать "логическая" и подразумевать при этом "физическую идентичность"? Если для тебя нет понятия логической идентичности, то мы просто обсуждаем разные понятия и наши доказательства ни к чему не приведут. G>Я вообще будут игнорировать твои понятия пока ты им не приведешь формальные определения. То есть чтобы можно было написать код, который это проверит для любых объектов.
S>>По ссылке выше три формальных определения. Допускают ли они трактовку, в которой логическая эквивалентность имеет место? Если нет, почему бы там сразу не написано "один и тот же объект"? G>Потому что "один и тот же" можно сказать когда есть два объекта. А тут попытались написать определение identity для одного.
Дай определение идентичности, которому ты доверяешь.
S>>Ссылку на определения идентичности я дал, отношение эквивалентности — вот G>Да нет, меня как раз интересует твое понимание идентичности.
Выше
S>>Следует добавить в пример реализацию отношения эквивалентности? Я могу это сделать. G>Ну, ты сделаешь два экивалентных, но не идентичных объекта.
Ты можешь показать их неидентичность не используя сравнение ссылок? ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта?
S>>Опровергнуть можно, я показал как. G>Ты ничего не показал. Покажи как свойство "логической идентичности" можно выразить в программе.
Существование отличий в поведении дает логическую неидентичность. Показать тебе все способы нахождения отличий?
S>>Физическая но не логическая. Перестань игнорировать термины, описание которых я приводил неоднократно. Или мы обсуждаем одну и ту же вещь, либо не обсуждаем вовсе за бессмысленностью. G>Чем физическая отличается от логической, приведи код. Рассуждения без кода не нужны.
Логическая определяется через поведение объекта, а не через ссылку. Проверять всевозможное поведение объекта слишком муторно для форума.
S>>Мы говорим не об одном и том же. G>Возможно. Ты придумываешь вещи, которые отсутствуют.
Их не я придумал. Есть несколько источников, где эти вещи описаны. Отрицай существование этих источников.
S>>x.Equals(x) — требование рефлексивности. Оно будет удовлетворено и для логической идентичности. Я забыл, о что мы доказывали. G>Object.ReferenceEquals(this, obj) это какая идентичность? После этого сразу напиши код для получения другой идентичности.
Это ссылочная эквивалентность а не идентичность. Из нее следует физическая идентичность. Из физической идентичности следует ссылочная эквивалентность. Но это не одно и то же. Понятия разные, но наблюдаются они у объекта одновременно. Смотри определения.
S>>Определения идентичности я приводил. G>Формально, код давай. Без кода это пустой треп.
Если для тебя это треп, то давай завязывать. Я тебе уже устал повторять, что доказать идентичность даже объекта самому себе кодом невозможно. Формально определение идентичности ссылается на свойства, которые позволяют отличать объекты друг от друга.
Возьми var a = "a"; var b = a; и докажи кодом что у a и b нет свойств, которые бы их отличали.
Потом требуй от меня код.
S>>Нужно еще формально показать что из него вытекает лишь физическая идентичность и никак не логическая. Покуда это не сделано строго и формально, я считаю что понятие логической идентичности вытекает из определения идентичности. Описание того, что такое логическая идентичность я приводил. G>В чем отличия физической и логической идентичности? Кодом.
Докажи идентичность объекта самому себе кодом, что бы сошлось с определением.
S>>Откуда тут следует что под that property подразумевается физическая уникальность экземпляра? Для меня это не очевидно. А значит могут существовать другие свойства объекта. Наблюдаемое поведение объекта — вполне одно из таких свойств. G>Концептуально — ниоткуда, а в контретной реализации ООП — очень даже понятно откуда. Других реализаций ООП не видел.
Это не значит, что других реализаций не может быть.
S>>Если ты отбрасываешь понятие логической идентичности потому как не видишь, как оно может вытечь из определения идентичности, давай на этом закончим. Ну или по крайней мере приостановим доказательства друг-другу своих утверждений до тех пор, пока не разберемся с определением идентичности и не найдем общее понимание его.
G>Я его отбрасываю потому что оно неформализуемо.
Оно формализуемо. Неформализуемо следствие по которому существует лишь физическая идентичность.
G>Вообще странно ты пытаешься поступить. Есть вполне формальное определение identity — отличить объект от всех остальных, для этого в C# например еcть Object.ReferenceEquals, который как-бы говорит нам о сравнении ссылок.
ReferenceEquals для сравнения ссылок, он не определяет идентичность формально. В нескольких источниках написано что неравенство ссылок не приводит к различным идентичностям. Оспаривай эти источники.
G> Ты придумываешь какое-то определение, которое неформализуемо и непредставимо в языке и разводишь на основании этого демагогию.
Я пользуюсь формальным определением. То что из него следует лишь физическая идентичность — не факт для меня. И еще раз — мопед не мой. Я указал как минимум 3 источника. Почему ты обвиняешь в придумывании и демагогии именно меня?
Скажи что все мои источники нагло врут, либо я их неверно понимаю. На этом закончим.
Здравствуйте, samius, Вы писали: S>Словами: идентичность — это такое свойство объекта, которое позволяет отличать его от остальных.
Это правильно. S>Опровергнуть идентичность можно следующими способами — сравнить поведение объектов. Если изменение состояния одного объекта не приводит к изменению состояния другого — объекты не идентичны. Если такие отличия не могут быть найдены, то это свидетельствует об идентичности, но быть уверенным что они идентичны нельзя.
Это — нет. Вы берёте базовое свойство ООП-модели и начинаете выражать его через другие два свойства, которые на самом деле от него зависят.
Вы почти всё понимаете правильно, кроме одного: идентичность обеспечивается в ООП независимым от поведения и состояния способом.
Всё. Точка.
Способов реализации этой идентичности — масса.
В системах с persistent storage в качестве identity используют OID — явный идентификатор, присущий любому объекту.
По OID всегда можно понять, идёт ли речь об одном и том же объекте, или нет, безо всяких апелляций к его поведению (которое может быть сейчас вообще недоступно, если объект offline).
В системах с flat моделью памяти и неперемещаемыми объектами в качестве identity можно использовать адрес объекта.
В системах типа COM для обеспечения идентичности приходится делать специальные приседания — QueryInterface для IUnknown.
Ссылочную эквивалентность можно использовать для идентичности в том случае, если соблюдаются определённые требования к ссылкам. В частности, в Java и .Net эти требования соблюдаются. В COM — нет.
Вообще, в целом, ссылка отличается от identity тем, что ссылку можно гарантированно разрешить, то есть выполнить dereference.
Identity нам такой возможности давать не обязана.
Из определения ссылки следует, что из ссылочной эквивалентности следует идентичность — ссылка однозначно определяет объект.
То есть у двух разных объектов гарантированно разные ссылки.
S>Ты можешь показать их неидентичность не используя сравнение ссылок? ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта?
Если хочется экспериментов с идентичностью в .Net, можно невиртуально вызвать object.GetHashCode() на двух "одинаковых" строках. Его реализация как раз возвращает различные int-ы для различных объектов
Но в целом, рекомендую перестать спорить с очевидным. В .Net идентичность через ссылочную эквивалентность принята по определению. Она лучше, чем предлагаемая "логическая идентичность" (которую в .Net называют просто "эквивалентностью") потому, что работает для всех объектов, а не только для immutable.
S>Существование отличий в поведении дает логическую неидентичность. Показать тебе все способы нахождения отличий?
Неэквивалентность. S>Логическая определяется через поведение объекта, а не через ссылку. Проверять всевозможное поведение объекта слишком муторно для форума.
Предлагаю вместо новоизобретённого термина "логическая идентичность" использовать общепонятный "эквивалентность поведения". В отличие от "логической идентичности", любое определение которой будет оксюмороном, этот термин легко определить формально.
Два объекта будут поведенчески эквивалентны, если их реакция на любое сообщение будет одинаковой.
Через эквивалентность поведения выражается понятие состояния — два поведенчески эквивалентных объекта будут находиться в одном состоянии. Напомню, что напрямую наблюдать состояние объекта в ООП нельзя — это чёрный ящик.
Эквивалентность поведения нельзя использовать для идентичности — это отдельное отношение эквивалентности, и оно разбивает объекты на другие классы эквивалентности.
S>Их не я придумал. Есть несколько источников, где эти вещи описаны. Отрицай существование этих источников.
Пока что ни один источник приведён не был. Было приведено неправильное толкование статьи из википедии.
G>>Я его отбрасываю потому что оно неформализуемо. S>Оно формализуемо. Неформализуемо следствие по которому существует лишь физическая идентичность.
G>>Вообще странно ты пытаешься поступить. Есть вполне формальное определение identity — отличить объект от всех остальных, для этого в C# например еcть Object.ReferenceEquals, который как-бы говорит нам о сравнении ссылок. S>ReferenceEquals для сравнения ссылок, он не определяет идентичность формально. В нескольких источниках написано что неравенство ссылок не приводит к различным идентичностям. Оспаривай эти источники.
S>Скажи что все мои источники нагло врут, либо я их неверно понимаю. На этом закончим.
Неверно понимаете.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
A consequence of this situation is if two objects are identical, a change to one will always affect the other.
S>И? Я вижу здесь только подтверждение моим словам. Нет никаких упоминаний "логической идентичности" vs "физической идентичности".
Отвечу сначала на это, потому как это быстро.
class Monostate
{
static int a;
public int A { get { return a; } set { a = value; } }
}
var a = new Monostate();
var b = new Monostate();
a.A = 42;
Assert(42 == b.A);
Нет способа изменить лишь один из них. Они удовлетворяют процитированному. Т.е. согласно процитированному являются идентичными.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: S>>Identity — это такая функция ID: obj->(?), переводящая объект или ссылку в неизвестно что, что можно сравнить. S>>Нигде не написано что это неизвестно что (?) не может иметь связи с поведением. S>Написано. Но вам это читать неинтересно. Вы предпочитаете читать между строк и мелким шрифтом, напрочь игнорируя всё остальное.
Между строк читаю что ID не зависит от изменения состояний и поведения конкретного объекта. Но не вижу причин почему не отличать объекты по какой-то величине из области значений ID, которая имеет связь с поведением.
S>>Вот я и предлагаю использовать область значений, завязанную на наблюдаемое поведение. Что не так? S>Как что? S>1. Ваше предложение не вполне соответствует определению, которое требует от идентичности независимости от состояния и поведения. В частности, такое определение требует наличия идентичности даже у объектов без поведения совсем.
Без изменяемого поведения. Отсутствие изменяемого поведения — это тоже поведение. Не могу себе представить объект без поведения совсем. Ничего не делает — значит такое у него поведение.
S>2. Ваше предложение противоречит определению, которое требует от идентичности возможности различать разные объекты.
Оно позволяет различать объекты с разным поведением. S>Тем не менее, вы упорно приводите примеры, когда ваше определение идентичности приводит к неразличимости разных объектов.
Да, но разных объектов с неразличимым поведением.
Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно.
Необходимым является само наличие ссылок (или чего-то, выполняющее их функцию). Функцией ссылки является обеспечение возможности обращения (вызова метода, посылки сообщения и т.п.) к конкретному объекту.
Кроме того, нужна возможность разным ссылкам ссылаться на один и тот же объект. "Один и тот же объект" означает, что вызовы его методов и изменения его состояния через любую из ссылок, на него ссылающихся, абсолютно эквивалентны.
И эти гарантии должны обеспечиваться языком программирования.
Вот если выкинуть, например, из C++ указатели и ссылки, а любые "объекты" передавать по значению — ООП будет невозможен:
A a1 = ...;
a1.setValue(0);//1
a1.setValue(42);//2
A a2 = a1;
a2.setValue(13);
assert(a1.getValue() == a2.getValue());//упс
Хитрость еще в том, что даже тут идентификаторы a1 и a2, по сути, все еще являются ссылками. В строках //1 и //2 мы работаем все с тем же объектом. Только в языках с полным отсутствием изменяемого состояния возможно, чтобы идентификатор не был ссылкой.
Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
S>Здравствуйте, samius, Вы писали:
S>>Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором. S>Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки.
+1
S>>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет. S>Смешные упражнения. Ок, пусть у нас будет ООП-система, в которой ссылки сравнивать нельзя — из неравенства ссылок не следует ничего интересного. Отлично, чтобы отличать объекты друг от друга, мы запихаем внутрь каждого экземпляра GUID. S>0. Этот GUID будет волшебным образом генерироваться при всяком создании объекта, будь то "с нуля" или при клонировании объекта. S>1. Этот ID будет недоступен коду самого объекта; его будет невозможно изменить в течение всего времени жизни. S>2. Сделаем волшебную функцию ID(obj), которая будет залезать внутрь объекта и возвращать его GUID. S>3. Объект никак не сможет повлиять на реализацию этой функции. S>Введённая нами функция ID удовлетворяет определению идентичности: она одинаковая для одного и того же объекта; она разная для разных объектов в силу 0; она не зависит от состояния объекта в силу 1; она не зависит от поведения объекта в силу 3.
Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. Не зависимо от того, как реализовано клонирование\копирование — с назначением нового ID или использованием того же.
Исключением является, например, случай, если ID копируется, а объект хранит свое состояние где-то вовне и "копии" разделяют это состояние (например, Active Record, каждый раз обращающийся к базе для получения\сохранения своего состояния с использованием ID в качестве ключа).
S>>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности. S>Не надо путать определение идентичности и реализацию идентичности. S>Применимость ссылок для идентичности в дотнете нетрудно доказать в два хода.
+1
А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
S>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL. S>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает.
Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности.
S>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений.
Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны.
Операции сравнения, как элемента языка, не требуется.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, Sinclair, Вы писали:
S>>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
ANS>Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
Ага, фаулер говорит что anemic — не ООП, и все сразу верят.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
ANS>>>>>Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
G>>>>Ага, фаулер говорит что anemic — не ООП, и все сразу верят.
ANS>>>Ну, я как бы, думал, что ты что-то своё под этим понимаешь. Я тут у многих заметил склонность к изобретению своих трактовок терминов и их ниспровержению. То примитивный мапер лёгким ОРМ обзовут, то еще что. Даже ссылку дал, дабы прояснить горизонты. И любому здравомыслящему человеку сразу видно, что описанное по ссылке не ОО-подход
G>>Там написано что это не ОО-подход, но доказательств этому нету. Более того по формальным признакам anemic не менее ОО, чем rich.
ANS>По теории код отдельно от данных это не ОО.
По какой теории?
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>По какой теории?
ANS>Названия не помню
Нет такой теории.
Фаулер опирается на заблуждение
....basic idea of object-oriented design; which is to combine data and process together
Object-oriented Analysis and Design (OOAD) был придуман сильно позже ООП, примерно середина 90-годов и популяризирован двумя людьми — Бертраном Мейером и Гради Бучем. Только у них появилась мысль что объекты — данные+методы, причем обязательно вместе.
К сожалению в это время не было другой литературы по ОО-проектированию и все дружно на слово поверили мейеру и бучу. Это даже при том что примерно в это время появилась книга Design Pattern банды четырех, но там описывается решение конкретных проблем, а не подход к проектированию.
Через 5-7 лет Фаулер и Эванс выпустили свои книги, принеся в мир ООП еще одну волну булшита. Например до смешного популяризировали паттерн Repository, который при наличии мощных ORM почти не нужен.
Еще через 5 лет их поддержал Грег Янг со своим абсолютизированием DDD и выдумыванием CQRS.
Причем это очень далеко ушло от первоначальных идей ООП и преимуществ, которые они давали.
Из всего этого можно понять что исторически все "теории", которым верят миллионы, продвигаются очень ограниченной группой людей. При этом большинство теорий плохо или вообще никак не формализованы.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Тривиальные вычисления, которые всегда дают одинаковый результат на любых входных данных, можно исключить из рассмотретрения, заменив их константами. G>>>Проделав это простое преобразование у тебя функция не опирается на фазы луны. S>>Это будет другая функция. Равная, но другая, потому как будет задана другим правилом. G>Тем не менее её можно использовать в рассуждениях вместо оригинальной. G>А вообще, что ты хочешь доказать?
Я хочу тебе доказать что опираться и зависеть — это не одно и то же. Тем более, я смутно понимаю, что такое опираться в отношении функций.
S>>И что, тебе не надо доказывать ее существование кодом на C#? Почему к моей функции у тебя другое отношение? G>Я же говорю, я могу написать функцию дирихле на C# или любом другом языке, но она всегда будет возвращать 1, так как нет в компьютере иррациональных чисел. Поэтому полезность её равна нулю.
Это будет не функция Дирихле, потому как ты не сможешь никого убедить что она вернет 0 для иррациональных чисел. Даже форма ее записи будет отличаться от функции Дирихле.
G>Ты же не можешь написать на C# функцию id(object), которая id(a)==id(b) только когда a и b — один объект, при этом функция не должна зависеть от состояния и поведения и при этом она не будет совпадать с object.ReferenceEquals.
Моя функция id не будет иметь отношения к ReferenceEquals и она не обязана будет возвращать те же результаты. Она будет удовлетворять определению identity OOP, а не ECMA-335.
G>>>>>Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет S>>Это не аксиомы, это определение идентичности OOP. G>В нашем случае аксимоы, так как они даны и их не нужно доказывать.
Дано определение идентичности.
S>>Для меня не то же самое. Покажи определение одинаковых объектов, а то твоя версия пункта 2 опирается на него.. G>Одинаковый — один и тот же, я даже специально same написал по английски в скобках чтобы ты понимал о чем речь.
Same объекты это те, для которы ID(obj) совпадает. У тебя это понятие относительно ООП по-другому выглядит?
Ты же мне говоришь что ID опирается на понятие разных объектов. Да, я про identity OOP, но не ECMA-335 identity.
G>>>Она есть, но на компьютере её выразить нельзя так как иррациональных числе нет. G>>>То есть функция дирихле всегда будет возвращать 1. S>>Окей, т.е. на С# она невыразима? G>Выразима, но толку мало.
Невыразима на компьютере, но выразима на C#
S>>Почему ты требуешь от меня выразить другую функцию, существование которой оспариваешь? G>То что ты пытаешься сделать — даже записать не получится.
Как и Дирихле на C#.
S>>ссылка в дотнете есть ECMA identity по определению ECMA-335. Это верно? G>Да
S>>Определение identity в ECMA-335 не является переформулировкой identity OOP. Это не одно и то же. Согласен? G>Согласен, оно является реализацией.
S>>Identity в ECMA-335 — это двоичное отношение, основанное на memory location. Так? G>Да, см (1) ниже
G>
G>8.2.5.1 Identity
G>...
G>• Otherwise, if their exact type is a reference type, then they are identical if and only if the
G>locations of the values are the same. (1)
G>Identity is implemented on System.Object via the ReferenceEquals method. (2)
Интересно, что нет функции id, но определено отношение на ReferenceEquals. Может быть и мне не нужно будет создавать функцию my_id, а достаточно будет определить отношение MyIdentityEquals? Думаю, да.
G>Я так не утверждаю, более того, я говорил что в других системах есть и другие способы. G>Ты же утвреждал
что в C# возможно identity без совпадения ссылок, хотя стандарт говорит обратное (см (2) выше).
Окей. Но это ведь ECMA, а не OOP. Я утверждал что существует другое identity, которое не совпадает с identity на memory location. Потому я не собираюсь доказывать какое-либо отношение того identity к ReferenceEquals.
G>
S>>>ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity).
G>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю.
G>Для C# две строки с одинаковым содержимым.
Все верно. Я говорил об идентичности OOP. Но ты об идентичности ECMA-335.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
A>>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы?
G>Например когда мы хотим поместить в коллекцию объекты класса, который не имеет equals и написан не нами. G>Как объекты такого класса будут сравниваться? Ты же понимаешь что equals переопределяет очень малый процент классов
Например, назначать коллекции стратегию сравнивания. А вообще, вопрос был не в том, с какими проблемами мы можем столкнуться в текущем проекте, если с завтрашнего дня внезапно появится запрет на вызов ReferenceEquals и всего, что его использует. Вопрос в том, можно ли будет писать объектно ориентированные программы после этого; т.е. возможна ли ситуация, что для реализации какого-то функционала (напр. требуемого заказчиком) будет невозможно не выйти за рамки ООП, хотя с наличием ReferenceEquals оно еще будет возможно?
A>>Ок, берем код ExposedObject, меняем там BindingFlags.NonPublic на BindingFlags.FlattenHierarchy, переопределяем методы из Equals, GetHashCode, ToString и создаем GetType. Делегируем все в агрегируемый объект. A>>
G>Ты привел пример эквивалентных, но не идентичных объектов. G>Мог бы не напрягаться, а взять две строки.
G>>>Тебе нужен пример где два объекта идентичны, то есть это один объект по сути. Но ссылки на него не равны. A>>Ссылки ссылаются на идентичные объекты, если они взаимозаменыемы с сохранением поведения программы. G>Бред. Смотри определения: G>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
Хорошая ссылка. G>Читай ECMA-335
.NET — это единственная возможная реализация ООП?
G>
G>8.2.5.1 Identity
G>The identity operator is defined by the CTS as follows.
G>• If the values have different exact types, then they are not identical.
G>• Otherwise, if their exact type is a value type, then they are identical if and only if the bit
G>sequences of the values are the same, bit by bit.
G>• Otherwise, if their exact type is a reference type, then they are identical if and only if the
G>locations of the values are the same.
G>Identity is implemented on System.Object via the ReferenceEquals method.
Определение через locations — слишком узко.
G>То что ты приводишь называется эквивалентностью
Так в примере не только ж Equals работает.
A>>Ок, другой пример: A>>
A>>class Something
A>>{
A>> private readonly ID id;
A>> public Something()
A>> {
A>> id = ID.GetUniqueId();
A>> //INSERT INTO table (ID, State) VALUES ($id, 0)
A>> }
A>> private Something(ID id)
A>> {
A>> this.id = id;
A>> }
A>> public static IEnumerable<Something> GetAll()
A>> {
A>> foreach(id in//SELECT ID FROM table)
A>> yield return new Something(id)
A>> }
A>> public int State
A>> {
A>> get { //SELECT State FROM table WHERE ID = $id }
A>> set { //UPDATE table SET State=$value WHERE ID = $id }
A>> }
A>>}
A>>
A>>Разжевать? G>Это ты чего понаписал? И зачем?
Если два объекта типа Something имеют одинаковый id, то они идентичны, независимо от того, что вернет object.ReferenceEquals.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Это противоречит определению так как ты на состояние будешь ориентироваться. S>>Определение не запрещает ориентироваться. Оно запрещает id изменяться вместе с состоянием объекта.
G>Ну так оно у тебя будет меняться. Даже readonly можно поменять с помощью рефлексии, все еще оставаясь в рамках CLR.
Но не в рамках OOP
G>>>Это получится как раз определение эквивалентности, но не идентичности. S>>И эквивалентности и идентичности. G>Нет, не идентичности.
Я читаю определени идентичности так: независит от состояния == сохраняется при изменении состояния.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>Это противоречит определению так как ты на состояние будешь ориентироваться. S>>>>Определение не запрещает ориентироваться. Оно запрещает id изменяться вместе с состоянием объекта.
G>>>Ну так оно у тебя будет меняться. Даже readonly можно поменять с помощью рефлексии, все еще оставаясь в рамках CLR. S>>Но не в рамках OOP G>Причем тут ООП? В ООП есть неизменяемые поля? readonly — не более чем особенность компилятора.
readonly непричем. Причем тут то, что рефлексия позволяет обходить инкапсуляцию данных. Это не ООП инструмент.
S>>Я читаю определени идентичности так: независит от состояния == сохраняется при изменении состояния. G>Да, причем при любом изменении, доступном в рамках системы. Конкретно в рамках СLR.
Конкретно в рамках CLR идентичность при изменении состояния не сохраняется у value типов. Не нужен даже рефлекшн
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>Коллекция тоже не тобой написана. Счиатй что у тебя изначально нет возможности переопределит операцию сравнения. Как будет выполняться операция Collection.Remove(item) S>>>>По назначенному компареру G>>>Еще раз: нет возможности переопределить операцию сравнения никак, ни компарер, ни equals, вообще никак. S>>Остается задвинуть на эту досадную коллекцию. Никто не обещал совместимость альтернативной идентичности со всем написанным кодом. G>Тем не менее коллекция есть, объект есть, сделай так чтобы Collectio.Remove(item) работало. Ведь в CLR оно работает. G>Будем считать что у тебя есть возможность сделать свою идентичность для CLR, как ты её определишь? Естественно ты тип item заранее не знаешь.
У меня не было намерений подменять идентичность в CLR. Но так и быть, если ты настаиваешь
Речи не было о том что бы взять совершенно другую идентичность. Я хотел взять немного другую идентичность, которая для некоторых хороших типов, была бы слабже чем штатная. Для всех остальных — ReferenceEquals. Соответственно, для любого наперед неизвестного типа это было бы сравнение ссылок. Для хороших типов типа строк — сравнение значений.
Собственно вот я все и выложил. Осталось ввернуть пару строк псевдокода:
bool MyIdentityEquals(object a, object b)
{
if (ReferenceEquals(a,b))
return true; // ослабить а не изменить в корнеif (a == null || b == null)
return false; // не знаю что определено в штатном порядке, пусть будет так.var type = a.GetType();
if (type != b.GetType())
return false;
if (type == typeof(string) && StringComparer.Ordinal.Equals((string)a, (string)b))
return true;
// тут обработка хороших типов.if (IsImmutable(type) && IsStructuralEquals(a, b))
return true;
return false;
}
Если это подсунуть вместо штатной ReferenceEquals и забыть про Reflection, который не ООП, то мы останемся в рамках ООП и даже возможно обеспечим некоторую совместимость с ReferenceEquals.
Да, будет тормозно. Но меня волнует лишь совместимость с ООП. Я уже говорил, что не собираюсь предлагать внедрять это в производство.
G>>>То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок? S>>Я не собирался определять идентичность в CLR. Я собирался показать отношение, удовлетворяющее идентичности ООП и отличное от идентичности ECMA-335. Из CLR ты можешь на него смотреть как на еще одно отношение эквивалентности. G>Оно должно быть отношением идентичности в CLR или другой системе, которую ты придумаешь. При этом не должно существовать функции f, позволяющей свести твое отношение идентичности к сравнению "ссылок". G>Такой пример уже есть. COM — формально ООП, для идентичных объектов могут ссылки не совпадать, но при QureyInterface(IUnknown) совпадают.
Только не говори, что QueryInterface не использует состояние
S>>Но вот, незадача, еще один фронт открылся — рефлексионный... G>Никаких фронтов. Сравнение неизменяемого состояния опирается как на само состояние (значения), так и на поведение (неизменяемость). Такая эквивалентность вдвойне неправильна а CLR позволяет быстро это доказать.
COM
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Речи не было о том что бы взять совершенно другую идентичность. Я хотел взять немного другую идентичность, которая для некоторых хороших типов, была бы слабже чем штатная. Для всех остальных — ReferenceEquals. Соответственно, для любого наперед неизвестного типа это было бы сравнение ссылок. Для хороших типов типа строк — сравнение значений. G>"Для некоторых хороших типов" — зависит от поведения.
Как и у QueryInterface
S>>Собственно вот я все и выложил. Осталось ввернуть пару строк псевдокода: S>>
S>>bool MyIdentityEquals(object a, object b)
S>>{
S>> if (ReferenceEquals(a,b))
S>> return true; // ослабить а не изменить в корне
S>> if (a == null || b == null)
S>> return false; // не знаю что определено в штатном порядке, пусть будет так.
S>> var type = a.GetType();
S>> if (type != b.GetType())
S>> return false;
S>> if (type == typeof(string) && StringComparer.Ordinal.Equals((string)a, (string)b))
S>> return true;
S>> // тут обработка хороших типов.
S>> if (IsImmutable(type) && IsStructuralEquals(a, b))
S>> return true;
S>> return false;
S>>}
S>>
G>1)Ты явно используешь поведение, когда сравниваешь строки.
Не беда G>2)Ты явно используешь состояние при сравнении. reflection испортит тебе идентичность
Рефлекшн к черту G>3)Есть подозрение что immutable выходит за рамки ООП
У меня нет. G>И кстати, как ты IsStructuralEquals определишь?
Как-нибудь, в этом нет магии.
G>
G>[Immutable]
G>class A
G>{
G> public B B { get; }
G>}
G>class B //не-immutable
G>{
G> public int Prop {get; set;}
G>}
G>var a = new A { B = new B { Prop = 1 } };
G>var b = new A { B = new B { Prop = 1 } };
G>Debug.Assert(MyIdentityEquals(a,b)); //Упадет?
G>b.B.Prop = 1;
G>Debug.Assert(MyIdentityEquals(a,b)); //А тут?
G>
Функция не настолько тупа что бы верить атрибуту [Immutable]. Возможно она шуршит по IL коду.
S>>Если это подсунуть вместо штатной ReferenceEquals и забыть про Reflection, который не ООП, то мы останемся в рамках ООП и даже возможно обеспечим некоторую совместимость с ReferenceEquals. G>А почему reflection не ООП? Например в самом ООП языке — smalltalk есть рефлексия. И свовйство что изменения в одном объекте сразу отражаются на другом, если объекты идентичны, тоже не говорит какие изменения. Значит в том числе refection.
Я уже писал, что рефлексия в дотнете ломает инкапсуляцию данных. G>А вот кстати использование только immutable объектов в программе скорее всего выходит за рамки ООП.
Тогда, скорее всего, любая программа, использующая иммутабельную строку, выходит за рамки ООП
S>>Только не говори, что QueryInterface не использует состояние G>Ты удивишься, но не использует. Это также явно в спецификации прописано. QueryInterface для объекта должна быть детерминированной функцией, то есть зависеть только от параметров.
Не поверишь, функция, сравнивающая две строки, тоже может быть детерминированной, т.е. зависеть только от параметров. По твоей же логике детерминированная функция не использует состояние. Значит сравнивать строки можно не используя состояние.
Наверное тогда можно сравнивать все объекты с детерминированными функциями (иммутабельные) не опираясь на состояние
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>Что значит "фактический объект"? Как ты понимаешь "Объект" в данном случае?
ANS>Не не не. Это мы уже проходили
. ANS>Ты всё сводишь к техническому моменту. Данные лежат в массиве? В массиве? Массив — это объект? Объект. Значит есть ОО. А потом приходят функциональщики и говорят "а зачем это всё?
Если смотреть на массив с точки зрения C\ассемблера, то массив — указатель непрерывный кусок памяти, то есть число. Число объектом не является (даже несмотря на SmallTalk), так как не обладает identity.
Если же мы возьмем язык программирования и создадим класс "массив", которому мы можем отправлять сообщения типа "верни элемент с индексом i", вот только массив этот может быть внутри и хеш-таблицой, и односвязным списком, и непрерывным блоком памяти. То есть некоторый "список" (упорядоченное множество) элементов.
С точки зрения низкого уровня массив не имеет identity, а с точки зрения высокого массив — деталь реализации "списка"
Если же подойти с философской точки зрения, то везде в мире нас окружают объекты: люди, компьютеры, дома, меблель. Но для ООП объекты должны обладать некоторыми свойствами. Так вот не все объекты в реальной жизни этими свойствами обладают, да и в программах тоже.
Поэтому ООП — не там где есть объекты, а там где выполняются свойства ООП.
Так вот anemic по формальным свойствам не менее ООП, а учитывая SOLID — даже более ООП, чем рич.
Вот только 15 лет назад буч с мейером сказали что ООП это данные с методами, и придумали OOAD в виде моделирования задачи, а не решения. И все им верят.
ANS>Хотя ОО позволяет делать тот самый "рекурсивный" дизайн, когда объекты и в верху и в низу, ты оставляя объекты внизу системы отказываешься от них на верху.
Еще раз: по формальным признакам anemic — не менее ООП. Хотя в случае распределенной среды выгодно забивать на identity сервисов, но это сейчас не рассматриваем. Anemic использует другой подход к созданию классов и объектов, пытаясь моделировать не задачу, а решение.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Его не надо хранить. Ты заранее выбери один интерфейс, к которому будет приводиться. S>>Интерфейсы pXXX и pYYY лежат в разных местах. Нужна навигация между ними. Приведением навигацию не обеспечить. G>Да без разницы, нам только надо возвращать всегда одинаковую ссылку на QueryInterface(IUnknown), остальное не интересует.
Интересует как ты будешь это выполнять в общем случае без состояния.
G>>>
G>>>return (IUnknown*)this;
G>>>
S>>this указывает на грань, отличную от IID_IUnknown. Как быть? G>Пусть указывает, ведь каждый интерфейс является всегда IUnknown и при данной реализации всегда будет возвращать одно значение.
Это противоречит спецификации. Все интерфейсы/грани объекта должны возвращать всегда один и тот же указатель при запросе QI(IID_IUnknow). G>Или ты что-то другое имеешь ввиду?
Именно то что пишу.
G>>>Не все сценарии, но основные вполне, для которых COM создавался — вполне. Некоторые фичи com по-моему вообще в дикой природе не встретишь. S>>Так ты предлагаешь отказаться от сценариев, где требуется состояние для реализации QI для того что бы убедить меня в том, что разработчики спеки не подразумевали использование состояния в QI при вычислении identity? G>Нет, я лишь говорю что если ты придумываешь сложности — ты их и решай. Но принципиальных проблем обеспечить независимость от состояния QueryInterface(IUnknown) я не вижу.
Это не мои сложности и я не вижу, как выполнить QI в общем случае без того что бы вернуть значение, хранящееся в состояние.
G>>>Я предлагаю решение для сценария, который ты сам придумал. Ведь можно и другой сценарий придумать, который будет не менее рабочий, и не менее COM. S>>Сценарий multiple interface navigation придумал не я. Это довольно типичный сценарий в COM уровня чуть глубже букварного. В спеке он упоминается неоднократно, даже с примерами реализации. G>А пример такого в компонентах есть?
В каких именно компонентах?
Я думаю что такие примеры надо искать не в компонентах в SDK продуктов типа ESRI ArgGIS и т.п. Вместо того что бы в дотнете наследоваться от IPlugin, COM прелагает именно агрегацию для расширения объектов.
S>>Не без разницы. Я тебе указываю на те случаи, когда результат QI нужно хранить в состоянии грани. Ты их упорно игнорируешь. G>Если ты сделал такую реализацию что надо хранить, то ССЗБ. Не делай такую реализацию. Я же тебе говорил что можно почти все сделать через механизмы множественного наследования, которые уже давно работают в разных языках.
В Visual Basic тоже?
Нет, это если ты предлагаешь забить на агрегацию вопреки спеке COM, то ты ССЗБ.
Здравствуйте, Lloyd, Вы писали:
I>>Это слишком общая формулировка. Разве здесь сказано, что "все структуры данных должны иметь хотя бы один метод для работы с этими данными" ?
L>Конечно общая. ООП — это вообще довольно мутное понятие.
Ну что, господа, наставившие минусов, количество сообщений в теме еще не убедило вас в правоте отквоченной фразы?
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, samius, Вы писали:
P>хъ
S>>
S>>3.3 The IUnknown Interface
S>>This specification has already mentioned the IUnknown interface many times. It is the fun-
S>>damental interface in COM that contains basic operations of not only all objects, but all
S>>interfaces as well: reference counting and QueryInterface. All interfaces in COM are poly-
S>>morphic with IUnknown, that is, if you look at the first three functions in any interface you
S>>see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
S>>all other interfaces inherit.
P>Ну и? Тут как раз и говориться, про то, что от любого интерфейса можно вызвать методы IUnknown. P>Меня интересует P>
P>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта.
Из того что все интерфейсы полиморфны IUnknown, следует, что полученный pUnk2 является легальным указателем на IUnknown. Способ его получения легален, хоть и не гарантирует получения отличного указателя.
COM идентичность говорит только о том, что что бы понять, являются ли эти указатели указателями на интерфейсы одного объекта, необходимо вызвать у каждого QI(IID_IUknown) и сравнить результаты.
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, samius, Вы писали:
P>[]
S>>Где в правилах COM написано что нельзя приводить указатель на интерфейс к IUnknown* ? Можно цитату?
P>Я не знаток стандарта ком, так что цитату не дам. P>И хочу уточнить, если ты не заметил — я с вами (с тобой и Синклером) вообще говоря не спорю, просто хочу разобраться.
Хорошо, давай разбираться. Но я тоже не знаток стандарта. Я его и не видел пока в этом топике ссылка не появилась. При случае открываю и делаю поиск в спецификации.
P>Афаик, ком не может говорить ничего такого, поскольку он ничего не знает ни про какие приведения типов. "Приведение типов" там ровно одно — QI.
QI это способ навигации между интерфейсами объекта. А приведение указателя интерфейса к указателю на IUnknown основано на двоичном стандарте vtbl, который использует COM для вызова методов, который "is exactly what most C++ compilers generate on PC and many RISC platforms".
P>Вообще говоря, спор в этом топике крутился вокруг IUnknown & identity. Правильно ли я понимаю, что ведя речь про то, что комовская идентичность опирается на состояние объекта, имеется в виду агрегация и ссылка на внешний объект в агрегате?
Да, но я бы перефразировал следующим образом: в связи с тем, что в COM заложены реюз и расширение объекта с помощью агрегации, COM identity опирается на специальные свойства метода QI, которые потребованы стандартом. В случае навигации между multiple interfaces одного объекта, предполагается использовать внутреннее состояние, хранящееся в объектах (не COM), реализующих COM интерфейсы COM объекта. Точнее не предполагается, а я не вижу способа обеспечить навигацию между различными интерфейсами без использования состояния.
Здравствуйте, Patalog, Вы писали:
S>>Где в правилах COM написано что нельзя приводить указатель на интерфейс к IUnknown* ? Можно цитату?
P>Я не знаток стандарта ком, так что цитату не дам. P>И хочу уточнить, если ты не заметил — я с вами (с тобой и Синклером) вообще говоря не спорю, просто хочу разобраться.
Указатель на любой интерфейс это в т.ч. указатель на IUnknown. Но есть нюанс — идентити можно проверять только в том случае, если делаем явно QI на IUnknown.
P>Афаик, ком не может говорить ничего такого, поскольку он ничего не знает ни про какие приведения типов. "Приведение типов" там ровно одно — QI.
COM не знает про приведения типов. COM знает про интерфейсы. Про приведения типов знают языки, которые реализуют COM. В com есть два механизма расширения интерфейсов — containment/delegation и aggregation. Первый из них реализуется через наследование, а это самое наследование полностью укладывается в бинарный стандарт COM.
Т.е. если IWebBrowser2 описан в IDL как interface IWebBrowser2 : IWebBrowser то это значит, что в его VMT будут все методы IWebBrowser.
В языке C для VMT будет использован cfront а не thunk, т.е. даже здесь будет фактически приведение типов
Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд.
Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
Просто беру и делаю, стараясь делать качественно, насколько это возможно, не слишком увлекаясь.
Делать просто хорошо не намного дольше, чем делать кое-как.
Вот потом уже рано или поздно нужно будет остановиться, посмотреть на то, что получилось и устроить хороший еврорефакторинг. В вашем случае это когда-нибудь придется делать тому, кто будет поддерживать ваш продукт, иначе лопнет. Но с вашими короткими проектами эта проблема вашей не станет.
L>Задачу на неделю для фриланса?! Конечно быстрее.
Что именно — первое или второе? По поводу второго еще можно поспорить, а с первым-то как? Вы давно писали что-нибудь в не-ООП стиле? Мне пришлось бы заставлять писать себя так, и это было бы явно медленнее, не говоря уже об отладке и сопровождении.
Здравствуйте, licedey, Вы писали:
L>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость
смотря, что за задача. кстати, а чем класс от объекта отличается? и чем они вместе отличаются от модулей?
> не дает нужного результата в релизе. Скажите как вы делаете задание с нуля.
смотрю, какие сущности и какой функционал мне потребуется для решения. и начинаю реализовывать это отдельными модулями, максимально абстрагированными друг от друга, а потом свожу их воедино. но это _сильно_ зависит от задачи. создание "с нуля" подразумевет, что этого еще никто не делал (или делал, но недоделал) и потому сначала нужно провести ресерч. потом заточить прототип. вы сочинения в школе тоже начисто сразу писали? или нет? наверное черкали, резали, а потом выбрасывали, меняли местами и склеивали. так и в программировании. начисто с нуля ничего не делается.
> Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
зависит от того кому это поддерживать
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, Sorc17, Вы писали:
S>Здравствуйте, VladD2, Вы писали:
VD>>Чтобы такого не случалось нужно кроме ООП познать и другие парадигмы. Как минимум имеет смысл освоить ФП, МП/DSL.
S>Посоветуйте, что почитать, чтобы асилить этот МП/DSL? Желательно "для чайников", ибо раньше никогда не пробовал
Внутренние языки, специфичные для предметной области: здесь
Здравствуйте, Lloyd, Вы писали:
L>Более того, очень многими неглупыми людьми ставится под сомнение его полезность. Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
Почему это анемик процедурный ? Если смтореть про инкапсуляцию как у Скота Мейерса, то ООПшность это именно переход от рич к анемик.
Здравствуйте, Lloyd, Вы писали:
L>>>Более того, очень многими неглупыми людьми ставится под сомнение его полезность. Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
I>>Почему это анемик процедурный ?
L>Потому что имеем разнесение данных и способов работы с ними. Может "процедурный" и не самое удачное слово, но вот "ООП" уж тут точно ни в какие ворота.
ООП как раз никуда не девалось
I>>Если смтореть про инкапсуляцию как у Скота Мейерса, то ООПшность это именно переход от рич к анемик.
L>Я не знаю, какая инкапсуляция у Мейерса.
Здравствуйте, licedey, Вы писали:
L>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
ООП — это инструмент управления структурной сложностью. Если программа простая, с коротким циклом поддержки (пофиксил баги и забыл), то на красивый дизайн можно забить. Конечному пользователю все равно что внутри, заказчику тоже пока корявость кода не бьет ему по карману стоимостью поддержки и модификации.
Здравствуйте, мыщъх, Вы писали:
М>то это будет не ооп, а модульное программирование, потому что "сортировка" это не сущность. это действие
Сущность может быть и действием и ещё много чем. Есть в ООП такая штука, как различные типы классов (я в литературе встречал название "типы объектов", но мне оно кажется не правильным). Какие-то классы описывают предметы, другие — действия, ... Их там 4 типа, оп-моему. Надо спросить у хорошо подкованных в теории ООП, они должны знать
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
L>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
Критерий простой — если программа будет в дальнейшем модифицироваться (изменение и уточнение требований в будущем, либо банальная инкрементальная разработка), то без нормальной архитектуры и хороших тестов это сделать будет невозможно.
Здравствуйте, Ikemefula, Вы писали:
L>>Да, именно. Стало более в ОО-духе.
I>Разница всего лишь в количестве сущностей которыми моделируется решение задачи. Т.е. разница в детализации.
Нет. Просто прочитайте определение и примерьте к своему примеру, все встанет на свои места.
Здравствуйте, Lloyd, Вы писали:
I>>Разница всего лишь в количестве сущностей которыми моделируется решение задачи. Т.е. разница в детализации.
L>Нет. Просто прочитайте определение и примерьте к своему примеру, все встанет на свои места.
Здравствуйте, Lloyd, Вы писали:
L>>>Нет. Просто прочитайте определение и примерьте к своему примеру, все встанет на свои места.
I>>А не мог бы ты показать, что не так ?
L>Нет, не мог бы. Определение я привел, теперь все в ваших силах. Дерзайте.
Оба примера полностью подходят под определение ООП
Здравствуйте, Ikemefula, Вы писали:
L>>Нет, не мог бы. Определение я привел, теперь все в ваших силах. Дерзайте.
I>Оба примера полностью подходят под определение ООП
Здравствуйте, Sorc17, Вы писали:
VD>>Чтобы такого не случалось нужно кроме ООП познать и другие парадигмы. Как минимум имеет смысл освоить ФП, МП/DSL.
S>Посоветуйте, что почитать, чтобы асилить этот МП/DSL? Желательно "для чайников", ибо раньше никогда не пробовал
Из теоретических писаний, пожалуй, Мартин Фаулер.
А так тема очень широкая, так как методы метапрограммирования и DSL-естроения очень разнообразны. От строковой конкатинации и T4, до Nemerle и Lisp.
Ну, и как и все темы в нашей области, эту нужно осваивать не в теории, а на практике.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, Lloyd, Вы писали:
L>>Здравствуйте, abibok, Вы писали:
L>>>>Задачу на неделю для фриланса?! Конечно быстрее.
A>>>Что именно — первое или второе? По поводу второго еще можно поспорить, а с первым-то как? Вы давно писали что-нибудь в не-ООП стиле? Мне пришлось бы заставлять писать себя так, и это было бы явно медленнее, не говоря уже об отладке и сопровождении.
L>>А вы уверены, что вы вообще хоть когда нибудь писали в ООП-стиле?
М>полностью поддерживаю. многие языки (не плюсы) имеют ооп чисто для галочки. и ведь живут. к тому же, если мы в плюсах создадим класс "сортировка" (с кучей разных алгосов сортировки), то это будет не ооп, а модульное программирование, потому что "сортировка" это не сущность. это действие, выполняемое над некоторыми сущностями (массивами, списками...). загнать разные методы сортировки в один класс можно, но что мы получим в результате? обыкновенный модуль, но не объект.
М>и потом, если взять два достаточно крупных проекта -- например, Spider Monkey (си) и Google V8 (плюсы), то в первом легко разобраться и с ходу начать дотачивать код под свои нужды. нужно прикрутить логгер -- берем и прикручиваем. а теперь смотрим на приплюснутый код. вообще-то он не совсем приплюснутый. он даже хуже. половина движка java script написана на спец-реализации самого java-script и взаимодействует с приплюснутым кодом очень нетривиальными путями. просто воткнуть fopen/fprintf не получается. и приходится в одном месте создавать новый интерфейс, а в другом месте его юзать. причем данные имеют жутко сложную структуру. итераторы всякие везде... да еще и с разными типами... хосподи. записать аргументы функции в файл -- это кошмар на улице вязов.
L>> Более того, очень многими неглупыми людьми ставится под сомнение его полезность. М>про все ооп не скажу, но вот никак не могу понять -- действительно ли язык программирования должен быть таким сложным, как плюсы? действительно ли у программиста должна болеть голова за виртуальные деструкторы? говорят, что плюсы обеспечивают высокую производительность. и где же она? куча программ на жабе не сильно уступает аналогичным программам на плюсах. хваленный сверхбыстрый движок гугла написан не только на плюсах, но и на жаба скрипте, причем там такие критические фрагменты кода, как, например, операции с массивами. вероятно, на этот шаг пошли по соображениям безопасности. чтобы память не текла и буфера нежиданно не переполнялись.
М>вот я и думаю -- а что мне дадут плюсы, если их выучить? питон мне дал высокую продуктивность и учить его не пришлось (так, полистал книжку на выходных), java script дала высокую портабельность (работает _везде_, включая мобилки и опять без затрат на обучение), чистый си дает производительность, но нам нем пишутся только самые низкоуровневые компоненты, а обвязка -- жаба, питон, руби или скала.
М>у плюсов же -- производительность только в теории, на практике оно тормозит и отжирает память (если, конечно, пользоваться приплюснутыми фичами на полную). программы сложно писать и еще сложнее понимать. с компиляторами и платформами сплошная чехарда. даже плагин для популярных программ обычно нужно писать на том компиляторе, которым собиралась сама программа.
Вы все правильно написало. Однако хотелось бы несколько пометок сделать. Язык не должен быть таким сложным как плюсы. Не при каком раскладе. Это что называется попал в нужное время в нужное место. ГУИ нужен, Сишного кода море, а вот тебе и абстрактность во всей ее красе. struct window {}; make_window_visible хуже ведь Class Window { void Show(); void Hide(); }; Для человека.
Тут как говорится, смешались люди кони. От меня требуют (ну впрочем я и сам привык), писать движок антивируса в ООП-стиле. Т.е. сканирование файла — класс. Загрузка сигнатур — класс. Настройки класс. Разновидности сканирование (память, реестр, мбр) — наследование абстрактного класса ScanTask. Вопрос Зачем? И почему наряду со знание базовых знаний (структуры данных, алгоритмы), знай шаблоны проектирования.
Есть же задачи (большинство их), где ООП замедляет процесс разработки. Иногда ломаешь голову, чтобы подогнать компоненты системы под иерархию наследования. Или вся эта виртуальность. Ну библиотечное это все течение. Я уже отписывал на хабре, что С++ для реализации задач и С++ для библиотек — это разные языки. Можно сказать, что первое — это повседневный язык студента, а второй преподавателя.
Я негодую....А еще этот ворох старья тянущейся с 70-ых годов...
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, licedey, Вы писали:
L>>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость М>смотря, что за задача. кстати, а чем класс от объекта отличается? и чем они вместе отличаются от модулей?
У меня любая задача так. Уж чему научился по книжкам ООП ин депс, тем и владею. От того и получается. Задача: напиши снифер 80-го протокола, чтобы уловить откуда видео идет. Я написал 3 класса: NetworkAdapterDetector, FlashSniffer, и TrackingURL. Ну думаю вы понимаете, что каждый из них делает. В тоже время, мой аппонент, Модифицировал существующий код. Ну я потратил на это все 30 часов. Он около 15-ти. Мой эстетичней, документированней и "разделяй и влавствуй". Его вроде бы как работает. Вот собственно предпосылка этого поста. Программировать на время, или на качество, с заделом на будущее. Под вопросом, нужно ли это заказчику.
>> не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. М>смотрю, какие сущности и какой функционал мне потребуется для решения. и начинаю реализовывать это отдельными модулями, максимально абстрагированными друг от друга, а потом свожу их воедино. но это _сильно_ зависит от задачи. создание "с нуля" подразумевет, что этого еще никто не делал (или делал, но недоделал) и потому сначала нужно провести ресерч. потом заточить прототип. вы сочинения в школе тоже начисто сразу писали? или нет? наверное черкали, резали, а потом выбрасывали, меняли местами и склеивали. так и в программировании. начисто с нуля ничего не делается.
Ну все равно, нажимаем же File->Add new item. потом уже дальше думаем. Мне больше с нуля нравится, когда за каждую строчку сам отвечаешь. И в случае чего, быстрей костыль подставлю.
>> Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри. М>зависит от того кому это поддерживать
Как правило, фриланс на том строится — вошел в доверие к заказчику — сам и сопровождай. А иначе, деньгу бери и бай бай.
Здравствуйте, licedey, Вы писали:
L>Здравствуйте, мыщъх, Вы писали:
М>>Здравствуйте, licedey, Вы писали:
L>У меня любая задача так. Уж чему научился по книжкам ООП ин депс, тем и владею. От того и получается. L>Задача: напиши снифер 80-го протокола, чтобы уловить откуда видео идет. L>Я написал 3 класса: NetworkAdapterDetector, FlashSniffer, и TrackingURL. L>Ну думаю вы понимаете, что каждый из них делает.
совершенно не представляю. нет такого протокола. нормальный сниффер (типа wireshark) сниффет все подряд. догадываюсь, что вам нужно сниффать TCP. догадываюсь, что это http. догадываюсь, что нужно парсить HTML. итого, мы имеем две _никак_ не связанные друг с другом задачи. первая -- просто сниффер. он уже есть. tcpdump в линухе. переводит карту в неразборчивый режим и ловит все, что адресовано ему и не ему. записывает резултать в pcap.
вторая задача -- распарсить pcap. сначала парсим, чтобы вытащить ethernet, из него ip, из него tcp, из него http. парсиг html в принципе это третья задача, т.к. парсеру html все равно подаем ли мы на вход html-файл, скаченный из сети или награбленный сниффером.
кстати, из ваших классов ни фига не понятно будет ли программа работать с уже готовыми pcap файлами или нет. так же непонятно почему flash выделена в отдельную сущность. там декопилтяор swf что ли?!
> В тоже время, мой аппонент, Модифицировал существующий код. > Ну я потратил на это все 30 часов. Он около 15-ти.
фигасе. с готовыми библеотеками (а их просто море) я написал экстрактор ссылк на полчаса (в которые вошел и поиск этих самых библиотек) и написание кода. у меня три отдельных модуля. сниффер (на входе трафик, на выходе pcap), экстрактор http трафика (на входе pcap, на выходе html) и декодер html, кстати, поддерживающий java script'ы и обсусцированные ссылки. на входе html на выходе -- список ссылок. причем, модули совершенно независимы и легко расширяемы.
> Мой эстетичней, документированней и "разделяй и влавствуй".
так у вас все в кучу. давайте еще раз разделять.
1) снифаем трафик;
2.1) парсим протоколы: Ethernet, IP, TCP
2.2) парсим HTTP (по хорошему это намного сложнее чем IP и TCP);
3.1) парсим HTML по тупому (считаем, что там нет скриптов)
3.2.1) выполняем java scrpt'ы и vbscipt на JS/VBS дивжках и грабим вывод;
3.3.2) эмулируем DOM (или берем готовый из браузера)
как-то так... если нужна детекция swf, то это отдельная задача. причем, я решил эту задачу в рамках процедурного подхода. приплюснотого кода там нет вообще. и это ни разу не ооп. но декомпозиция задачи выполнена вполне. собственно, говоря, парсер HTTP это отдельная задача, т.к. нужно поддержать кучу методов кодировая данных, кучу ответов сервера. понимать что такое POST и GET... но считаем, что парсер HTTP берется библиотечный, т.к. писать его самим это работы на 30 дней, а не часов
> Вот собственно предпосылка этого поста. Программировать на время, или на качество, > с заделом на будущее. Под вопросом, нужно ли это заказчику.
по вашей модели не ясно -- будет ли оно работать под никсами, например. сколько кода придется переписать. а что если это будет другой порт? а что если у нас прокси? а как на счет https траффика? а если нужно ловить не только HTML ссылки, но и составить "черынй" список доменных имен и IP адресов, относящийся ко всем протоколам? в приведенной мной модели все это делается без напряга. т.к. уровни четко разграничены и каждый уровень делает свою работу. а у вас?
L>Ну все равно, нажимаем же File->Add new item.
а если это vim?
> потом уже дальше думаем. Мне больше с нуля нравится, когда за каждую строчку > сам отвечаешь. И в случае чего, быстрей костыль подставлю.
мне тоже нравится отвечать за себя и больше ни за кого. но вот надо решить задачу и разбросать ее между несколькими сотрудниками, котрые в разных странах живут, часовые пояса совсем не перекрываются, да и пишут они на разных языках. правильная декомпозиция приводит к тому, что сотрудники вообще не будут знать друг о друге. в частности, парсер HTTP не зависет от парсера HTML, не говоря уже за сам сниффер.
на чем пишут люди -- мне все равно. хоть на си, хоть на плюсах, хоть на иврите. так что заканчивайте думать о строчках и думайте о задаче в целом, поскольку задача имеет множество решений:
1) сниффер, втыкаемый в ethernet и снифающий траффик;
2) сниффер на внешнем гейте;
3) http-proxy на гейте;
https можно сниффать только если или добавить на все компы свой сертификат или через https прокси. но в первом случае нужнен доступ ко всем компам и ноутам сотрудников, а во втором браузер будет ругаться на левый сертификат.
кстати, если уже пошел разговор за конкретные иженерные задачи -- на фига вам изобреть свой велосипед? есть же опен-соурсный Snort. на его базе можно замутить практически что угодно. и ничего парсить не надо. достаточно написать правило для ловли всех GET'ов (т.к. видео будет в них).
тут так же следует уточнить про какое видео мы говорим. если про то, которое льется по интернету -- то тут HTML вообще парсить не надо, а можно ограничится HTTP. если же нужно извлечь ссылки на видео еще до того как их начнут смотреть -- пишем парсер.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, Lloyd, Вы писали:
L>Потому что имеем разнесение данных и способов работы с ними.
Не всех данных, а только модели данных приложения. И причина не в плохом ООП, а в том простом факте, что модель данных меняется намного реже модели обработки этих данных.
... << RSDN@Home 1.2.0 alpha 5 rev. 1530 on Windows 7 6.1.7601.65536>>
Здравствуйте, AndrewVK, Вы писали:
L>>Потому что имеем разнесение данных и способов работы с ними.
AVK>Не всех данных, а только модели данных приложения. И причина не в плохом ООП, а в том простом факте, что модель данных меняется намного реже модели обработки этих данных.
Я никогда не понимал, что означает эта фраза.
От того, что мы замесим в один класс и хранимые поля, и методы работы с ними, что от этого модель данных начнет меняться чаще?
Или если мы делаем проект, про который мы гарантированно знаем, что модель данных не будет меняться, то что ООП начнет "блистать во всей красе"?
Я могу еще понять аппеляцию к SRP, но не эту же мутную фразу приводить в кач-ве аргумента.
По моему мнению, с "процедурным" подходом получается все как-то проще, чем в тру-риче. Уже за это стоит его любить.
Здравствуйте, Lloyd, Вы писали:
L> Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
Пример из насквозь оопшного DDD ты назвал неоопшным
Здравствуйте, Ikemefula, Вы писали:
L>> Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
I>Пример из насквозь оопшного DDD ты назвал неоопшным
Здравствуйте, Lloyd, Вы писали:
L>От того, что мы замесим в один класс и хранимые поля, и методы работы с ними, что от этого модель данных начнет меняться чаще?
Представь себе модель данных которая есть сеть == граф, который задан одним из известных способов. Модель примитивная до безобразия.
Теперь начинаем работать над этой сетью для достижения целей кастомера, т.е. выполнять его пожеления.Внезапно оказывается, модель для решения задач меняется постоянно, т.к. кастомер вечно хочет новые вещи, а модель данных прктически не меняется и так и остаётся графом, который задан известным способом.
И вот изредка, когда некоторые задачи требуют иное задание графа с целью получить более выгодную вычислительную сложность, приходится менять и модель данных.
Итого, в наличии две модели — модель данных и модель операций над моделью данных. И в каждой из моделей data structures будут разными. Всего то.
Здравствуйте, Ikemefula, Вы писали:
L>>От того, что мы замесим в один класс и хранимые поля, и методы работы с ними, что от этого модель данных начнет меняться чаще?
I>Представь себе модель данных которая есть сеть == граф, который задан одним из известных способов. Модель примитивная до безобразия. I>Теперь начинаем работать над этой сетью для достижения целей кастомера, т.е. выполнять его пожеления.Внезапно оказывается, модель для решения задач меняется постоянно, т.к. кастомер вечно хочет новые вещи, а модель данных прктически не меняется и так и остаётся графом, который задан известным способом. I>И вот изредка, когда некоторые задачи требуют иное задание графа с целью получить более выгодную вычислительную сложность, приходится менять и модель данных. I>Итого, в наличии две модели — модель данных и модель операций над моделью данных. И в каждой из моделей data structures будут разными. Всего то.
I>Собственно про это и говорится в DDD
Здравствуйте, Lloyd, Вы писали:
L>Или если мы делаем проект, про который мы гарантированно знаем, что модель данных не будет меняться, то что ООП начнет "блистать во всей красе"?
Нужно всего лишь отделять модель данных от модели операций над этими данными. В простейшем случае это можно объединить и в приведеном примере будет
account1.TransferTo(accout2, 100, Currency.USD);
Но когда трансферы усложняются, для этих операций вырастает своя моделька и хранить её вместе с моделью account как то не правильно.
Здравствуйте, Ikemefula, Вы писали:
I>Итого, в наличии две модели — модель данных и модель операций над моделью данных. И в каждой из моделей data structures будут разными. Всего то.
Ага, вот только остается вопрос: какие классы создавать?
I>Собственно про это и говорится в DDD
Не все, см вопрос выше.
Здравствуйте, gandjustas, Вы писали:
I>>Итого, в наличии две модели — модель данных и модель операций над моделью данных. И в каждой из моделей data structures будут разными. Всего то. G>Ага, вот только остается вопрос: какие классы создавать?
Классы в зависимости от функций каждой модели.
I>>Собственно про это и говорится в DDD G>Не все, см вопрос выше.
Здравствуйте, Lloyd, Вы писали:
I>>Нужно всего лишь отделять модель данных от модели операций над этими данными. В простейшем случае это можно объединить и в приведеном примере будет I>>
I>>Но когда трансферы усложняются, для этих операций вырастает своя моделька и хранить её вместе с моделью account как то не правильно.
L>Поздравляю, ты тоже сторонник процедурного подхода.
Здравствуйте, Ikemefula, Вы писали:
I>>>Но когда трансферы усложняются, для этих операций вырастает своя моделька и хранить её вместе с моделью account как то не правильно.
L>>Поздравляю, ты тоже сторонник процедурного подхода.
I>Я сторонник разделения мух и котлет.
Да, и отход от ООП в его классическом определении очень способствует этому.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>Итого, в наличии две модели — модель данных и модель операций над моделью данных. И в каждой из моделей data structures будут разными. Всего то. G>>Ага, вот только остается вопрос: какие классы создавать?
I>Классы в зависимости от функций каждой модели.
То есть сделать кучу "параллельных" моделей, поддерживать синхронно изменения, перекладывать данные туда-сюда постоянно?
Здравствуйте, Lloyd, Вы писали:
L>Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions").
А что если data structure будет иметь вот такой вид:
Здравствуйте, gandjustas, Вы писали:
I>>>>Итого, в наличии две модели — модель данных и модель операций над моделью данных. И в каждой из моделей data structures будут разными. Всего то. G>>>Ага, вот только остается вопрос: какие классы создавать?
I>>Классы в зависимости от функций каждой модели.
G>То есть сделать кучу "параллельных" моделей, поддерживать синхронно изменения, перекладывать данные туда-сюда постоянно?
Зачем перекладывать ? Модель данных и модель операций — это значит что данных отдельно от операций над ними. Всё. Модель операций может вообще не иметь состояния. Но даже если и имеет, это далеко не всегда значит, что будут какие то параллельные модели где надо синхронизировать изменения.
Здравствуйте, Ikemefula, Вы писали:
L>>Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions").
I>А что если data structure будет иметь вот такой вид:
I>
I>Добавив сюда метод Transfer и дав всему этому название TransferService получим ровно то что в классическом определении.
Я не знаю ни что такое Account, ни что такое ICurrencyRates, ни что такое ITransferPolicy.
I>Или ты считаешь, что data structure может состоять только из примитивных типов ?
1. Что такое "примитивные типы"?
2. С чего вы это взяли, что я так считаю?
3. Какое это имеет отношение в тому, что обсуждается?
P.S. Вы не могли бу проямнить свою позицию, чтобы я понимал, что именно вы отстаиваете?
I>>Добавив сюда метод Transfer и дав всему этому название TransferService получим ровно то что в классическом определении. L>Я не знаю ни что такое Account, ни что такое ICurrencyRates, ни что такое ITransferPolicy.
Account это entity, например такие классы генерит EF ICurrencyRates это конвертор курсов, нужен для перевода средств со счета на счет если у счетов разные валюты. ITrancferPolicy это правила которые определяют как происходит конкретный трансфер.
I>>Или ты считаешь, что data structure может состоять только из примитивных типов ?
L>1. Что такое "примитивные типы"?
int, string, double
L>2. С чего вы это взяли, что я так считаю?
Потому что один раз ты назвал такой подход "менее ооп"
L>3. Какое это имеет отношение в тому, что обсуждается?
I>>>Добавив сюда метод Transfer и дав всему этому название TransferService получим ровно то что в классическом определении. L>>Я не знаю ни что такое Account, ни что такое ICurrencyRates, ни что такое ITransferPolicy.
I>Account это entity, например такие классы генерит EF ICurrencyRates это конвертор курсов, нужен для перевода средств со счета на счет если у счетов разные валюты. ITrancferPolicy это правила которые определяют как происходит конкретный трансфер.
Что Account делает в полях сервиса? Зачем он там?
I>>>Или ты считаешь, что data structure может состоять только из примитивных типов ?
L>>1. Что такое "примитивные типы"?
I>int, string, double
Ок.
L>>2. С чего вы это взяли, что я так считаю?
I>Потому что один раз ты назвал такой подход "менее ооп"
При чем тут подход? С спрашивал "с чего вы взяли, что я считаю, что data structure может состоять только из примитивных типов"?
L>>3. Какое это имеет отношение в тому, что обсуждается?
I>Непосредственное.
Значит вам не составит труда продемострировать это отношение. Дерзайте.
P.S. Вы не могли бу проямнить свою позицию, чтобы я понимал, что именно вы отстаиваете?
L>Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions").
Вообще-то никакого ухода от ООП здесь нет. Логика, затрагивающая несколько сущностей, не обязательно должна быть инкапсулирована в одной из них. Вполне нормально, когда она инкапуслирована в каком-то контексте. Пример: два объекта класса "Человек" судятся друг с другом. Нельзя определить операцию "податьВСуд" для класса "Человек", потому что суд руководствуется законом. DDD в таких случаях предлагает в слое бизнес-логики создать класс "Суд" с методом "рассудить(Человек истец, Человек ответчик)" и инициализировать его экземпляр сводом законов.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>>>Итого, в наличии две модели — модель данных и модель операций над моделью данных. И в каждой из моделей data structures будут разными. Всего то. G>>>>Ага, вот только остается вопрос: какие классы создавать?
I>>>Классы в зависимости от функций каждой модели.
G>>То есть сделать кучу "параллельных" моделей, поддерживать синхронно изменения, перекладывать данные туда-сюда постоянно?
I>Зачем перекладывать ? Модель данных и модель операций — это значит что данных отдельно от операций над ними. Всё. Модель операций может вообще не иметь состояния. Но даже если и имеет, это далеко не всегда значит, что будут какие то параллельные модели где надо синхронизировать изменения.
Понял, "модель операций" это те самые сервисы, которые так любя те кто занимается anemic и не любят те кто занимаются ddd.
G>Понял, "модель операций" это те самые сервисы, которые так любя те кто занимается anemic и не любят те кто занимаются ddd.
Вот всё-таки интересно, кто же "занимается ddd и не любит сервисы"? Откуда это?
Здравствуйте, Lloyd, Вы писали:
I>>Account это entity, например такие классы генерит EF ICurrencyRates это конвертор курсов, нужен для перевода средств со счета на счет если у счетов разные валюты. ITrancferPolicy это правила которые определяют как происходит конкретный трансфер.
L>Что Account делает в полях сервиса? Зачем он там?
Для того, что бы сервис выполнял над ним операции. Это ж очевидно — отделение инициализации от операции. Удобно для работы передавать часть параметров в конструкторе, а остальные уже в конкретном методе для конкретной операции.
data structure здесь микс данных на которыми будут выполняться какие то действия и управляющие данные. Оба объекта Account являются частью этой data structure.
Еще вариант вот такой:
var rep = new AccountRepository(Application.Db);
var account1 = rep.LookUpFor(id_1);
var account2 = rep.LookUpFor(id_2);
var svc = new TransferService(Application.CurrencyRates);
svc.Transfer(account1, account2, 100, Currency.USD);
Почему это будет не ОО ? data structure будет немного другой, если точне, то будет хранить только управляющие данные как например ICurrencyRates, ITransferPolicy, а так же все остальные депенденсы которые только могут взяться. В определении ООП ничего не сказано каким должен быть data в data structure. Там используется общий термин, а следовательно подходят все случаи, в т.ч. когда data это управляющие данные.
I>>>>Или ты считаешь, что data structure может состоять только из примитивных типов ? L>>>1. Что такое "примитивные типы"? I>>int, string, double L>Ок.
L>>>2. С чего вы это взяли, что я так считаю? I>>Потому что один раз ты назвал такой подход "менее ооп" L>При чем тут подход? С спрашивал "с чего вы взяли, что я считаю, что data structure может состоять только из примитивных типов"?
Мб. не правильно понял. Но ты ведь не проясняешь свою позицию, только кидаешься общими фразами вроде "читайте определение" и тд. Сэкономь время себе и мне. Не хочешь объяснять — я ж тебя за язык не тяну.
L>>>3. Какое это имеет отношение в тому, что обсуждается? I>>Непосредственное. L>Значит вам не составит труда продемострировать это отношение. Дерзайте.
В моём примере код ты сам углядел это отношение и один из примеров выделил как "более ООП". Я продолжаю ровно ту же тему
L>Откуда взялись "несколько сущностей"?
(Капитан Очевидность) Любой метод класса с одним и более параметрами, равно как любая процедура с двумя и более параметрами, работает с несколькими сущностями. Сущности могут быть одного типа.
L>Еще немного, еще чуть-чуть и вы сами зададите вопрос о том, а в чем вообще смысл держать логику рядом с объектом. Где бенефиты?
Про бенефиты написано много в соответствующей литературе. Рекомендую ознакомиться, чтобы не выдавать одно предложение из википедии за "классическое определение ООП".
Здравствуйте, gandjustas, Вы писали:
G>Понял, "модель операций" это те самые сервисы, которые так любя те кто занимается anemic и не любят те кто занимаются ddd.
Это мягко говоря неправда В книге DDD эванс пишет в т.ч. про сервисы
Здравствуйте, Lloyd, Вы писали:
L>Еще немного, еще чуть-чуть и вы сами зададите вопрос о том, а в чем вообще смысл держать логику рядом с объектом. Где бенефиты?
Вопрос сводитcя к тому, как ты понимаешь слово data в data structure.
Здравствуйте, Baudolino, Вы писали:
L>>Откуда взялись "несколько сущностей"? B>(Капитан Очевидность) Любой метод класса с одним и более параметрами, равно как любая процедура с двумя и более параметрами, работает с несколькими сущностями. Сущности могут быть одного типа.
Повторю вопрос, откуда взялись "несколько сущностей"?
L>>Еще немного, еще чуть-чуть и вы сами зададите вопрос о том, а в чем вообще смысл держать логику рядом с объектом. Где бенефиты? B>Про бенефиты написано много в соответствующей литературе. Рекомендую ознакомиться, чтобы не выдавать одно предложение из википедии за "классическое определение ООП".
Спасибо, родной. Но большинство литературы (включая Эванса) было мною давно прочитано.
А вам я в свою очередь могу порекомендовать не только читать литературу, но и вопросы, которые вам задают. Если вы затрудняетесь ответить, то переходить на личности — не самый лучший способ скрыть это.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Lloyd, Вы писали:
L>>Еще немного, еще чуть-чуть и вы сами зададите вопрос о том, а в чем вообще смысл держать логику рядом с объектом. Где бенефиты?
I>Вопрос сводитcя к тому, как ты понимаешь слово data в data structure.
Да, в этом и есть проблема. Я наерное неудачно использовал это слово.
L>Повторю вопрос, откуда взялись "несколько сущностей"?
Я не понимаю смысл этого вопроса. Они взялись в качестве примера, в котором в рамках объектно-ориентированного подхода разделяются модель предметной области и бизнес-логика. По-моему, очевидно, что в ситуации, когда имеется один объект с парой-тройкой примитивных полей (или N никак не связанных объектов), бизнес-логику выносить некуда и незачем.
Здравствуйте, Baudolino, Вы писали:
B>По-моему, очевидно, что в ситуации, когда имеется один объект с парой-тройкой примитивных полей (или N никак не связанных объектов), бизнес-логику выносить некуда и незачем.
Ок. Предположим, что незачем. Преимущества какие-нибудь есть в "не-вынесении"?
Здравствуйте, Baudolino, Вы писали:
G>>Понял, "модель операций" это те самые сервисы, которые так любя те кто занимается anemic и не любят те кто занимаются ddd. B>Вот всё-таки интересно, кто же "занимается ddd и не любит сервисы"? Откуда это?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
G>>Понял, "модель операций" это те самые сервисы, которые так любя те кто занимается anemic и не любят те кто занимаются ddd.
I>Это мягко говоря неправда В книге DDD эванс пишет в т.ч. про сервисы
L>Ок. Предположим, что незачем. Преимущества какие-нибудь есть в "не-вынесении"?
Я обозначил тривиальный случай ровно потому, что его нет смысла обсуждать — он тривиален. Если вам очень важно знать, каковы плюсы и минусы различных подходов в случае модели с одним объектом, имеет смысл создать отдельную тему в разделе "О жизни". Если это просто способ что-нибудь сказать, но по существу вопроса возражений нет, давайте лучше просто закончим разговор и не будем тратить время.
L>То, что DDD и anemic model — перпендикулярные концепции.
Ну выскажите свои аргументы, если не согласны. Почему DDD исключает или наоборот обязательно подразумевает anemic model?
Здравствуйте, Baudolino, Вы писали:
L>>Ок. Предположим, что незачем. Преимущества какие-нибудь есть в "не-вынесении"? B>Я обозначил тривиальный случай ровно потому, что его нет смысла обсуждать — он тривиален.
Если он тривиальный, то и объяснить преимущества будет очень легко.
B>Если вам очень важно знать, каковы плюсы и минусы различных подходов в случае модели с одним объектом, имеет смысл создать отдельную тему в разделе "О жизни". Если это просто способ что-нибудь сказать, но по существу вопроса возражений нет, давайте лучше просто закончим разговор и не будем тратить время.
Кажется в демагогии этот прием называется "ложная альтернатива", не так ли?
L>Если он тривиальный, то и объяснить преимущества будет очень легко. L>Кажется в демагогии этот прием называется "ложная альтернатива", не так ли?
Демагогия — это ваша попытка увести разговор в сторону обсуждения всякой ерунды.
Здравствуйте, Baudolino, Вы писали:
L>>То, что DDD и anemic model — перпендикулярные концепции. B>Ну выскажите свои аргументы, если не согласны. Почему DDD исключает или наоборот обязательно подразумевает anemic model?
Вы меня прям в неловкое положение ставите. Некрасиво как-то предлагать вам открыть Эванса и хотя бы пролистать, глянуть на даиграмки, которые он там приводит. Там практически что не сущность, то с методами.
Тут одно из двух — либо Эванс это уже не ddd, либо в anemic нормальная практика объявлять бизнес-логику в методах сущностей.
Здравствуйте, Baudolino, Вы писали:
L>>Если он тривиальный, то и объяснить преимущества будет очень легко.
Вы забыли ответить на вопрос.
L>>Кажется в демагогии этот прием называется "ложная альтернатива", не так ли? B>Демагогия — это ваша попытка увести разговор в сторону обсуждения всякой ерунды.
Вы увели разговор в сторону частного случая, когда в опреации учавствует более одной сущности. Почему я не могу его увести в другую сторону?
L>Вы меня прям в неловкое положение ставите. Некрасиво как-то предлагать вам открыть Эванса и хотя бы пролистать, глянуть на даиграмки, которые он там приводит. Там практически что не сущность, то с методами.
Вперёд. Открываете Эванса и ищете утверждение, из которого прямо следует, что DDD и anemic model взаимно исключающие понятия. Потом постите сюда цитату и номер страницы.
То, что вы там где-то на диаграммах и в примерах увидели, меня не интересует.
Здравствуйте, Baudolino, Вы писали:
L>>Вы увели разговор в сторону частного случая, когда в опреации учавствует более одной сущности. Почему я не могу его увести в другую сторону? B>Потому что ваш частный случай не интересен с точки зрения архитектуры. Единственный объект с состоянием эквивалентен программе с несколькими глобальными переменными.
Я и не предлагаю такой случай обсуждать. Прочтите внимательнее, речь не об одном объекте, а об операции, в которой учавствиет один объект.
Чтобы было еще понятнее: например, операция "*" требует 2-х аргументов, а операция abs — одного.
B>ОО подход здесь вырождается в процедурный. Не имеет никакого значения, в каком пространстве имён будут размещены процедуры, работающие с состоянием этого объекта.
Не, ну зачем вы так, не надо так уж принижать процедурный подход. Глобальные переменные — далеко не единственный способ передать данные в процедуру.
B>Тут абсолютно нечего обсуждать, и дальше в этом направлении разговор я поддерживать не буду.
Здравствуйте, Baudolino, Вы писали:
L>>Вы меня прям в неловкое положение ставите. Некрасиво как-то предлагать вам открыть Эванса и хотя бы пролистать, глянуть на даиграмки, которые он там приводит. Там практически что не сущность, то с методами. B>Вперёд. Открываете Эванса и ищете утверждение, из которого прямо следует, что DDD и anemic model взаимно исключающие понятия.
На этот раз — манипулирование смыслом высказываний и подмена тезиса. Такое ощущение, что вы прям как по списку идете.
B>Потом постите сюда цитату и номер страницы.
Первое, что попалось: "Figure 11.7. The class diagram after the implementation", страницу не скжу. Найдите на най класс Asset и убедитесь.
B>То, что вы там где-то на диаграммах и в примерах увидели, меня не интересует.
Здравствуйте, Baudolino, Вы писали:
L>>Вы увели разговор в сторону частного случая, когда в опреации учавствует более одной сущности. Почему я не могу его увести в другую сторону? B>Потому что ваш частный случай не интересен с точки зрения архитектуры. Единственный объект с состоянием эквивалентен программе с несколькими глобальными переменными. ОО подход здесь вырождается в процедурный. Не имеет никакого значения, в каком пространстве имён будут размещены процедуры, работающие с состоянием этого объекта. Тут абсолютно нечего обсуждать, и дальше в этом направлении разговор я поддерживать не буду.
Позвольте, шло обсуждение некоторого общего случая на примере с двумя экземплярами аккаунта. Никто на этом не акцентировал внимание, кроме вас
. Теперь вы вашему частному случаю противопоставляете единственный объект со состоянием. Кто ж вас заставляет в крайности кидаться? Ниужели по-вашему между нескольких сущностей и единственным объектом с состоянием ничего нет?
Между прочим, сущности есть и в процедурном подходе. Их там называют "записями". Вполне себе можно иметь несколько экземпляров записей, не ограничиваясь глобальными переменными.
L>Я и не предлагаю такой случай обсуждать. Прочтите внимательнее, речь не об одном объекте, а об операции, в которой учавствиет один объект.
У меня есть привычка внимательно читать, что мне пишут. Цитирую ваши же слова: Откуда взялись "несколько сущностей"?
Если подразумевалась операция, надо было об этом сказать сразу. Впрочем, я бы ответил то же самое. Это вырожденный случай и он не интересен. Если у вас данные из предметной области никак не взаимодействуют между собой и не связаны отношениями, то всё, опять же, сводится к процедурному подходу, и, опять же, не имеет никакого значения, в каком пространстве имён расположены операции над этими данными. Как только появляется отношение и/или взаимодействие — всё, уже можно рассматривать контекст и возможность/необходимость выноса в сервисный слой.
L>На этот раз — манипулирование смыслом высказываний и подмена тезиса. Такое ощущение, что вы прям как по списку идете.
Хорош юлить. Какое нафиг манипулирование? Либо вы опровергаете мои слова, доказывая, что DDD и anemic model — связанные понятия (т.е. DDD требует или наоборот исключает anemic model), либо нет.
B>>Потом постите сюда цитату и номер страницы. L>Первое, что попалось: "Figure 11.7. The class diagram after the implementation", страницу не скжу. Найдите на най класс Asset и убедитесь. L>Да, я так и понял. http://en.wikipedia.org/wiki/Proof_by_example
L>Нет, это не вырожденный случай. Откройте Эванса и убедитесь, что эта "вырожденность" — на каждой второй диаграмме с сущностями.
У вас какой-то особый навык делать могучие логические выводы из картинок в книжке. В данном конкретном случае не имеет никакого значения, что там нарисовал Эванс. Думайте своей головой.
L>Или понятие "вырожденность" вы тоже как-то индивидуально трактуете и оно меняется от поста к посту?
Меняется только у вас в голове, потому что вы не хотите внимательно прочитать, что я писал, и подумать над этим.
L>"Сервисный слой" — это и есть "поцедурный" подход.
Ну это просто растиражированный здесь бред, который легко опровергается мной же приведенным примером, в котором сервис имеет состояние.
S>Ниужели по-вашему между нескольких сущностей и единственным объектом с состоянием ничего нет?
Между единицей и любым числом больше единицы действительно ничего нет.
S>Между прочим, сущности есть и в процедурном подходе. Их там называют "записями".
Спасибо, что открыли мне глаза.
S>Вполне себе можно иметь несколько экземпляров записей, не ограничиваясь глобальными переменными.
Можно. Это что-то меняет?
Здравствуйте, Baudolino, Вы писали:
L>>На этот раз — манипулирование смыслом высказываний и подмена тезиса. Такое ощущение, что вы прям как по списку идете. B>Хорош юлить. Какое нафиг манипулирование? Либо вы опровергаете мои слова, доказывая, что DDD и anemic model — связанные понятия (т.е. DDD требует или наоборот исключает anemic model), либо нет.
Есть ряд практик (бизнес-логика в сущеностях), которые "запрещены" anemic, но вполне приемлемы (судя по примерам Эванса) в ddd.
Упреждая дальнейшую подмену:
противополижностью запрещения делать что-либо являемя не запрет не делать это, а разрешение это делать.
Это не тот случай, чтобы вы не начали говорить, что ddd не запрещает выносить логику из классов.
B>>>Потом постите сюда цитату и номер страницы. L>>Первое, что попалось: "Figure 11.7. The class diagram after the implementation", страницу не скжу. Найдите на най класс Asset и убедитесь. L>>Да, я так и понял. B>http://en.wikipedia.org/wiki/Proof_by_example
Нет, либо ты неудачно пошутил, либо не понял, что там написано.
Для того, чтобы показать, что какое-то явление возможно, достаточно привести 1 пример. "какое-то явление" тут — это наличие бизнес-логики в сущностях.
Здравствуйте, Baudolino, Вы писали:
S>>Ниужели по-вашему между нескольких сущностей и единственным объектом с состоянием ничего нет? B>Между единицей и любым числом больше единицы действительно ничего нет.
Снова подмена. Речь шла о нескольких сущностях без оговорок, потом о единственном объекте с состоянием, эквивалентным программе с глобальными переменными.
На что подменили — я даже не понял. Что представляет собой величина, определенная как разинца между единицей и любым числом больше единицы? Разница между единицей и наперед заданным числом больше единицы — понимаю. Но эта разница существенна для любого наперед заданного числа.
Сначала было неоговоренное кол-во сущностей. Потом вы сузили до несколько, на что вам справедливо заметили что вы рассматриваете частный случай. В противоположность вашему случаю вы же придумали случай с одним объектом. Причем не просто с одним, а с одним объектом с состоянием (наверное другие без состояния). Эквивалентность такого случая программе с несколькими глобальными переменными не очевидна.
S>>Между прочим, сущности есть и в процедурном подходе. Их там называют "записями". B>Спасибо, что открыли мне глаза.
Не за что
S>>Вполне себе можно иметь несколько экземпляров записей, не ограничиваясь глобальными переменными. B>Можно. Это что-то меняет?
не меняет. Это ставит под сомнение адекватность перехода от нескольких сущностей к процедурному подходу в контексте спора о том, является ли анемик безотносительно кол-ва сущностей шагом от ООП или нет.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Baudolino, Вы писали:
L>>>"Сервисный слой" — это и есть "поцедурный" подход. B>>Ну это просто растиражированный здесь бред, который легко опровергается мной же приведенным примером, в котором сервис имеет состояние.
L>А где я писал, что сервим не может иметь состояния? Опять "подмена тезиса"?
Нет, не подмена. Это попытка http://en.wikipedia.org/wiki/Proof_by_example. Только неудача в том, что процедура тоже может иметь состояние (пусть глобальное), и сервисом с состоянием такую процедуру не напугать.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
I>>>Это мягко говоря неправда В книге DDD эванс пишет в т.ч. про сервисы
G>>Где именно?
L>В 5-й главе.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>>>Где именно?
L>>>В 5-й главе.
G>>А до 5 главы что?
L>До 5-й главы — главы с 1-й по 4-ю.
То есть о важном только к середине книги, а до этого бредятина всякая
B>>Между единицей и любым числом больше единицы действительно ничего нет. S>Снова подмена. Речь шла о нескольких сущностях без оговорок, потом о единственном объекте с состоянием, эквивалентным программе с глобальными переменными.
Какая нафиг подмена? Сами запутались в предмете спора и меня ещё в чём-то смеете обвинять.
Перечитайте диалог заново.
L>То вы просите цитаты, а как вам их дают, то сразу они оказываются не нужны.
Вы врёте. Цитат не было. Была отсылка к какой-то картинке.
L>Вы не ответили на вопрос, как у вас так получилось, что слово "сущность" когда об этом говорите вы и ваш собеседник обозначает для вас не одно и то же.
Вы врёте. Этот вопрос мне задан не был.
L>И таки-да, еще вы не ответили на вопрос по поводу преимуществ рекомендуемого вами подхода.
Вы врёте. Я не рекомендовал никаких подходов, соответственно вы не задавали такого вопроса. Нигде в нашем диалоге ни в одном сообщении нет моих слов "рекомендую" и "подход".
L>А где я писал, что сервим не может иметь состояния? Опять "подмена тезиса"?
Подмены пока что присутствуют исключительно в ваших репликах. Сервис может быть объектом в терминах ООП со всеми признаками — инкапсуляция, полиморфизм, наследование и проч.
L>Мои опасения про "список" только подтверждаются — вы умело продемонстриовали прием "Переход на личности".
Переход на личности обоснован. Я имею дело со лжецом и демагогом, не способным нормально аргументировать свою позицию. Ок, разговор окончен.
Здравствуйте, Baudolino, Вы писали:
L>>То вы просите цитаты, а как вам их дают, то сразу они оказываются не нужны. B>Вы врёте. Цитат не было. Была отсылка к какой-то картинке.
Эта картинка является цитатой из книги прородителья ddd.
У вас нет даже этой книжки? Если нет, то она легко гуглица. Хотя тогда не понятно чего же вы меня посылаете читать литерутуру, если сами с оной не ознакомились?
L>>Вы не ответили на вопрос, как у вас так получилось, что слово "сущность" когда об этом говорите вы и ваш собеседник обозначает для вас не одно и то же. B>Вы врёте. Этот вопрос мне задан не был.
Т.е. когда вы писали про "несколько сущностей", вы поняли все правильно. А когда я спросил про вариант с одной сущностью, то вы почему-то решили, что речь идет об экземпляре?
Как-то не вяжется.
Вот цитата из поста. Ваш ответ на него не содержал ответа.
Я-то может и вру, но содержимое форума говорит об обратном.
L>>И таки-да, еще вы не ответили на вопрос по поводу преимуществ рекомендуемого вами подхода. B>Вы врёте. Я не рекомендовал никаких подходов, соответственно вы не задавали такого вопроса. Нигде в нашем диалоге ни в одном сообщении нет моих слов "рекомендую" и "подход".
Очередное доказательство демагогии. То, что вы не употребляли слов "рекомендую" и "подход" не означает, что вы не рекомендовали подхода.
А тот факт, что вы отрицаете это, и вовсе не играет в вашу пользу — вы написали полтора десятка постов и так и не прояснили, что именно вы отстаиваете. Демагог и есть.
L>>А где я писал, что сервим не может иметь состояния? Опять "подмена тезиса"? B>Подмены пока что присутствуют исключительно в ваших репликах.
И таки, я с удовольствием бы выслушал ответ на вопрос:
А где я писал, что сервим не может иметь состояния?
B>Сервис может быть объектом в терминах ООП со всеми признаками — инкапсуляция, полиморфизм, наследование и проч.
Это было к чему сказано? Разве я оспариваю то, что вы прочитали школьный учебник по программированию?
И кстати, приведенным признами отсутствуют во многих вполне себе ОО-языках (питон, джаваскрипт, даже на С при желании можно писать в ОО-стиле).
L>>Мои опасения про "список" только подтверждаются — вы умело продемонстриовали прием "Переход на личности". B>Переход на личности обоснован. Я имею дело со лжецом и демагогом, не способным нормально аргументировать свою позицию.
Вот вы и добрались до самого главного пункта "обвинение собеседника в демагогоии". Браво, маэстро. Несите зачетку.
B>Ок, разговор окончен.
Ты главное, не расплакайся там. Не стоит оно того. Лучше учебник еще раз перечитай.
Здравствуйте, Ziaw, Вы писали:
L>>Для того, чтобы показать, что какое-то явление возможно, достаточно привести 1 пример. "какое-то явление" тут — это наличие бизнес-логики в сущностях.
Z>Это означает ровно одно. Что Эванс демонстрирует DDD на примерах c rich model.
Z>Доказательства того, что DDD и anemic несовместимы здесь нет. Есть доказательство совместимости с rich model, при этом, возможна совместимость и с anemic. Основной постулат DDD — максимальное приближение модели данных к естественным сущностям в бизнесе.
Не согласен я.
В понимании Эванса (точнее в моем понимании Эванса ), ddd — это не только принцип, но и архитектура с определенным разбиением на энтити, агрегаты, вэлью-объекты, фабрики, репозитории, сервисы и так дале и тому подобное.
И примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель.
Более того, раздел про сервисы начинается, что мол если у вас есть непонятки по поводу того, куда поместить операцию (In some cases, the clearest and most pragmatic design includes operations that do not conceptually belong to any object), то кладите ее в отдельный сервис. Это как-бы отводит сервисам вторичную роль, мол если не удалось найти куда приткнуть, то делайте сервис, что как бы опять приводит к выводу, что в остальных случаях у нас операции будут в энтитях.
Если в качестве первоисточника обращаться к эвансу, то ddd — это все-таки рич.
Здравствуйте, Baudolino, Вы писали:
B>>>Между единицей и любым числом больше единицы действительно ничего нет. S>>Снова подмена. Речь шла о нескольких сущностях без оговорок, потом о единственном объекте с состоянием, эквивалентным программе с глобальными переменными. B>Какая нафиг подмена? Сами запутались в предмете спора и меня ещё в чём-то смеете обвинять.
Я в предмета спора не касался и тем самым не давал повода обвинять меня в запутанности. Мои посты здесь касались только ваших попыток трансформации темы. И я вас не обвиняю, я указываю на недоразумения в ваших аргументах.
B>Перечитайте диалог заново.
Перечитывал. И свое видение ваших постов описывал. Возражений не нашел, наверное вы согласны с этим видением.
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, Lloyd, Вы писали:
L>>Для того, чтобы показать, что какое-то явление возможно, достаточно привести 1 пример. "какое-то явление" тут — это наличие бизнес-логики в сущностях.
Z>Это означает ровно одно. Что Эванс демонстрирует DDD на примерах c rich model.
Z>Доказательства того, что DDD и anemic несовместимы здесь нет. Есть доказательство совместимости с rich model, при этом, возможна совместимость и с anemic. Основной постулат DDD — максимальное приближение модели данных к естественным сущностям в бизнесе. Я совершенно не понимаю хайпа вокруг этой аббревиатуры.
Z>Кстати, ровно то же самое говорит википедия: Z>
Relationship to other ideas
Z>... Z>POJOs and POCOs Z>POJOs and POCOs are technical implementation concepts, specific to the Java and .NET framework respectively. However, the emergence of the terms POJO and POCO, reflect a growing view that, within the context of either of those technical platforms, domain objects should be defined purely to implement the business behaviour of the corresponding domain concept, rather than be defined by the requirements of a more specific technology framework.
Изначально в ветке противопоставлялись анемик и ООП. Не совсем противопоставлялись, речь шла о том что анемик это шаг от ООП. Раз пошли в ход ссылки на википедию, тоже всталю. В википедии отсылают к процедурному программированию.
The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design; which is to combine data and process together. The anemic domain model is really just a procedural style design, exactly the kind of thing that object bigots like me (and Eric) have been fighting since our early days in Smalltalk.
Я не согласен что это ужасно, хочу лишь обратить внимание на то что Фаулер (and Eric) тоже отсылает к процедурному стилю.
Там же у Фаулера есть цитата из Еванса о том что он против концентрирования логики в сервисных слоях (что имеет место при активном использовании анемика). Это не значит что DDD и anemic несовместимы, но косвенно выдает отношение Еванса к жирным сервисным слоям.
И кроме этого, я считаю что POJO и anemic — совершенно разные вещи.
VD>Позволь полюбопытствовать, а "нормальная архитектура" и ООП — это одно и то же?
Вопрос с подвохом Нормальный OOD — как минимум, соблюдение SOLID. Получаем поддерживаемую систему, могущую изменяться под новые требования без переписывания половины кода с последующим трехмесячным дебагом. Что такое говнокод на ОО-языке? Номер раз — процедурщина. Этого добра так много, что номер два (нездоровое увлечение фп) на ее фоне почти незаметен. Немного фп внутри класса — ок, упрощает рутинные операции, но когда пытаются строить на этом архитектуру — это даже не смешно.
Здравствуйте, -VaS-, Вы писали:
VD>>Позволь полюбопытствовать, а "нормальная архитектура" и ООП — это одно и то же?
VS>Вопрос с подвохом Нормальный OOD — как минимум, соблюдение SOLID.
1) SOLID не про ООП в основном, там только принцип OCP непосредственно связан с ООП, и то это совершенно бесполезный принцип в оргинале
2) Сами принципы крайне туманны и не дают критерия соответствия принципам. То есть ты по коду не можешь объективно утверждать выполняется ли тот или иной принцип (за редким исключением). http://gandjustas.blogspot.com/2011/08/solid.html
тут подробно свой взгляд описал. Предупреждаю, он сильно не соответствует тому что можно в интернетах прочитать.
VS>Получаем поддерживаемую систему, могущую изменяться под новые требования без переписывания половины кода с последующим трехмесячным дебагом.
У меня после такой фразы возникает вопрос: каким образом тогда новый функционал достигается?
VS>Что такое говнокод на ОО-языке? Номер раз — процедурщина. Этого добра так много, что номер два (нездоровое увлечение фп) на ее фоне почти незаметен. Немного фп внутри класса — ок, упрощает рутинные операции, но когда пытаются строить на этом архитектуру — это даже не смешно.
Поменьше эмоциональных оценок, побольше конкретики. Что такое "процедурщина" ? Почему плохо строить на ФП всю архитектуру?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, licedey, Вы писали:
L>>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
G>Да, ты угадал. ООП совсем не подходит для проектирования программ.
Это ирония? А что тогда подходит или дополняет ООП?
Я говорю не о масштабных программах, а скорее о конкретной задаче. Например такого типа: сниффер, плагин к браузеру, архиватор...Вопрос спорный, нужно ли изголяться и выявлять сущности, которых по сути нет. Для них создавать класс, при том, что объект может быть один..
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, licedey, Вы писали:
L>>Здравствуйте, мыщъх, Вы писали:
М>>>Здравствуйте, licedey, Вы писали:
L>>У меня любая задача так. Уж чему научился по книжкам ООП ин депс, тем и владею. От того и получается. L>>Задача: напиши снифер 80-го протокола, чтобы уловить откуда видео идет. L>>Я написал 3 класса: NetworkAdapterDetector, FlashSniffer, и TrackingURL. L>>Ну думаю вы понимаете, что каждый из них делает. М>совершенно не представляю. нет такого протокола. нормальный сниффер (типа wireshark) сниффет все подряд. догадываюсь, что вам нужно сниффать TCP. догадываюсь, что это http. догадываюсь, что нужно парсить HTML. итого, мы имеем две _никак_ не связанные друг с другом задачи. первая -- просто сниффер. он уже есть. tcpdump в линухе. переводит карту в неразборчивый режим и ловит все, что адресовано ему и не ему. записывает резултать в pcap.
М>вторая задача -- распарсить pcap. сначала парсим, чтобы вытащить ethernet, из него ip, из него tcp, из него http. парсиг html в принципе это третья задача, т.к. парсеру html все равно подаем ли мы на вход html-файл, скаченный из сети или награбленный сниффером.
М>кстати, из ваших классов ни фига не понятно будет ли программа работать с уже готовыми pcap файлами или нет. так же непонятно почему flash выделена в отдельную сущность. там декопилтяор swf что ли?!
>> В тоже время, мой аппонент, Модифицировал существующий код. >> Ну я потратил на это все 30 часов. Он около 15-ти. М>фигасе. с готовыми библеотеками (а их просто море) я написал экстрактор ссылк на полчаса (в которые вошел и поиск этих самых библиотек) и написание кода. у меня три отдельных модуля. сниффер (на входе трафик, на выходе pcap), экстрактор http трафика (на входе pcap, на выходе html) и декодер html, кстати, поддерживающий java script'ы и обсусцированные ссылки. на входе html на выходе -- список ссылок. причем, модули совершенно независимы и легко расширяемы.
>> Мой эстетичней, документированней и "разделяй и влавствуй". М>так у вас все в кучу. давайте еще раз разделять. М>1) снифаем трафик; М>2.1) парсим протоколы: Ethernet, IP, TCP М>2.2) парсим HTTP (по хорошему это намного сложнее чем IP и TCP); М>3.1) парсим HTML по тупому (считаем, что там нет скриптов) М>3.2.1) выполняем java scrpt'ы и vbscipt на JS/VBS дивжках и грабим вывод; М>3.3.2) эмулируем DOM (или берем готовый из браузера)
М>как-то так... если нужна детекция swf, то это отдельная задача. причем, я решил эту задачу в рамках процедурного подхода. приплюснотого кода там нет вообще. и это ни разу не ооп. но декомпозиция задачи выполнена вполне. собственно, говоря, парсер HTTP это отдельная задача, т.к. нужно поддержать кучу методов кодировая данных, кучу ответов сервера. понимать что такое POST и GET... но считаем, что парсер HTTP берется библиотечный, т.к. писать его самим это работы на 30 дней, а не часов
>> Вот собственно предпосылка этого поста. Программировать на время, или на качество, >> с заделом на будущее. Под вопросом, нужно ли это заказчику. М>по вашей модели не ясно -- будет ли оно работать под никсами, например. сколько кода придется переписать. а что если это будет другой порт? а что если у нас прокси? а как на счет https траффика? а если нужно ловить не только HTML ссылки, но и составить "черынй" список доменных имен и IP адресов, относящийся ко всем протоколам? в приведенной мной модели все это делается без напряга. т.к. уровни четко разграничены и каждый уровень делает свою работу. а у вас?
L>>Ну все равно, нажимаем же File->Add new item. М>а если это vim?
>> потом уже дальше думаем. Мне больше с нуля нравится, когда за каждую строчку >> сам отвечаешь. И в случае чего, быстрей костыль подставлю. М>мне тоже нравится отвечать за себя и больше ни за кого. но вот надо решить задачу и разбросать ее между несколькими сотрудниками, котрые в разных странах живут, часовые пояса совсем не перекрываются, да и пишут они на разных языках. правильная декомпозиция приводит к тому, что сотрудники вообще не будут знать друг о друге. в частности, парсер HTTP не зависет от парсера HTML, не говоря уже за сам сниффер.
М>на чем пишут люди -- мне все равно. хоть на си, хоть на плюсах, хоть на иврите. так что заканчивайте думать о строчках и думайте о задаче в целом, поскольку задача имеет множество решений:
М>1) сниффер, втыкаемый в ethernet и снифающий траффик; М>2) сниффер на внешнем гейте; М>3) http-proxy на гейте;
М>https можно сниффать только если или добавить на все компы свой сертификат или через https прокси. но в первом случае нужнен доступ ко всем компам и ноутам сотрудников, а во втором браузер будет ругаться на левый сертификат.
М>кстати, если уже пошел разговор за конкретные иженерные задачи -- на фига вам изобреть свой велосипед? есть же опен-соурсный Snort. на его базе можно замутить практически что угодно. и ничего парсить не надо. достаточно написать правило для ловли всех GET'ов (т.к. видео будет в них).
М>тут так же следует уточнить про какое видео мы говорим. если про то, которое льется по интернету -- то тут HTML вообще парсить не надо, а можно ограничится HTTP. если же нужно извлечь ссылки на видео еще до того как их начнут смотреть -- пишем парсер.
Отвечу коротко, уж извините Есть такого рода MediaSniffer. Но он парсит только видео по расширению от 'GET' ответа. Использует WinPcap либу. Для ютюба например, такой подход не годится. У него в гэт запросе неясно, что за поток идет.
Поэтому было предложено парсить также ответ сервера на Content-Type. По полученному майм-типу, собственно и выявлялось что имеем. Также заданием было определять нужный адаптер автоматически, этим занимался NetworkAdapter (делая пинг и какой адаптер словит — тот и активный). FlashSniffer занимался тем самым парсингом ответов сервера на предмет типа потока. Ну а TrackingUrl привязывался к хосту, от которого идет видео-поток.
К слову сказать, с тем же ютюбом, ответы иногда идут не HTTP 200, а HTTP 304 например. Не перехватывает моя реализация также и rutube.ru. Нет от него ответа 200, с типом контента. Используеться WinPCap.
В вашем комментарии одно задело, "за 30 минут с учетом поиска". На чтение спецификации только и копания сырцов медисниффера, только день ушел. И то в режиме "дым из попы". Потом на детект адаптера день, попутно изучив тонкости WinPcap. И день уже на реализацию снифера согласно спецификации.
При всем уважении к вашему профессионализму — это невозможно! Даже знаю winpcap и не следуя строго требованиями. Минимум день.
Здравствуйте, Sinclair, Вы писали:
S>>>Для начала, нужно твёрдо усвоить, что ООП — оно целиком про поведение. А не про структуру полей и методов. L>>Несомненно, Антон из Новосиборска туфты не напишет. S>Спасибо за доверие, но я тут ни при чём. Читайте изобретателя ООП — Алана Кея.
С удовольствием почитаю. Но раз уж вы его рекомендуете, то вам несомненно не составит труда привести цитату автора, опровергающую формулировку из википедии.
S>Кроме того, имеет смысл применять критическое мышление. К примеру, если вы видите, что предлагаемые кем-то правила неизменно приводят к плохому результату, то эти правила сами плохи. Особенно если есть альтернативные правила, которые приводят к более понятным и предсказуемым результатам. S>Например, трактовка ООП как механизма по конструированию объектов из данных и методов приводит к бесплодным спорам вроде того, наследовать ли эллипс от круга или наоборот. При этом моделирование от поведения моментально приводит к правильному ответу.
Факт 1: применение ООП (по википедии) приводит к " бесплодным спорам".
Факт 2: моделирование от поведения приводит к правильному ответу.
Вывод: ООП — целиком про поведение.
Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан.
А так да, я согласен, "имеет смысл применять критическое мышление", причем прежде всего имеет смысл применять его к себе же.
L>Отвечу коротко, уж извините Есть такого рода MediaSniffer. L>Но он парсит только видео по расширению от 'GET' ответа. Использует WinPcap либу.
что хорошо укладывается в предложенную мной модель. если достаточно парсинга GET, ограничиваемся модулем HTTP и в HTML не лезем. в принципе, с некоторым риском можно парсить "сырой" поток минуя IP и TCP по регуляркам, т.к. скорее всего GET будет целиком в одном пакете. как сырое и быстрое решение для набора статистики "какой гад смотрит видео" оно вполне прокатит (ведь никто же не будет устанавливать TCP-тоннель, кладующий в пакет по одному байту).
но тут все зависит от задачи. если мы парсим HTML, то можно вытянуть не только линк на видео, но и название клипа. одно дело если человек смотрит лекцию от гугла по распределенной файловой системе и совсем другое если это "видеоприколы" или порно. а многие порносайты используют обфускацию для обхода фаеров. там вообще очень интересная схема, где задействуется reverse dns как средство передачи актуального линка. и GET'а не будет. не, ну то есть он будет конечно, но там будет GET на случайное доменное имя и случайный ID. такие доменные имена живут не больше недели, что сильно затрудняет их блокировку и чтобы их все-таки заблокировать нужно распарсить еще и dns.
> Также заданием было определять нужный адаптер автоматически, этим занимался NetworkAdapter > (делая пинг и какой адаптер словит — тот и активный).
что значит "активный"? у меня, например, три адаптера. два физических и один виртуальный. и все активные. но смотрят в разные сети. и при заходе на ms.com траффик идет через один, а при заходе на юутб -- через другой. а при заходе на произвольный сайт -- хз. нужно смотреть как марштутизация прописана.
L> К слову сказать, с тем же ютюбом, ответы иногда идут не HTTP 200, а HTTP 304 например.
и еще 307 быть может. так что нужно парсить все возможные ответы.
L> В вашем комментарии одно задело, "за 30 минут с учетом поиска".
именно столько нужно, чтобы взять готовые либы и собрать их. на выходе мы будет иметь разобранный HTTP трафик с поддержкой всех кодов ответа и остальных полей.
> На чтение спецификации только и копания сырцов медисниффера, только день ушел.
это потому что вы взяли неправильный открытый проект. я использовал вот это: http://code.google.com/p/pypcap/
не самая лучшая библиотека, но на первой странице гугла. глубже искать было лениво.
> И то в режиме "дым из попы". Потом на детект адаптера день, попутно изучив тонкости WinPcap.
а обязательно именно winpcap? линух заюзать не проще было бы? там этих тонкостей меньше. хотя если вы никогда ранее не сталкивались с такой задачей -- тогда, конечно, совсем другое дело.
L>При всем уважении к вашему профессионализму — это невозможно! L>Даже знаю winpcap и не следуя строго требованиями. Минимум день.
с использованием dpkt либы парсер HTTP уровня у меня уложился в 93 строки (включая пустые), причем 68 из них -- это копи-паст примера использования этой либы с незначительным допилом под свои нужды. главное -- не писать уже написанное другими.
но мы вообще отклонились от темы. и ваша, и моя концепции укладываются в модульное программирование. кстати, closures -- они ж вроде вполне себе процедурные и совсем не объективно ореентированные, хотя используют ООП-концепцию, где данные упрятаны внутрь объекта. т.е. мы пишем read = OpenAdapter(аргументы) и дальше buf = read(ethernet.ETH_TYPE_IP); красиво и элегантно и данные об адаптере уже внутри OpenAdapter, который вернул функцию read, имеющую к ним доступ. и на closures можно писать то, что пишется на классах и это будет совсем не похоже на ООП.
поскольку, задачи грабежа, парсинга, анализа трафика и визуализации результатов анализа совершенно незавимые, то ООП тут никаким боком. предлгаю -- грабеж делать на базе tcpdump, парсинг -- на питоне, результат ложить в базу данных типа мускуля, через механизм сообщений (выдранный из апача) дергать модуль на руби, который извлечет данные и их проанализирует, записав в другую базу, а визуализация -- это веб-интерфейс на жаба.
какой смысл писать все на си++ ? и задача декомпозиции ну никак не сводится к трем упомянутыми вами компонентам. поскольку, мало распарсить трафик, нужно проанализировать результат и где-то его сохранить. если трафика немного, то можно ограничится хэш-массивами. а вот если трафика сильно до фига, то правильный выбор базы данных -- это отельная задача, не говоря уже за проектирование самой структуры этой базы.
и, кстати, вы не ответили на мой коренной вопрос -- чем отличается класс от модуля? в смысле чем он отличается в вашей схеме. модуль это черный ящик с публичным интерфейсом. класс -- это черный ящик с публичным интерфейсом и обозначенной иерархией. в частности, TCP и UDP в ООП могут быть производными от IP. а у модуля они все одного ранга. и в этом сила модулей. что вы скажите за TCP over TCP ? если ваши классы не предусматривают возможности такой "производности", то мы приплыли и нужно все перепроетировать заново. а если вспомнить о IPv6 over IPv4, то неудачно выбранная модель классов не позволит его поддержать без переделки всего и вся. и возникает вопрос -- а зачем нам вообще нужны классы?! зачем нам явно указывать иерархию? вот и не будет ее указывать! но "плоская" модель одноранговых классов по сути своей является набором модулей.
в общем, не вижу я здесь ООП.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, licedey, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, licedey, Вы писали:
L>>>Я хотел бы спросить. Вот поступает задача. У меня как у фрилансера это часто, на месяц неделю итд. L>>>Ну я стараюсь разбить ее на классы, объекты сначала. Но эта внутренняя красивость не дает нужного результата в релизе. Скажите как вы делаете задание с нуля. Главное ведь чтоб работало? А это "эстетствующее" никак с ним не вяжется. Кому интересно что там внутри.
G>>Да, ты угадал. ООП совсем не подходит для проектирования программ.
L>Это ирония? А что тогда подходит или дополняет ООП? L>Я говорю не о масштабных программах, а скорее о конкретной задаче. Например такого типа: сниффер, плагин к браузеру, архиватор...Вопрос спорный, нужно ли изголяться и выявлять сущности, которых по сути нет. Для них создавать класс, при том, что объект может быть один..
Как ни странно помогает функциональная (!) декомпозиция.
Программа у тебя — черный ящик, она принимает некоторые данные на вход и выдает что-то на выходе.
Прямо из юзкейсов можно получить входы и выходы.
Далее ты пытаешься черный ящик разбить на более простые ящики, которые также имеют входы и выходы итд, пока не дойдешь до конкретных модулей, реализацию каждого из которых ты уже можешь себе представить или взять готовые модули.
Берем например сниффер:
1)На входе у нас поток пакетов с сетевой платы
2)На выходе пусть будет некоторый GUI
Значит наша схема выглядит как [пакеты с сетевой платы -> черный ящик -> экран].
Пойдем слева направо.
Для перехвата пакетов нам нужен драйвер и некоторый user mode api для работы.
[драйвер -> api -> черный ящик -> экран]
далее все пакеты выводить не надо, надо их по правилам фильтровать
[драйвер -> api -> фильтр пакетов -> черный ящик -> экран]
далее становится ясно что фильтры надо как-то задавать и хранить, у нас получается два dataflow
[драйвер -> api -> фильтр пакетов -> черный ящик -> экран]
[хранилище фильтров -> другой черный ящик -> фильтры] (и наоборот кстати)
Далее пусть GUI ну нас будет просто консолькой, а фильтры будут в конфиге
[драйвер -> api -> фильтр пакетов -> форматер пактов -> экран]
[конфиг -> парсер конфига -> фильтры] (один раз при загрузке)
Далее выбираем технические средства.
Например я пишу на .NET, там уже есть инструментарий для конфигов, для разбирания возьму WinPCAP, он же осуществляет фильтрацию
Получается так:
[.NET обертка для WinPCAP -> форматер пактов -> экран]
[кастомная секция конфига -> фильтр для WinPCAP]
.NET обертка уже есть http://pcapdotnet.codeplex.com/
В итоге остается сделать только секцию конфига, преобразование её в фильтр, и написать форматтер.
Но такое можно за час сделать, попробуем ченить поинтереснее придумать.
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, licedey, Вы писали:
L>>Отвечу коротко, уж извините Есть такого рода MediaSniffer. L>>Но он парсит только видео по расширению от 'GET' ответа. Использует WinPcap либу. М>что хорошо укладывается в предложенную мной модель. если достаточно парсинга GET, ограничиваемся модулем HTTP и в HTML не лезем. в принципе, с некоторым риском можно парсить "сырой" поток минуя IP и TCP по регуляркам, т.к. скорее всего GET будет целиком в одном пакете. как сырое и быстрое решение для набора статистики "какой гад смотрит видео" оно вполне прокатит (ведь никто же не будет устанавливать TCP-тоннель, кладующий в пакет по одному байту).
Задача — выявлять прямые ссылки на видео, для скачивания.
М>но тут все зависит от задачи. если мы парсим HTML, то можно вытянуть не только линк на видео, но и название клипа. одно дело если человек смотрит лекцию от гугла по распределенной файловой системе и совсем другое если это "видеоприколы" или порно. а многие порносайты используют обфускацию для обхода фаеров. там вообще очень интересная схема, где задействуется reverse dns как средство передачи актуального линка. и GET'а не будет. не, ну то есть он будет конечно, но там будет GET на случайное доменное имя и случайный ID. такие доменные имена живут не больше недели, что сильно затрудняет их блокировку и чтобы их все-таки заблокировать нужно распарсить еще и dns.
В requirements такого не было. Можно еще оффтопика? Вы четко следуете требованиям к заданию? Если требуется по пунктно, но общее решение вы знаете лучше — сделаете по своему? (Я бы тему создал, но вашего ответа будет достаточно. Я часто замыкаюсь на задании в мельчайших подробностях, при этом общаяя картина часто уплывает, и получается 30 часов "как видит заказчик", вместо 10 — как вижу решение я).
>> Также заданием было определять нужный адаптер автоматически, этим занимался NetworkAdapter >> (делая пинг и какой адаптер словит — тот и активный). М>что значит "активный"? у меня, например, три адаптера. два физических и один виртуальный. и все активные. но смотрят в разные сети. и при заходе на ms.com траффик идет через один, а при заходе на юутб -- через другой. а при заходе на произвольный сайт -- хз. нужно смотреть как марштутизация прописана.
Интернет-активный. Я в курсе что у вас 6 компов и 10 сетевух. Но для общего случая пинг и отзыв для определения адаптера, который ловит инет — думаю достаточно. Ну и задание большего не требовало.
L>> В вашем комментарии одно задело, "за 30 минут с учетом поиска". М>именно столько нужно, чтобы взять готовые либы и собрать их. на выходе мы будет иметь разобранный HTTP трафик с поддержкой всех кодов ответа и остальных полей.
Скилсы, скилсы...мне как написали — так и делал.
>> На чтение спецификации только и копания сырцов медисниффера, только день ушел. М>это потому что вы взяли неправильный открытый проект. я использовал вот это: http://code.google.com/p/pypcap/ М>не самая лучшая библиотека, но на первой странице гугла. глубже искать было лениво.
>> И то в режиме "дым из попы". Потом на детект адаптера день, попутно изучив тонкости WinPcap. М>а обязательно именно winpcap? линух заюзать не проще было бы? там этих тонкостей меньше. хотя если вы никогда ранее не сталкивались с такой задачей -
— тогда, конечно, совсем другое дело.
Да, все упирается в требования. Заказчик на 5 страницах описал, как он видит задачу и решение. Я максимально старался им следовать. Решение оптимально с точки зрения как просили. Это блин, вроде говорить хирургу, где резать, что-ле...Ну я сам себе начальник, поэтому личные отношения ставлю выше...
М>поскольку, задачи грабежа, парсинга, анализа трафика и визуализации результатов анализа совершенно незавимые, то ООП тут никаким боком. предлгаю -- грабеж делать на базе tcpdump, парсинг -- на питоне, результат ложить в базу данных типа мускуля, через механизм сообщений (выдранный из апача) дергать модуль на руби, который извлечет данные и их проанализирует, записав в другую базу, а визуализация -- это веб-интерфейс на жаба.
Это зоопарк какой-то? Ну сделаете вы на питоне, tcpdump — это обертка над Си-шной pcap либой, база данных в моем случае не нужна, только ловить ссылки на видео. Даже если вы это реализуете, круто так, то сопровождать вам же. Станете рабом проекта.
М>какой смысл писать все на си++ ? и задача декомпозиции ну никак не сводится к трем упомянутыми вами компонентам. поскольку, мало распарсить трафик, нужно проанализировать результат и где-то его сохранить. если трафика немного, то можно ограничится хэш-массивами. а вот если трафика сильно до фига, то правильный выбор базы данных -- это отельная задача, не говоря уже за проектирование самой структуры этой базы.
Распарсил, вывел ссылку в окошко. И вся задача
М>и, кстати, вы не ответили на мой коренной вопрос -- чем отличается класс от модуля? в смысле чем он отличается в вашей схеме.
Модуль у меня в первую очередь ассоциируется с файлом. Файл кода = модуль, который другие файлы могут использовать. В модуле могут быть несколько классов, любых абстракций. Например модуль Sniffer, может содержать классы Parser, Listner, функции Init, Finish...Т.е. модуль — это более осязаемое,
чем класс. Класс — задает правила, модуль — их расширяет. Если в глубоком смысле.
М>в общем, не вижу я здесь ООП.
В моей практике, большая часть задач не требует ООП. Просто бери и пиши (фриланс). Однако я следуя советам и опыту старших коллег, в свое время довольно увлекся ООП дизайном, анализом, UML, паттернами. Что-то декомпозировать — пожалуйста! Найду закономерность в 2-х несвязных сущностях. Решить задачу — на втором месте. А мне еще рано до архитектора...
Здравствуйте, gandjustas, Вы писали:
G>2) Сами принципы крайне туманны и не дают критерия соответствия принципам. То есть ты по коду не можешь объективно утверждать выполняется ли тот или иной принцип (за редким исключением). G>http://gandjustas.blogspot.com/2011/08/solid.html G>тут подробно свой взгляд описал. Предупреждаю, он сильно не соответствует тому что можно в интернетах прочитать.
помоему вы просто ниасилили
(впрочем в том посте так и написано)
Здравствуйте, licedey, Вы писали:
L>Здравствуйте, мыщъх, Вы писали:
L>Задача — выявлять прямые ссылки на видео, для скачивания.
пишется регулярками за несколько минут. можно и без регулярок на ansi c минут за десять. в принципе, парсинг промежуточных протоколов необязателен. ну на крайний случай можно сделать быструю проверку на TCP заголовок с проверкой порта.
а поставить Snort чем не вариант? он HTTP распарсит. и там даже flow сигнатуры есть. т.е. можно связать GET с ответом сервера. и есть сигнатуры для видеоконтента. уже написанные и готовые. под все мыслимые видеформаты. берем и пишем правило -- если в ответ на GET мы получили видео, то генерируем алерт такой-то.
L> В requirements такого не было. Можно еще оффтопика?
я ж не знаю ваших requirements. вам чтобы формальности были соблюдены или чтобы работало? вы упомянули лишь только 80 порт. какая-то расплывчатая формулировка. "я все чаще замечаю" (с) кот матроскин, что urlы пишутся с указанием нестандартных портов и юзер даже не в курсе, ибо для него это просто ссылка, которую нужно щелкнуть.
L> Вы четко следуете требованиям к заданию?
у меня нет опыта написания программ под заказ с целью "за отвалите вы от меня на три хвоста, как написато в ТЗ, так и работает".
> Если требуется по пунктно, но общее решение вы знаете лучше — сделаете по своему? > Я бы тему создал, но вашего ответа будет достаточно.
буду делать так, чтобы работало. писать то, что работать не будет -- смысла не вижу никакого. и нужно намного больше деталей. т.к. если у клиента прокси, то универсальее всего написать на icap. если прокси нет, то ограничиваться одним лишь HTTP недостаточно, т.к. народ активно смотрит потоковое видео в макромедиа флэш формате, а это 1935 порт по умолчанию (пишу по памяти, могу соврать). а что на счет вебок? там же тоже далеко не 80 порт и даже не TCP. и ссылок никаких нет. а трафик нагоняют здорово.
если нужен только вывод ссылок в окошко, то готовый пример гуглиться за несколько минут. после чего останется только доработать его, чтобы он выводил ссылки только на видео, но такое решение ни фига не работает.
> Я часто замыкаюсь на задании в мельчайших подробностях, при этом общаяя картина часто > уплывает, и получается 30 часов "как видит заказчик", вместо 10 — как вижу решение я
подробности прорабатываются по месту. сначала нужно решить концептуальные вопросы. например, на чем это вообще писать. хотите писать на си -- ваше право, но сможете ли вы это обосновать? вдруг у вас там буфер переполнится? и выяснится, что установка такого анализатора -- это бэкдор. а чтобы бэкдора не было, значит, или брать жабу (или на худой конец питона) или сразу писать отказ от всякой ответственности. гигабитный трафик спокойно обрабатывается питоном. а вот сто гигабит уже требуют ручной оптимизации и низкоуровневых языков. кстати, даже на 100 мегабит без быстрой базы данных никуда.
L> Интернет-активный. Я в курсе что у вас 6 компов и 10 сетевух. Но для общего случая пинг L> и отзыв для определения адаптера, который ловит инет — думаю достаточно. Ну и задание большего не требовало.
грабить трафик можно кучей программ как под винду, так и под линух. и они сами разбираются какой интернет активный. если у меня на ноуте включить wifi и езернет, то работают сразу два. причем по умолчанию они работают параллельно, и при скачке большого файла он льется сразу через два. wireshark с ума сходит.
> Я максимально старался им следовать.
конечно, когда есть ТЗ, то от него можно плясать. но тогда непонятно к чему все разговоры за возможные подходы к решению задачи, если уже есть подробное описание того, что нужно делать?
L> Это зоопарк какой-то?
зоопарк, согласен. но оно как-то универсальнее выходит. быстрее, надежнее, дешевле, безопаснее. и четкое разделение на независимые уровни, которые вообще можно реализовать на разных осях. и на выходе все-таки база данных, а не просто окошко с ссылками. потому как заказчику определенно нужна хистори, гибкая выборка ну и ответная рекация -- типа генерации правил для фаера, чтобы заблокировать это видео на хрен.
> Даже если вы это реализуете, круто так, то сопровождать вам же. Станете рабом проекта.
а вы предлагаете отливать монолит из гранита? а потом выяснится, что на некоторых чипсетах сниффер теряет пакеты. причем теряет их много. и нужно ставить патчи. в смысле это мне их ставить нужно. более того, если я не дурак, то посмотрю какие платформы сертифицированы под грабеж трафика на tcpdump и если обнаружится пропажа пакетов (а она обнаружится), то буду лениво пинать поддержку софта и харда, закачик -- в cc и видит, что "мы работаем над этим". а если у вас монолит и пакеты теряются потому что драйвер на карту имеет баг и вендор его не фиксит, т.к. не подряжался на этой платформе сниффать траффик -- что вы будете делать?
если это не утилита за $30, то проще отдать заказчику готовый комплес в котором стоит железо и ось, выбранное с учетом специфики решаемой задачи (в данном конкретном случае, производитель железа гарантирует, что конкретный драйвер на конкетной оси гарантированно грабит трафик без проблем). исчезает сразу куча проблем. берешь коробку, втыкаешь в стойку, подключаешь питание и езернет и -- вуаля!!! оно работает через web-интерфейс и там внутри база данных, которая так же доступа удаленно. заказчик кипятком ссыт от восторга.
инсталлятор писать и тестировать его на совместимость всяко дольше, чем запихать все внутрь. ладно, пусть железо мы поставить не можем. и не надо! пошлем закзчику iso образ, который гарантированно работает под vm ware, чем решаем кучу пробем.
L> Распарсил, вывел ссылку в окошко. И вся задача
а если в окошке Over 9000 ссылок? что будет с ними делать заказчик? а как хранить историю? как делать выборку за последний час, день, месяц? как делать выборку по доменам? типа куда народ ходит больше всего и кто наш самый главный враг и убийца рабочего времени. какой локальный IP потребляет больше всех? (а тут нужно еще и ARP парсить, чтобы MAC определить или как-то еще).
опять-таки. берем wireshark. пишет дебильно простое правило поиска за три минуты. и он выводи в окошке только get'ы на видео. причем, у шарка еще и интерфейс продвинутый. и он работает на любой платформе. и обновляется по мере выхода новых версий винды. чем вам не решение?
L>Модуль у меня в первую очередь ассоциируется с файлом.
в исходных текстах модуль обычно реализуется множеством файлов. как минимум должен быть cpp/c и h.
в библиотеках в lib можно запихать в один файл 100500 модулей и линкер сам разберется какой из них вытаскивать.
> Файл кода = модуль, который другие файлы могут использовать.
давайте все-таки плясать от того, что модуль это концептуально законченный фрагмент программы типа черный ящик с документированным интерфейсом и недокументированной внутренней архитектурой.
> В модуле могут быть несколько классов, любых абстракций. Например модуль Sniffer, > может содержать классы Parser, Listner, функции Init, Finish...Т.е. модуль — это более осязаемое,
а какое отношение имеет сниффер к парсеру? сниффер снифает трафик. парсер -- парсит. причем, парсер может (и должен!) работать не только с сетевым адаптером, но и с pcap файлами, а их можно генерировать и самому. что, кстати, полезно для тестирования. как вы будете тестировать монолитный сниффер, совмещенный с парсером? вот я хочу подать ему на вход разный мусор, сгенерированный фаззерами с целью его завалить.
L> В моей практике, большая часть задач не требует ООП. Просто бери и пиши (фриланс).
вот и я говорю, что не требует.
> Однако я следуя советам и опыту старших коллег, > в свое время довольно увлекся ООП дизайном, анализом, UML, паттернами.
странные у вас коллеги, если в результате увлечения вы видите парсер частью сниффера. они даже работают с разными объектами. это издевательство над ООП. ну вот смотрите.
а что получается у вас: адаптер->парсить();
интересно как можно распарсить адаптер
как раз на чистом си можно запихать в один модуль разные сущности -- он все стерпит. а вот ООП визжит и сопротивляется. никак парсер не ложится в том же класс, что и сниффер. разве что сделать супер класс "программа" с методами "грабить трафик" и "парсить трафик". но в этом случае у нас будет только один класс. а один класс это не ООП
> Что-то декомпозировать — пожалуйста! Найду закономерность в 2-х несвязных сущностях. > Решить задачу — на втором месте. А мне еще рано до архитектора...
мне, кстати, тоже рано быть архитектором и архитектором у нас работает очень умный дядька, который образно говоря проектирует самолеты, а я создаю для них движки. на уровне движка я с архитектурой еще справляюсь, но вот всю инфраструктуру самолета разработать не могу, а если даже и разработаю, то этот самолет вряд ли оторвется от земли.
причем это даже походе не отсутствие опыта, а особенность мышления. я мыслю на микро-уровне. например, как задетектить неизвестную ранее малварь. и у меня на выходе получается программа с вводом/выводом, считывающая с диска файл и возвращающая результат. но это не продукт. это только малая его часть. причем, она реальна малая -- несколько тысяч строк, которые по большой нужде можно и с нуля переписать. а весь комплекс это сотни тысяч строк и куча модулей. такой уровень я не тяну.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, licedey, Вы писали:
G>далее все пакеты выводить не надо, надо их по правилам фильтровать G>[драйвер -> api -> фильтр пакетов -> черный ящик -> экран]
вот тут не согласен. тут все-таки не фильтр, а нечто более сложное. как миниум нужен ассемблер TCP. далее фильтровать HTTP не получится, т.к. нужно ловить GET и соответствующий ему ответ сервера (с поддержкой редиректов).
опять же -- нет прямых указаний, что это должен быть драйвер. это может быть и плагин для прокси, что избавит нас от необходимости сборки TCP и декодирования HTTP. а собирать TCP и держать сессии в памяти -- памяти не хватит. и мы неизбежно возвращаемся к необходимости базы данных. причем, быстрой.
с другой стороны -- все это уже написано. главное, знать, что заюзать. путем несложных умозаключений мы приходим к выводу, что нам подойдет любая нормальная IDS/IPS и нам останется только написать свои правила, которые пишутся на довольно простом языке.
написать нормальный ассемблер TCP -- это же сдохнуть можно. и HTTP тоже не прост.
G>[драйвер -> api -> фильтр пакетов -> форматер пактов -> экран] G>[конфиг -> парсер конфига -> фильтры] (один раз при загрузке)
тут упущена одна важная детать. если захардокдить логику фильтрации -- то при всяком внесении изменений -- перекомпилировать всю программу. если же вынести ее в конфиг, то это не просто конфиг будет, а очень продвинутый конфиг, т.к. нам нужно описывать довольно нетривальную логику, связывающую GET и ответ сервера. тут могут быть и поля типа контент и детекция формата возвращаемых сервером данных... короче, нам нужен скриптовый язык по любому.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, Lloyd, Вы писали:
L>И примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель.
С этим я абсолютно согласен. Я не согласен с приведенным тобой доказательством. И пост написал просто потому, что ты, всегда педантично относящийся к законам логики, так грубо их нарушаешь.
Здравствуйте, samius, Вы писали:
S>И кроме этого, я считаю что POJO и anemic — совершенно разные вещи.
Хм... Век живи век учись Оказалось, что да, POJO не такие уж простые DTO, которые рекомендует anemic. Не знал.
И да, я согласен, что anemic это шаг в сторону от OOP и не согласен, что это ужасно. Особенно сейчас, когда процедурный подход все больше превращается в функциональный в мейнстрим языках.
Офтопик
Вставлю свои 5 копеек про рич и анемик: раньше я много копий ломал про них в архитектуре, сейчас надоело.
Самый простой и наглядный БЛ код работающий с БД, который мне доводилось писать и читать это ActiveRecord в руби. Он же и максимально оопшный (контроллер и бизнес объекты обмениваются сообщениями). И если производительность устраивает, я считаю, что можно спокойно положить на SRP и писать читаемый код так как удобно. И плевать с потолка на все абстракции от хранилища, ибо те же транзакции это чистая бизнес логика.
Тот же анемик довольно хорош, чтобы обеспечить достойную производительность. Но тоже имеет свои недостатки, на которые можно спокойно плевать, если на данный момент производительность важна.
Прекрасно работают оба подхода. Реальная разница только одна: в рич трудно писать производительный код, в анемик краткий и понятный код бизнес сценариев.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали:
L>>С удовольствием почитаю. Но раз уж вы его рекомендуете, то вам несомненно не составит труда привести цитату автора, опровергающую формулировку из википедии. S>Для начала можно взять более вменяемую формулировку из той же Википедии: S>
S>В центре ООП находится понятие объекта. Объект — это сущность которой можно посылать сообщения, и которая может на них реагировать, используя свои данные. Данные объекта скрыты от остальной программы
Не, раз уж взялись аппелировать к авторитету, так уж будьте добры приводить ссылки на авторитет, а не на википедию. Ведь согласно вашей формулировке там "чушь".
L>>Факт 1: применение ООП (по википедии) приводит к " бесплодным спорам". L>>Факт 2: моделирование от поведения приводит к правильному ответу. L>>Вывод: ООП — целиком про поведение.
L>>Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан. S>Меня просто утомляет каждый раз приводить эту, достаточно банальную, цепочку аргументов, всякий раз,
Да, это аргумент — "Утомляет" и переходн на личности.
S>как в форум прибегает очередной знаток ООП, начитавшийся Авторитетов.
Это вы про Алана Кея?
L>>А так да, я согласен, "имеет смысл применять критическое мышление", причем прежде всего имеет смысл применять его к себе же. S>Ну так я его к себе и применил. Я ООП начал изучать ещё по Turbo Pascal 6.0, примерно 20 лет назад.
не впеяатляет, ибо я и сам немногим позже начал его изучать, причем по тем же технологиям.
S>И все заблуждения, упорно насаждаемые недалёкими объясняльщиками, я честно разделял. Ровно до тех пор, пока не накопилась критическая масса фактов, противоречащих большинству мифов об ООП. Ну там, типа — "в ООП производится моделирование объектов предметной области при помощи экземпляров классов" и прочего. S>Помимо мифов, существует также некоторое количество малоконструктивных подходов. В их числе и попытки моделировать иерархию классов, исходя из структуры данных. Несмотря на то, что иногда этот подход даёт более-менее приемлемые результаты, в целом он значительно чаще оставляет программиста наедине с неразрешимыми в рамках этого подхода вопросами.
Только вот вывод вы из этого неправильный сделали. Ошибка — не в определении ООП как "моделирование объектов предметной области при помощи экземпляров классов", а в использовании ООП для "моделирования объектов предметной области".
Здравствуйте, Ziaw, Вы писали:
Z>Доказательства того, что DDD и anemic несовместимы здесь нет. Есть доказательство совместимости с rich model, при этом, возможна совместимость и с anemic. Основной постулат DDD — максимальное приближение модели данных к естественным сущностям в бизнесе. Я совершенно не понимаю хайпа вокруг этой аббревиатуры.
Что-то на этом пункте я завис. А в чем отличие "rich model" от "максимальное приближение модели данных к естественным сущностям в бизнесе"?
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, licedey, Вы писали:
G>>далее все пакеты выводить не надо, надо их по правилам фильтровать G>>[драйвер -> api -> фильтр пакетов -> черный ящик -> экран] М>вот тут не согласен. тут все-таки не фильтр, а нечто более сложное. как миниум нужен ассемблер TCP. далее фильтровать HTTP не получится, т.к. нужно ловить GET и соответствующий ему ответ сервера (с поддержкой редиректов).
М>опять же -- нет прямых указаний, что это должен быть драйвер. это может быть и плагин для прокси, что избавит нас от необходимости сборки TCP и декодирования HTTP. а собирать TCP и держать сессии в памяти -- памяти не хватит. и мы неизбежно возвращаемся к необходимости базы данных. причем, быстрой.
Сорри, я не следил за дискуссией по поводу сниффера, просто вывалил поток мыслей как дизайнить подобное приложение. Не учел те кейсы, которые вы рассматривали.
G>Сорри, я не следил за дискуссией по поводу сниффера, просто вывалил поток мыслей как дизайнить подобное приложение. Не учел те кейсы, которые вы рассматривали.
дело в том, что если писать это по уму, то это мегапроект. фактически мы должны повторить TCP стек. а ведь ни один вендор -- ни в никсах, ни в винде, не избежал кучи ошибок. а ведь нам нужно не просто собрать TCP и поднять до уровня HTTP, но еще и отслеживать сессии, чтобы было ясно какой ответ HTTP сервера какому HTTP запросу соответствует и с какого MAC адреса он пришел.
допустим, у нас гигабит канал (в реальности у клиента может быть совокупный траффик и до ста гигабит), но даже с гигабитом -- при таймауте в несколько минут (а меньше ставить нельзя) на 32-битах в памть оно физически не влезет. на 64-битах ситуация проще, но тоже будут проблемы. так что нужна база данных. причем шустрая и отзычивая.
но дело даже не в этом. снифферов то ведь нету. даже на энтерпрйз маркете где только сертифицированные оси (никсы, конечно), которые сертифицированны на данном конктетном железе под конкетную задачу -- сниффать траффик конкретной програмой tcpdump куча пробелем. 10% потери пакетов -- это реальность. и это при том, что поддержка энерпрайзных никсов и железа на уровне. но... они же там не боги. вылизали 32 бита. а вот 64 бита все еще сосут.
благо, у ТС не IDS и ему потеря пакетов не страшна. но использовать wincap это безумие однозначно. оно же работает только по большим праздникам. хотя зависит от задачи... потеря пакетов возникает когда загружен ЦП и когда трафик реально валит как дым из трубы.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, Lloyd, Вы писали:
Z>>Доказательства того, что DDD и anemic несовместимы здесь нет. Есть доказательство совместимости с rich model, при этом, возможна совместимость и с anemic. Основной постулат DDD — максимальное приближение модели данных к естественным сущностям в бизнесе. Я совершенно не понимаю хайпа вокруг этой аббревиатуры.
L>Что-то на этом пункте я завис. А в чем отличие "rich model" от "максимальное приближение модели данных к естественным сущностям в бизнесе"?
рич модель это вариант реализации, а ДДД это вобщем то методология
Здравствуйте, Ikemefula, Вы писали:
L>>Что-то на этом пункте я завис. А в чем отличие "rich model" от "максимальное приближение модели данных к естественным сущностям в бизнесе"?
I>рич модель это вариант реализации, а ДДД это вобщем то методология
С фига ли?! Открой Эванса и убедись, что ДДД — это в том числе и архитектура.
Здравствуйте, Lloyd, Вы писали:
I>>рич модель это вариант реализации, а ДДД это вобщем то методология
L>С фига ли?! Открой Эванса и убедись, что ДДД — это в том числе и архитектура.
Так у Эванса это и написано, что ДДД это сначала методология Про модель он говорит, что нет готового решения, надо пилить, пилить а потом дистилировать.
Будь ДДД архитектурой, достаточно вместо книги накидать пару примеров и сказать что де надо делать вот так.
Здравствуйте, Ikemefula, Вы писали:
L>>С фига ли?! Открой Эванса и убедись, что ДДД — это в том числе и архитектура.
I>Так у Эванса это и написано, что ДДД это сначала методология Про модель он говорит, что нет готового решения, надо пилить, пилить а потом дистилировать.
А ты точно Эванса открывал? У него описанию этого готового решения, которого якобы нет, отводит места больше, чем на методологию.
I>Будь ДДД архитектурой, достаточно вместо книги накидать пару примеров и сказать что де надо делать вот так.
Здравствуйте, Lloyd, Вы писали:
I>>Так у Эванса это и написано, что ДДД это сначала методология Про модель он говорит, что нет готового решения, надо пилить, пилить а потом дистилировать.
L>А ты точно Эванса открывал? У него описанию этого готового решения, которого якобы нет, отводит места больше, чем на методологию.
Главы с 1й до 7й это описание методологии, а не конкретных решений. Да и в последующих главах хватает описания именно методологии.
Естесвтенно, ДДД как методология ни разу не всеохватывающая, как XP и тд.
Здравствуйте, Ikemefula, Вы писали:
L>>А ты точно Эванса открывал? У него описанию этого готового решения, которого якобы нет, отводит места больше, чем на методологию.
I>Главы с 1й до 7й это описание методологии, а не конкретных решений. Да и в последующих главах хватает описания именно методологии.
Зачем вы обманываете? С 4-й по 7-ю главы идет описание архитектуры (7-я пример).
Здравствуйте, Lloyd, Вы писали:
L>>>А ты точно Эванса открывал? У него описанию этого готового решения, которого якобы нет, отводит места больше, чем на методологию. I>>Главы с 1й до 7й это описание методологии, а не конкретных решений. Да и в последующих главах хватает описания именно методологии.
L>Зачем вы обманываете? С 4-й по 7-ю главы идет описание архитектуры (7-я пример).
Зачем ты обманываешь ?
С 1й по 7ю идет описание подхода к построению архитектуры Разумеется на конкретном примере. Читай внимательно его советы и рекомендации, что делать и что не делать. Это не похоже на архитектуру
Здравствуйте, Ikemefula, Вы писали:
I>>>Главы с 1й до 7й это описание методологии, а не конкретных решений. Да и в последующих главах хватает описания именно методологии.
L>>Зачем вы обманываете? С 4-й по 7-ю главы идет описание архитектуры (7-я пример).
I>Зачем ты обманываешь ?
I>С 1й по 7ю идет описание подхода к построению архитектуры
Пошла игра словами? Ок, не возражаю.
Не можешь прояснить, в чем отличие архитектуры и подхода к построению архитектуры? Решение о размещении бизнес-логики в энтитях — это архитектура, или подход к ней.
I>Разумеется на конкретном примере.
Не, конкретных решение там нет. Сам Ikemefula об этом писал 2 поста назад, он в теме.
I>Читай внимательно его советы и рекомендации, что делать и что не делать. Это не похоже на архитектуру
L>Не можешь прояснить, в чем отличие архитектуры и подхода к построению архитектуры? Решение о размещении бизнес-логики в энтитях — это архитектура, или подход к ней.
Он нигде не говорит о необходимости размещать БЛ в энтитях.
I>>Читай внимательно его советы и рекомендации, что делать и что не делать. Это не похоже на архитектуру
L>У меня для тебя плохие новости.
Т.е. когда он говорит, что модель надо дистилировать, проговаривать, рефакторить денно и нощно — в этом тебе видится конкретная ДДД-архитектура ? Я правильно тебя понял ?
Здравствуйте, Ikemefula, Вы писали:
L>>Не можешь прояснить, в чем отличие архитектуры и подхода к построению архитектуры? Решение о размещении бизнес-логики в энтитях — это архитектура, или подход к ней.
Если ты не заметил, тут был знак вопроса.
I>Он нигде не говорит о необходимости размещать БЛ в энтитях.
Он описал кейсы, когда бизнес-логика попадает в сервисы. Следовательно в остальных кейсах эта логика располагается где-то еще. Единственное место, которое мне приходит в голову — это энтити.
Возможно я ошибаюсь, поправьте меня, если это так и расскажите, где еще может быть расположена логика кроме сервисов и энтитей.
I>>>Читай внимательно его советы и рекомендации, что делать и что не делать. Это не похоже на архитектуру
L>>У меня для тебя плохие новости.
I>Т.е. когда он говорит, что модель надо дистилировать, проговаривать, рефакторить денно и нощно — в этом тебе видится конкретная ДДД-архитектура ? Я правильно тебя понял ?
Простмотри хотя бы заголовки глав с 4-й по 7-ю. Разговоры про "дистилировать, проговаривать, рефакторить" — либо перед этими главами, либо после.
Здравствуйте, Lloyd, Вы писали:
L>>>Не можешь прояснить, в чем отличие архитектуры и подхода к построению архитектуры? Решение о размещении бизнес-логики в энтитях — это архитектура, или подход к ней.
L>Если ты не заметил, тут был знак вопроса.
I>>Он нигде не говорит о необходимости размещать БЛ в энтитях.
Если ты незаметил, это ответ на твой вопрос.
L>Он описал кейсы, когда бизнес-логика попадает в сервисы. Следовательно в остальных кейсах эта логика располагается где-то еще. Единственное место, которое мне приходит в голову — это энтити.
Он показывает рассуждения о том как нужно строить архитектуру. А если в конкретном варианте это попало в сервисы — дело десятое.
I>>Т.е. когда он говорит, что модель надо дистилировать, проговаривать, рефакторить денно и нощно — в этом тебе видится конкретная ДДД-архитектура ? Я правильно тебя понял ?
L>Простмотри хотя бы заголовки глав с 4-й по 7-ю. Разговоры про "дистилировать, проговаривать, рефакторить" — либо перед этими главами, либо после.
Похоже, ты читал только заголовки Под рукой у меня нет книги, а дома есть книга но нет компа, что бы процитировать. Как быть ?
Здравствуйте, Ikemefula, Вы писали:
L>>>>Не можешь прояснить, в чем отличие архитектуры и подхода к построению архитектуры? Решение о размещении бизнес-логики в энтитях — это архитектура, или подход к ней.
L>>Если ты не заметил, тут был знак вопроса.
I>>>Он нигде не говорит о необходимости размещать БЛ в энтитях.
I>Если ты незаметил, это ответ на твой вопрос.
Нет, это не ответ на вопрос "в чем отличие архитектуры и подхода к построению архитектуры".
L>>Он описал кейсы, когда бизнес-логика попадает в сервисы. Следовательно в остальных кейсах эта логика располагается где-то еще. Единственное место, которое мне приходит в голову — это энтити.
I>Он показывает рассуждения о том как нужно строить архитектуру. А если в конкретном варианте это попало в сервисы — дело десятое.
Он описывает, какого рода операции попадают в сервисы. Ответ на вопрос о том, куда попадают остальные операции, лежит на поверхности.
I>>>Т.е. когда он говорит, что модель надо дистилировать, проговаривать, рефакторить денно и нощно — в этом тебе видится конкретная ДДД-архитектура ? Я правильно тебя понял ?
L>>Простмотри хотя бы заголовки глав с 4-й по 7-ю. Разговоры про "дистилировать, проговаривать, рефакторить" — либо перед этими главами, либо после.
I>Похоже, ты читал только заголовки
Похоже, ты знаком с содержанием только по слухам, раз не заметил полкниги.
I>Под рукой у меня нет книги, а дома есть книга но нет компа, что бы процитировать. Как быть ?
Здравствуйте, Lloyd, Вы писали:
I>>>>Он нигде не говорит о необходимости размещать БЛ в энтитях.
I>>Если ты незаметил, это ответ на твой вопрос.
L>Нет, это не ответ на вопрос "в чем отличие архитектуры и подхода к построению архитектуры".
Разница в рекомендациях которые дает автор. Если Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)" то конечно он описывает архитектуру. А если вместо этого говорит о том, как прийти к конкретной модели, как модель влияет на дизайн, талдычит про язык, рефакторинг и тд, то речь о подходе.
I>>Он показывает рассуждения о том как нужно строить архитектуру. А если в конкретном варианте это попало в сервисы — дело десятое. L>Он описывает, какого рода операции попадают в сервисы. Ответ на вопрос о том, куда попадают остальные операции, лежит на поверхности.
Он говорит про подход
I>>Похоже, ты читал только заголовки L>Похоже, ты знаком с содержанием только по слухам, раз не заметил полкниги.
Важные вещи я читаю дважды а то и трижды Сам Эванс не считает ДДД методологией и его можно понять, в ДДД нет ничего про планирование и управление. Тем не менее это методология разработки архитектуры. Т.е. методология как подход, а не аналог таких вещей как XP, Scrum и тд.
Теперь вопрос, раз ты читал эту книгу, можно ли архитектуру определить как "a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains. " ?
Хочу получить простой ответ, вроде да — можно, нет — нельзя.
I>>Под рукой у меня нет книги, а дома есть книга но нет компа, что бы процитировать. Как быть ?
L>rutracker.org в помощь.
дай ссылку на всю книгу, у меня нет доступа к этому ресурсу.
Здравствуйте, Ikemefula, Вы писали:
L>>Нет, это не ответ на вопрос "в чем отличие архитектуры и подхода к построению архитектуры".
I>Разница в рекомендациях которые дает автор. Если Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)" то конечно он описывает архитектуру. А если вместо этого говорит о том, как прийти к конкретной модели, как модель влияет на дизайн, талдычит про язык, рефакторинг и тд, то речь о подходе.
I>>>Он показывает рассуждения о том как нужно строить архитектуру. А если в конкретном варианте это попало в сервисы — дело десятое. L>>Он описывает, какого рода операции попадают в сервисы. Ответ на вопрос о том, куда попадают остальные операции, лежит на поверхности.
I>Он говорит про подход
Вы меня прям в рекурсию загоняете. Двумя строчками было "размещать БЛ надо в сервисах" — это архитектура, теперь то же самое — подход.
Хм, надеюсь, что дело все-таки в лыжах, а не во мне.
I>>>Похоже, ты читал только заголовки L>>Похоже, ты знаком с содержанием только по слухам, раз не заметил полкниги.
I>Важные вещи я читаю дважды а то и трижды Сам Эванс не считает ДДД методологией и его можно понять, в ДДД нет ничего про планирование и управление. Тем не менее это методология разработки архитектуры. Т.е. методология как подход, а не аналог таких вещей как XP, Scrum и тд.
Зачем ты это раз за разом повторяешь? Я где-то оспаривал это утверждение? Вроде нет.
Мой поинт лишь в том, что это не только методология, но и вполне себе архитектура, одним из пунктов которой является rich-ность модели.
I>Теперь вопрос, раз ты читал эту книгу, можно ли архитектуру определить как "a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains. " ?
I>Хочу получить простой ответ, вроде да — можно, нет — нельзя.
Извини, но это out-of-scope того, что обсуждается. Если хочешь, создавай отдельную тему, но участвовать в ней я не буду.
L>>rutracker.org в помощь.
I>дай ссылку на всю книгу, у меня нет доступа к этому ресурсу.
Здравствуйте, Lloyd, Вы писали:
L>Вы меня прям в рекурсию загоняете. Двумя строчками было "размещать БЛ надо в сервисах" — это архитектура, теперь то же самое — подход.
А дай ка ссылку, где я писал вроде "Эванс пишет 'размещать БЛ надо в сервисах'" ?
I>>Важные вещи я читаю дважды а то и трижды Сам Эванс не считает ДДД методологией и его можно понять, в ДДД нет ничего про планирование и управление. Тем не менее это методология разработки архитектуры. Т.е. методология как подход, а не аналог таких вещей как XP, Scrum и тд.
L>Зачем ты это раз за разом повторяешь? Я где-то оспаривал это утверждение? Вроде нет. L>Мой поинт лишь в том, что это не только методология, но и вполне себе архитектура, одним из пунктов которой является rich-ность модели.
Астролябия, как модель звездного неба, это рич или анемик ? Эванс говорит, что если нарисовалась модель, то надо сделать её как следует и для этого выдает кучу рекомендаций, приоритеторв и тд и тд.
I>>Теперь вопрос, раз ты читал эту книгу, можно ли архитектуру определить как "a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains. " ?
I>>Хочу получить простой ответ, вроде да — можно, нет — нельзя.
L>Извини, но это out-of-scope того, что обсуждается. Если хочешь, создавай отдельную тему, но участвовать в ней я не буду.
Это слова Эванса непосредственно относящиеся к его книге и ДДД. Фраза однозначно разрешает вопрос архитектура ДДД или нет.
I>>дай ссылку на всю книгу, у меня нет доступа к этому ресурсу.
L>Она и так гуглится, без торрента.
см выше, надобность в книге отпадает, если ты возьмёшься прочесть определение Эванса, что же такое ДДД.
Здравствуйте, Ikemefula, Вы писали:
L>>Вы меня прям в рекурсию загоняете. Двумя строчками было "размещать БЛ надо в сервисах" — это архитектура, теперь то же самое — подход.
I>А дай ка ссылку, где я писал вроде "Эванс пишет 'размещать БЛ надо в сервисах'" ?
rsdn.ru/forum/philosophy/4434550.1.aspx
L>>Зачем ты это раз за разом повторяешь? Я где-то оспаривал это утверждение? Вроде нет. L>>Мой поинт лишь в том, что это не только методология, но и вполне себе архитектура, одним из пунктов которой является rich-ность модели.
I>Астролябия, как модель звездного неба, это рич или анемик ? Эванс говорит, что если нарисовалась модель, то надо сделать её как следует и для этого выдает кучу рекомендаций, приоритеторв и тд и тд.
Зачем вы постоянно уходите в сторону? Вам же приводят вполне конкретные цитаты из главы про сервисы, а вы постоянно уплываете куда-то в философию.
L>>Извини, но это out-of-scope того, что обсуждается. Если хочешь, создавай отдельную тему, но участвовать в ней я не буду.
I>Это слова Эванса непосредственно относящиеся к его книге и ДДД. Фраза однозначно разрешает вопрос архитектура ДДД или нет.
Нет, не разрешает. Если я скажу я — пионер, это не будет значить, что я — не Петя Васечкин.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
L>>>Вы меня прям в рекурсию загоняете. Двумя строчками было "размещать БЛ надо в сервисах" — это архитектура, теперь то же самое — подход.
I>>А дай ка ссылку, где я писал вроде "Эванс пишет 'размещать БЛ надо в сервисах'" ?
L>rsdn.ru/forum/philosophy/4434550.1.aspx
Стало быть для тебя "Если" == "" Как тебе что либо объяснить, я даже не знаю тперь.
L>>>Извини, но это out-of-scope того, что обсуждается. Если хочешь, создавай отдельную тему, но участвовать в ней я не буду. I>>Это слова Эванса непосредственно относящиеся к его книге и ДДД. Фраза однозначно разрешает вопрос архитектура ДДД или нет.
L>Нет, не разрешает. Если я скажу я — пионер, это не будет значить, что я — не Петя Васечкин.
Здравствуйте, Ikemefula, Вы писали:
L>>>>Вы меня прям в рекурсию загоняете. Двумя строчками было "размещать БЛ надо в сервисах" — это архитектура, теперь то же самое — подход.
I>>>А дай ка ссылку, где я писал вроде "Эванс пишет 'размещать БЛ надо в сервисах'" ?
L>>rsdn.ru/forum/philosophy/4434550.1.aspx
I>Стало быть для тебя "Если" == "" Как тебе что либо объяснить, я даже не знаю тперь.
Если Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)" то конечно он описывает архитектуру.
Утверждение "Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)"" — верно, я приводил цитату из раздела про сервисы.
Подставляя true в процитированное "Если", получаем, что Эванс описывает архитектуру.
Между тем, тут
L>Он описывает, какого рода операции попадают в сервисы. Ответ на вопрос о том, куда попадают остальные операции, лежит на поверхности.
Он говорит про подход
ты утверждаешь, что это не архитектура, а подход.
Ты уж как-нибудь определись уже.
L>>>>Извини, но это out-of-scope того, что обсуждается. Если хочешь, создавай отдельную тему, но участвовать в ней я не буду. I>>>Это слова Эванса непосредственно относящиеся к его книге и ДДД. Фраза однозначно разрешает вопрос архитектура ДДД или нет.
L>>Нет, не разрешает. Если я скажу я — пионер, это не будет значить, что я — не Петя Васечкин.
I>way of thinking никак не может быть архитектурой
Это просто праздник какой-то, ты даже элементарными логическими операциями оперировать не можешь.
"way of thinking" может и не может быть архитектурой (хрен с ним), но ddd ею не только может быть, но и является.
На всякий случай: "A is B" — это не то же самое, что и "A == B". А из того, что "A is B" и "A is С" не следует никакой связи между B и C.
Здравствуйте, мыщъх, Вы писали:
М>вот я и думаю -- а что мне дадут плюсы, если их выучить? питон мне дал высокую продуктивность и учить его не пришлось (так, полистал книжку на выходных), java script дала высокую портабельность (работает _везде_, включая мобилки и опять без затрат на обучение), чистый си дает производительность, но нам нем пишутся только самые низкоуровневые компоненты, а обвязка -- жаба, питон, руби или скала.
М>у плюсов же -- производительность только в теории, на практике оно тормозит и отжирает память (если, конечно, пользоваться приплюснутыми фичами на полную). программы сложно писать и еще сложнее понимать. с компиляторами и платформами сплошная чехарда. даже плагин для популярных программ обычно нужно писать на том компиляторе, которым собиралась сама программа.
Главная фича плюсов — их фичи можно использовать избирательно. Поэтому например я могу писать на С++ для 8-битников, используя наследование и шаблоны и не используя динамическую память, stl и исключения. По сравнению с чистыми сями получается весьма неплохо.
Главный минус питона и яваскрипта для меня — отсутствие компиляции. В отсутствии хорошего покрытия тестами приятно иметь за спиной компилятор. Но например для билд-скриптов питон самое оно. Они довольно компактные, результат виден и проверяем сразу.
Здравствуйте, enji, Вы писали:
E>Главный минус питона и яваскрипта для меня — отсутствие компиляции. В отсутствии хорошего покрытия тестами приятно иметь за спиной компилятор. Но например для билд-скриптов питон самое оно. Они довольно компактные, результат виден и проверяем сразу.
для питона компиляторы есть. очень помогают обнаруживать баги
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, enji, Вы писали:
E>>Главный минус питона и яваскрипта для меня — отсутствие компиляции. В отсутствии хорошего покрытия тестами приятно иметь за спиной компилятор. Но например для билд-скриптов питон самое оно. Они довольно компактные, результат виден и проверяем сразу.
М>для питона компиляторы есть. очень помогают обнаруживать баги
Если ты про пилинт, то помогает, но никакого сравнения с компилятором той же явы или с++ не выдерживает.
А с учетом того, что язык динамический, что-то лучшее для него написать сложно
Здравствуйте, enji, Вы писали:
E>Здравствуйте, мыщъх, Вы писали:
М>>Здравствуйте, enji, Вы писали:
E>>>Главный минус питона и яваскрипта для меня — отсутствие компиляции. В отсутствии хорошего покрытия тестами приятно иметь за спиной компилятор. Но например для билд-скриптов питон самое оно. Они довольно компактные, результат виден и проверяем сразу.
М>>для питона компиляторы есть. очень помогают обнаруживать баги
E>Если ты про пилинт, то помогает, но никакого сравнения с компилятором той же явы или с++ не выдерживает.
я цейтон использую. правда, он тащит за собой все питоновские библиотеки. т.е. на целевой машине питон все-таки должен быть. но компиляция вполне нормальная. самый главный минус -- не все питоновские фичи поддерживаются. [a*3 for a in range(100) if a % 3] -- не поддерживается. абыдно.
E>А с учетом того, что язык динамический, что-то лучшее для него написать сложно
если вы говорите про отлов ошибок, то с вами полностью согласен. в динамическом языке ошибки в типах на стадии компиляции можно обнаружить только если эти ошибки уж очень грубые. из-за чего программы на питоне приходится тестировать тщательнее, чем на си. и очень серьезно мешает несовместимость разных версий. написать код, работающий на всех версиях питона -- это квест. версия X этой фичи еще не поддерживает, а версия X+1 уже не поддерживает. а у кастомера может стоять все, что угодно. ставить несколько версий питона -- не вариант, особенно если мы говорим о чужих машинах.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, Tilir, Вы писали:
М>собствнно у меня есть только одно возражение к вашему посту. вы пишите "вот я тут заведу статическую переменную и никто не заметит -- бейте себя по рукам". по моему глубокому убеждению проблемы нужно решать по мере их возникновения. писать программы на вырост нужно лишь хорошо подумав, ибо это из серии: "почему сегодня не делают корабли, летающие к звездам?! ответ: потому что корабль, построенный завтра, прибудет быстрее. а корабль, построенный послезавтра, еще быстрее. и их обоих обгонит корбаль построенный лет через пятьдесят, но когда он вернется обратно, то обнаружит, что у человечества совсем другие проблемы".
Корабли строят не сразу. Что бы построить через 50 лет корабль, который обгонит другие, его потребуется строить все 50 лет, ломая и переделывая, учитывая опыт. Если мы сегодня не будем делать то что нужно будет через 50 лет, то через 50 лет ничего хорошего не получится.
Кроме этого, мы сегодня пишем софт для сегодняшних задач, а не для того корабля, который через 50 лет то ли полетит то ли его не сделают что бы полететь через 100 лет быстрее. Ситуация может быть прямо противоположной. Если мы не сделаем сегодня плохо, то завтра конкуренты сделают еще хуже и снимут пенки.
Здравствуйте, мыщъх, Вы писали:
М>и очень серьезно мешает несовместимость разных версий. написать код, работающий на всех версиях питона -- это квест. версия X этой фичи еще не поддерживает, а версия X+1 уже не поддерживает. а у кастомера может стоять все, что угодно. ставить несколько версий питона -- не вариант, особенно если мы говорим о чужих машинах.
А как вообще так можно сделать? Разве можно написать код, работающий и на 3.xx и на 2.xx? Все библиотеки, которые я юзаю, имеют отдельные версии для 2-го и 3-го питонов
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
L>>>>>Вы меня прям в рекурсию загоняете. Двумя строчками было "размещать БЛ надо в сервисах" — это архитектура, теперь то же самое — подход.
I>>>>А дай ка ссылку, где я писал вроде "Эванс пишет 'размещать БЛ надо в сервисах'" ?
L>>>rsdn.ru/forum/philosophy/4434550.1.aspx
I>>Стало быть для тебя "Если" == "" Как тебе что либо объяснить, я даже не знаю тперь.
L>
L>Если Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)" то конечно он описывает архитектуру.
L>Утверждение "Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)"" — верно, я приводил цитату из раздела про сервисы. L>Подставляя true в процитированное "Если", получаем, что Эванс описывает архитектуру.
L>Между тем, тут L>
L>>Он описывает, какого рода операции попадают в сервисы. Ответ на вопрос о том, куда попадают остальные операции, лежит на поверхности.
L>Он говорит про подход
L>ты утверждаешь, что это не архитектура, а подход.
L>Ты уж как-нибудь определись уже.
L>>>>>Извини, но это out-of-scope того, что обсуждается. Если хочешь, создавай отдельную тему, но участвовать в ней я не буду. I>>>>Это слова Эванса непосредственно относящиеся к его книге и ДДД. Фраза однозначно разрешает вопрос архитектура ДДД или нет.
L>>>Нет, не разрешает. Если я скажу я — пионер, это не будет значить, что я — не Петя Васечкин.
I>>way of thinking никак не может быть архитектурой
L>Это просто праздник какой-то, ты даже элементарными логическими операциями оперировать не можешь. L>"way of thinking" может и не может быть архитектурой (хрен с ним), но ddd ею не только может быть, но и является.
L>На всякий случай: "A is B" — это не то же самое, что и "A == B". А из того, что "A is B" и "A is С" не следует никакой связи между B и C.
L>Утверждение "Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)"" — верно, я приводил цитату из раздела про сервисы.
Эванс лишь советует.
Домен это не только энтити с методами. а так же сервисы и инфраструктура.
Ты как-то узко мыслишь.
Сам Эванс всю книгу говорит быть прагматичнее.
Но ты почему-то воспринимаешь всё буквально.
Здравствуйте, Lloyd, Вы писали:
I>>Стало быть для тебя "Если" == "" Как тебе что либо объяснить, я даже не знаю тперь.
L>
L>Если Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)" то конечно он описывает архитектуру.
L>Утверждение "Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)"" — верно, я приводил цитату из раздела про сервисы.
"Более того, раздел про сервисы начинается, что мол если у вас есть непонятки по поводу того, куда поместить операцию (In some cases, the clearest and most pragmatic design includes operations that do not conceptually belong to any object), то кладите ее в отдельный сервис. Это как-бы отводит сервисам вторичную роль, мол если не удалось найти куда приткнуть, то делайте сервис, что как бы опять приводит к выводу, что в остальных случаях у нас операции будут в энтитях."
Здесь тоже самое что я тебе говорил — если... то... Т.е. речь идет про выбор места и предлагает вариант. То есть это всего лишь конкретный пример на котором он объясняет свой подход.
L>>>Нет, не разрешает. Если я скажу я — пионер, это не будет значить, что я — не Петя Васечкин.
I>>way of thinking никак не может быть архитектурой
L>Это просто праздник какой-то, ты даже элементарными логическими операциями оперировать не можешь.
Сегодня специально глянул Эванса. У него в гл.5 так и написано, что приведеная (многоуровневая) ахитектура не является единственным вариантом реализации ДДД. Сгодится любая другая которая позволит отделить модель предметной области.
Что касается твоих сервисов, то он пишет, что то естествнный вариант для размещения БЛ в многоуровневой архитектуре. Но он нигде не приводи какой то специальный вариант архитектуры. Он всего то описыват как применять ДДД в этой самой многоуровневой архитектуре.С таким же успехом ДДД можно применить где угодно, главное что бы модель предметной области была выделена явно.
Далее он говорит тоже самое про парадигму. Все примеры у него относятся к ОО, но только по той причине что он считает что это доминирующая парадигма. Он сам указывает и Пролог, и декларативное задание модели и ДСЛ и чего угодно и везде говорит, какие проблемы могут встретиться. Т.е. твое утверждение что де "ДДД насквозь ОО" получается неверным
L>"way of thinking" может и не может быть архитектурой (хрен с ним), но ddd ею не только может быть, но и является.
Ты в курсе, что любая архитектура это дизайн, но не любой дизайн это архитектура ? Вот если пропатчить твои высказывания и заменить архитектура на дизайн, получится все в порядке
Здравствуйте, Ikemefula, Вы писали:
I>Сегодня специально глянул Эванса. У него в гл.5 так и написано, что приведеная (многоуровневая) ахитектура не является единственным вариантом реализации ДДД. Сгодится любая другая которая позволит отделить модель предметной области.
I>Что касается твоих сервисов, то он пишет, что то естествнный вариант для размещения БЛ в многоуровневой архитектуре. Но он нигде не приводи какой то специальный вариант архитектуры. Он всего то описыват как применять ДДД в этой самой многоуровневой архитектуре.С таким же успехом ДДД можно применить где угодно, главное что бы модель предметной области была выделена явно.
I>Далее он говорит тоже самое про парадигму. Все примеры у него относятся к ОО, но только по той причине что он считает что это доминирующая парадигма. Он сам указывает и Пролог, и декларативное задание модели и ДСЛ и чего угодно и везде говорит, какие проблемы могут встретиться. Т.е. твое утверждение что де "ДДД насквозь ОО" получается неверным
А что такое "модель предметной области" у Эванса?
Это тоже самое что модель предметной области у фаулера (Domain Model в PoEAA), а это классы данных с методами БЛ. Причем когда фаулер (и эванс) говорят об anemic model, то как раз противопоставляют объектно-ориентированность domain mode процедурности anemic model.
Так что "модель предметной области" у фаулера\эванса\других_апологетов это именно классы с данными + методы бл, то есть rich model.
Здравствуйте, Enomay, Вы писали:
L>>Утверждение "Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)"" — верно, я приводил цитату из раздела про сервисы.
E>Эванс лишь советует.
Конечно советует. У него разве есть возможность заставить?
E>Домен это не только энтити с методами. а так же сервисы и инфраструктура. E>Ты как-то узко мыслишь.
Я где-то писал, что там "только энтити с методами"?
E>Сам Эванс всю книгу говорит быть прагматичнее. E>Но ты почему-то воспринимаешь всё буквально.
Я говорю о том, что архитектура, которую описывает Эванс в своей книге — рич, ничего более.
L>>Если Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)" то конечно он описывает архитектуру.
L>>Утверждение "Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)"" — верно, я приводил цитату из раздела про сервисы.
I>"Более того, раздел про сервисы начинается, что мол если у вас есть непонятки по поводу того, куда поместить операцию (In some cases, the clearest and most pragmatic design includes operations that do not conceptually belong to any object), то кладите ее в отдельный сервис. Это как-бы отводит сервисам вторичную роль, мол если не удалось найти куда приткнуть, то делайте сервис, что как бы опять приводит к выводу, что в остальных случаях у нас операции будут в энтитях."
I>Здесь тоже самое что я тебе говорил — если... то... Т.е. речь идет про выбор места и предлагает вариант. То есть это всего лишь конкретный пример на котором он объясняет свой подход.
Нет, это не конкретный пример, а описание мотивации введения сервисов в описываемую архитектуру.
L>>>>Нет, не разрешает. Если я скажу я — пионер, это не будет значить, что я — не Петя Васечкин.
I>>>way of thinking никак не может быть архитектурой
L>>Это просто праздник какой-то, ты даже элементарными логическими операциями оперировать не можешь.
I>Сегодня специально глянул Эванса. У него в гл.5 так и написано, что приведеная (многоуровневая) ахитектура не является единственным вариантом реализации ДДД. Сгодится любая другая которая позволит отделить модель предметной области.
Цитата?
I>Что касается твоих сервисов, то он пишет, что то естествнный вариант для размещения БЛ в многоуровневой архитектуре. Но он нигде не приводи какой то специальный вариант архитектуры. Он всего то описыват как применять ДДД в этой самой многоуровневой архитектуре.С таким же успехом ДДД можно применить где угодно, главное что бы модель предметной области была выделена явно.
Ты опять путаешь "философию" и описание архитектуры.
I>Далее он говорит тоже самое про парадигму. Все примеры у него относятся к ОО, но только по той причине что он считает что это доминирующая парадигма. Он сам указывает и Пролог, и декларативное задание модели и ДСЛ и чего угодно и везде говорит, какие проблемы могут встретиться. Т.е. твое утверждение что де "ДДД насквозь ОО" получается неверным
Во-первых, приведи цитату, во-вторых я не писал, что "ДДД насквозь ОО"
L>>"way of thinking" может и не может быть архитектурой (хрен с ним), но ddd ею не только может быть, но и является.
I>Ты в курсе, что любая архитектура это дизайн, но не любой дизайн это архитектура ? Вот если пропатчить твои высказывания и заменить архитектура на дизайн, получится все в порядке
Во-первых, где свзь? Во-вторых, отиличе архитектуры от дизайна только в масштабе решений.
Здравствуйте, Enomay, Вы писали:
L>>Утверждение "Эванс говорит "размещать БЛ надо в сервисах(энтитях, контроллере и тд)"" — верно, я приводил цитату из раздела про сервисы.
E>Эванс лишь советует. E>Домен это не только энтити с методами. а так же сервисы и инфраструктура.
Инфрастуктура в общем случае как в предметную область попала?
Здравствуйте, gandjustas, Вы писали:
G>А что такое "модель предметной области" у Эванса? G>Это тоже самое что модель предметной области у фаулера (Domain Model в PoEAA), а это классы данных с методами БЛ.
Ни в коем разе. Эванс ни много ни мало утверждает что это только один из вариантов реализации. Он же говорит, что модель и вовсем может быть не объектной.
>Причем когда фаулер (и эванс) говорят об anemic model, то как раз противопоставляют объектно-ориентированность domain mode процедурности anemic model.
, рассматривать "моедль предметной области" как модель поведения при работе с предметной областью, то получится именно amenic model.
Самое интересное, что Эванс утвержает, что ОО-парадигма совсем не обязательна для ДДД. сгодится и любая другая парадигма. Так что выходит ДДД сильно ортогонально ОО И потому с помощью ДДД может быть построена как рич модель, так и анемик, так и функциональная и вообще какая угодно.
По твоему астролябия это рич или анемик модель звездного неба ?
Здравствуйте, Lloyd, Вы писали:
L>Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан.
Центральная штукенция у Кея это messaging, т.е. взаимодействие объектов == поведение.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Lloyd, Вы писали:
L>>Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан.
I>Центральная штукенция у Кея это messaging, т.е. взаимодействие объектов == поведение.
Павел, а вы по какому принцыпу выбираете на что отвечать и что квотить. Как-то никак не получается уловить закономерность.
Здравствуйте, Lloyd, Вы писали:
I>>Здесь тоже самое что я тебе говорил — если... то... Т.е. речь идет про выбор места и предлагает вариант. То есть это всего лишь конкретный пример на котором он объясняет свой подход.
L>Нет, это не конкретный пример, а описание мотивации введения сервисов в описываемую архитектуру.
И потому Эванс пишет, что могут использоваться и другие архитектуры ?
I>>Сегодня специально глянул Эванса. У него в гл.5 так и написано, что приведеная (многоуровневая) ахитектура не является единственным вариантом реализации ДДД. Сгодится любая другая которая позволит отделить модель предметной области.
L>Цитата?
Жди завтрашнего дня, у меня нет электронной книги. Примерно в конце гл. 5, про парадигмы и тд.
I>>Далее он говорит тоже самое про парадигму. Все примеры у него относятся к ОО, но только по той причине что он считает что это доминирующая парадигма. Он сам указывает и Пролог, и декларативное задание модели и ДСЛ и чего угодно и везде говорит, какие проблемы могут встретиться. Т.е. твое утверждение что де "ДДД насквозь ОО" получается неверным
L>Во-первых, приведи цитату, во-вторых я не писал, что "ДДД насквозь ОО"
Некий Lloyd писал "Все народ от того же насквозь оопшного DDD плюется,"
I>>Ты в курсе, что любая архитектура это дизайн, но не любой дизайн это архитектура ? Вот если пропатчить твои высказывания и заменить архитектура на дизайн, получится все в порядке
L>Во-первых, где связь? Во-вторых, отиличе архитектуры от дизайна только в масштабе решений.
Связь достаточно простая, если архитектура позволяет отделить модель предметной области, то в её рамках возможен ДДД-дизайн. В качестве архитектуры для рассмотрения, т.е. пример для книги, он берёт многоуровневую архитектуру с бледжеком и шлюхами сервисами и даже объясняет свой выбор
Соответсвенно можно говорить про архитектуры как пригодные для ДДД и это не делает их ДДД
Здравствуйте, Lloyd, Вы писали:
I>>Центральная штукенция у Кея это messaging, т.е. взаимодействие объектов == поведение.
L>Павел, а вы по какому принцыпу выбираете на что отвечать и что квотить. Как-то никак не получается уловить закономерность.
В данном случае я отвечал на всё твоё сообщение, просто неудачно процитировал.
T>Во-первых есть решения и инструменты которые кажутся простыми, таковыми не являясь. Я не буду подробно останавливаться -- копипаст, макросы (в обоих смыслах), goto, volatile в многопоточном окружении, продолжайте сами. Самое главное, когда речь идёт о простоте -- не надо экономить свои усилия к написанию кода. Вместо этого вы экономите чужие усилия к его прочтению и переиспользованию. И этим сберегаются ваши усилия.
Это ты зря сказал, не дай бог это увидят Н...(ой!), крику будет на три месяца вперёд.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
G>>А что такое "модель предметной области" у Эванса? G>>Это тоже самое что модель предметной области у фаулера (Domain Model в PoEAA), а это классы данных с методами БЛ.
I>Ни в коем разе. Эванс ни много ни мало утверждает что это только один из вариантов реализации. Он же говорит, что модель и вовсем может быть не объектной.
А какой тогда? И что такое "модель предметной области"? Ведь по сути большая часть его книги про написание кода в основе которого лежит что "модель предметной области" это то что описано у фаулера.
>>Причем когда фаулер (и эванс) говорят об anemic model, то как раз противопоставляют объектно-ориентированность domain mode процедурности anemic model.
I>Нет у Эванса такого противопоставления
лень искать, но помоему я видел аналогичные высказывания эванса.
G>>Если же, как говорит Sinclair
, рассматривать "моедль предметной области" как модель поведения при работе с предметной областью, то получится именно amenic model.
I> Самое интересное, что Эванс утвержает, что ОО-парадигма совсем не обязательна для ДДД. сгодится и любая другая парадигма. Так что выходит ДДД сильно ортогонально ОО И потому с помощью ДДД может быть построена как рич модель, так и анемик, так и функциональная и вообще какая угодно.
Тогда что такое "модель предметной области" и DDD вообще?
I>По твоему астролябия это рич или анемик модель звездного неба ?
Ни то, ни другое, потому что anemic\rich — способ организации кода (дизайна).
Здравствуйте, Ikemefula, Вы писали:
L>>Нет, это не конкретный пример, а описание мотивации введения сервисов в описываемую архитектуру.
I>И потому Эванс пишет, что могут использоваться и другие архитектуры ?
И это как-то меняет тот факт, что ddd как архитектура является rich?
L>>Во-первых, приведи цитату, во-вторых я не писал, что "ДДД насквозь ОО"
I>Некий Lloyd писал "Все народ от того же насквозь оопшного DDD плюется,"
I>
Уел.
I>>>Ты в курсе, что любая архитектура это дизайн, но не любой дизайн это архитектура ? Вот если пропатчить твои высказывания и заменить архитектура на дизайн, получится все в порядке
L>>Во-первых, где связь? Во-вторых, отиличе архитектуры от дизайна только в масштабе решений.
I>Связь достаточно простая, если архитектура позволяет отделить модель предметной области, то в её рамках возможен ДДД-дизайн. В качестве архитектуры для рассмотрения, т.е. пример для книги, он берёт многоуровневую архитектуру с бледжеком и шлюхами сервисами и даже объясняет свой выбор
I>Соответсвенно можно говорить про архитектуры как пригодные для ДДД и это не делает их ДДД
А кто-то говорит противоположное? Еще раз повторюсь ддд-архитектура, описанная у Эванса — рич. Точка. Это весь посыл, что как был в начальном посте, так и остался. Ты о чем споришь-то? Ты ставишь это под сомнение? Если ставишь, не буду тебя разубеждать, тебе достаточно пролистать книгу и убедиться в этом самому.
Здравствуйте, Ikemefula, Вы писали:
I>>>Центральная штукенция у Кея это messaging, т.е. взаимодействие объектов == поведение.
L>>Павел, а вы по какому принцыпу выбираете на что отвечать и что квотить. Как-то никак не получается уловить закономерность.
I>В данном случае я отвечал на всё твоё сообщение, просто неудачно процитировал.
нет, ты отвечал точно на что-то другое, ибо вообще никакой связи нет.
Здравствуйте, Lloyd, Вы писали:
I>>В данном случае я отвечал на всё твоё сообщение, просто неудачно процитировал.
L>нет, ты отвечал точно на что-то другое, ибо вообще никакой связи нет.
смотри:
Факт 1: применение ООП (по википедии) приводит к " бесплодным спорам".
Факт 2: моделирование от поведения приводит к правильному ответу.
Вывод: ООП — целиком про поведение.
Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан.
А так да, я согласен, "имеет смысл применять критическое мышление", причем прежде всего имеет смысл применять его к себе же.
Это ты писал или ктото за тебя ? Факт1, Факт2 это просто передёргивание Вывод про ООП и поведение сделан исходят из других посылок и я указал тебе "Центральная штукенция у Кея это messaging, т.е. взаимодействие объектов == поведение."
Здравствуйте, Lloyd, Вы писали:
I>>И потому Эванс пишет, что могут использоваться и другие архитектуры ? L>И это как-то меняет тот факт, что ddd как архитектура является rich?
Конечно. Он сам пишет и про Transaction Script и про логическую модель и много про что еще, ты же почему то замечаешь тоьлко рич
I>>Соответсвенно можно говорить про архитектуры как пригодные для ДДД и это не делает их ДДД
L>А кто-то говорит противоположное? Еще раз повторюсь ддд-архитектура, описанная у Эванса — рич. Точка.
I>Факт 1: применение ООП (по википедии) приводит к " бесплодным спорам".
I>Факт 2: моделирование от поведения приводит к правильному ответу.
I>Вывод: ООП — целиком про поведение.
I>Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан.
I>А так да, я согласен, "имеет смысл применять критическое мышление", причем прежде всего имеет смысл применять его к себе же.
I>Это ты писал или ктото за тебя ? Факт1, Факт2 это просто передёргивание
Павел, вы следите за словами-то. Раз уж обвиняете меня в передергивании, то уж потрудитесь приводить аргуметы, а не ограничивайтесь смайликами.
I>Вывод про ООП и поведение сделан исходят из других посылок и я указал тебе "Центральная штукенция у Кея это messaging, т.е. взаимодействие объектов == поведение."
Это ортогонально тому, что у объектов есть состояние.
Здравствуйте, Ikemefula, Вы писали:
L>>И это как-то меняет тот факт, что ddd как архитектура является rich?
I>Конечно. Он сам пишет и про Transaction Script и про логическую модель и много про что еще, ты же почему то замечаешь тоьлко рич
Я где-то говорил, что нет там перечисленного тобою? То, что он пишет про "Transaction Script и про логическую модель и много про что еще", не отменяет того факта, что в сущностях у него методы с бизнес-логикой.
I>>>Соответсвенно можно говорить про архитектуры как пригодные для ДДД и это не делает их ДДД
L>>А кто-то говорит противоположное? Еще раз повторюсь ддд-архитектура, описанная у Эванса — рич. Точка.
I>Читай http://www.rsdn.ru/forum/philosophy/4432392.1.aspx
Зачем мне это перечитывать?
I>и свой ответ на него.
свой ответ на мой же пост? павел, вы не употребляйте больше эти вещества.
I>Так что ты ни много ни мало утверждаешь, что совсем другое.
Нет, ровно все то же самое:
В понимании Эванса (точнее в моем понимании Эванса ), ddd — это не только принцип, но и архитектура с определенным разбиением на энтити, агрегаты, вэлью-объекты, фабрики, репозитории, сервисы и так дале и тому подобное.
И примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель.
Где совсем другое?
I>Эванс всего то демонстрирует ДДД на примере многоуровневой архитектуры с рич моделью. Еще и объясняет почему именно такой выбор.
Нее, он всего-то долил философской воды вокруг ddd-архитектуры, а ты ее и приянял за суть.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
I>>смотри: I>>
I>>Факт 1: применение ООП (по википедии) приводит к " бесплодным спорам".
I>>Факт 2: моделирование от поведения приводит к правильному ответу.
I>>Вывод: ООП — целиком про поведение.
I>>Извини, но по-моему в твоих размышлениях пропущена цепочка промежуточных аргументов, т.к. по приведенным фактам нельзя сделать вывод, которые был сделан.
I>>А так да, я согласен, "имеет смысл применять критическое мышление", причем прежде всего имеет смысл применять его к себе же.
I>>Это ты писал или ктото за тебя ? Факт1, Факт2 это просто передёргивание
L>Павел, вы следите за словами-то. Раз уж обвиняете меня в передергивании, то уж потрудитесь приводить аргуметы, а не ограничивайтесь смайликами.
Было " ООП — оно целиком про поведение", потом "Читайте изобретателя ООП — Алана Кея." а уже в конце следствия "... бесплодным спорам" и "... приводит к правильному ответу".
Т.е. ты ни много ни мало, вывод(следствие) попутал со входной установкой Точнее — ты намеренно смешал всё в кучу.
I>>Вывод про ООП и поведение сделан исходят из других посылок и я указал тебе "Центральная штукенция у Кея это messaging, т.е. взаимодействие объектов == поведение."
L>Это ортогонально тому, что у объектов есть состояние.
Даём слово Алану Кею
I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea.
The big idea is "messaging" -- that is what the kernal of Smalltalk/Squeak
is all about (and it's something that was never quite completed in our
Xerox PARC phase). The Japanese have a small word -- ma -- for "that which
is in between" -- perhaps the nearest English equivalent is "interstitial".
The key in making great and growable systems is much more to design how its
modules communicate rather than what their internal properties and
behaviors should be.
I thought of objects being like biological cells and/or individual
computers on a network, only able to communicate with messages (so
messaging came at the very beginning -- it took a while to see how to
do messaging in a programming language efficiently enough to be
useful).
То есть, когда Кей говорит про объекты, он говорит не про состояние, а про сообщения и в его трактовке состояние наименее важная часть в объекте.
Здравствуйте, Ikemefula, Вы писали:
I>>>Это ты писал или ктото за тебя ? Факт1, Факт2 это просто передёргивание
L>>Павел, вы следите за словами-то. Раз уж обвиняете меня в передергивании, то уж потрудитесь приводить аргуметы, а не ограничивайтесь смайликами.
I>Было " ООП — оно целиком про поведение", потом "Читайте изобретателя ООП — Алана Кея." а уже в конце следствия "... бесплодным спорам" и "... приводит к правильному ответу".
То, что написал Sinclair:
трактовка ООП как механизма по конструированию объектов из данных и методов приводит к бесплодным спорам
То, что написал я:
применение ООП (по википедии) приводит к " бесплодным спорам"
Определение по википедии я приводил выше по ветке и оно именно про "конструированию объектов из данных и методов".
Где передергвание? Это практически прямая цитата.
I>Т.е. ты ни много ни мало, вывод(следствие) попутал со входной установкой Точнее — ты намеренно смешал всё в кучу.
Вы бы Павел, лучше свои посты перечитывали, а не обвиняли других.
I>То есть, когда Кей говорит про объекты, он говорит не про состояние, а про сообщения и в его трактовке состояние наименее важная часть в объекте.
Здравствуйте, Lloyd, Вы писали:
I>>Конечно. Он сам пишет и про Transaction Script и про логическую модель и много про что еще, ты же почему то замечаешь тоьлко рич
L>Я где-то говорил, что нет там перечисленного тобою? То, что он пишет про "Transaction Script и про логическую модель и много про что еще", не отменяет того факта, что в сущностях у него методы с бизнес-логикой.
То есть, если он рассказывает ДДД на примере многослойной архитектуры с рич моделью, то стало быть, ДДД это и есть многослойная архитектура с рич моделью ?
I>>Читай http://www.rsdn.ru/forum/philosophy/4432392.1.aspx
L>В понимании Эванса (точнее в моем понимании Эванса ), ddd — это не только принцип, но и архитектура с определенным разбиением на энтити, агрегаты, вэлью-объекты, фабрики, репозитории, сервисы и так дале и тому подобное.
L>И примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель.
L>Где совсем другое?
Читаем тебя же
I>Соответсвенно можно говорить про архитектуры как пригодные для ДДД и это не делает их ДДД
А кто-то говорит противоположное?
Очевидно, ты где то попутал Эванс использует многослойную архитектуру и рич-модель только по той причине, что это самые популярные, доминирующие решения.
Описывать ДДД подход на всех пригодных архитектурах просто не хватит времени и потому он просто указывает, что ДДД может быть использован в любой архитектуре, главное что бы можно было отделить саму модель.
Здравствуйте, Ikemefula, Вы писали:
I>>>Конечно. Он сам пишет и про Transaction Script и про логическую модель и много про что еще, ты же почему то замечаешь тоьлко рич
L>>Я где-то говорил, что нет там перечисленного тобою? То, что он пишет про "Transaction Script и про логическую модель и много про что еще", не отменяет того факта, что в сущностях у него методы с бизнес-логикой.
I>То есть, если он рассказывает ДДД на примере многослойной архитектуры с рич моделью, то стало быть, ДДД это и есть многослойная архитектура с рич моделью ?
Не надо передергивать, Павел. Он приводит свое представление о ddd-архитектуре, это предвставление — рич, следовательно ddd-архитектура по Эвансу — рич. Как еще проще-то объяснить?
I>>>Читай http://www.rsdn.ru/forum/philosophy/4432392.1.aspx
L>>Зачем мне это перечитывать? I>>>и свой ответ на него. L>>свой ответ на мой же пост? павел, вы не употребляйте больше эти вещества.
I>Я попутал чуток: I>http://www.rsdn.ru/forum/philosophy/4432114.1.aspx
В понимании Эванса (точнее в моем понимании Эванса ), ddd — это не только принцип, но и архитектура с определенным разбиением на энтити, агрегаты, вэлью-объекты, фабрики, репозитории, сервисы и так дале и тому подобное.
И примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель.
Более того, раздел про сервисы начинается, что мол если у вас есть непонятки по поводу того, куда поместить операцию (In some cases, the clearest and most pragmatic design includes operations that do not conceptually belong to any object), то кладите ее в отдельный сервис. Это как-бы отводит сервисам вторичную роль, мол если не удалось найти куда приткнуть, то делайте сервис, что как бы опять приводит к выводу, что в остальных случаях у нас операции будут в энтитях.
Если в качестве первоисточника обращаться к эвансу, то ddd — это все-таки рич.
То, в чем вы нашли якобы противоречие со словами приведенными выше:
А кто-то говорит противоположное? Еще раз повторюсь ддд-архитектура, описанная у Эванса — рич. Точка.
Не могли бы вы прояснить, где это противоречие? Или вы опять что-то чутка попутали?
L>>Нет, ровно все то же самое: L>>
L>>В понимании Эванса (точнее в моем понимании Эванса ), ddd — это не только принцип, но и архитектура с определенным разбиением на энтити, агрегаты, вэлью-объекты, фабрики, репозитории, сервисы и так дале и тому подобное.
L>>И примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель.
L>>Где совсем другое?
I>Читаем тебя же I>
I>>Соответсвенно можно говорить про архитектуры как пригодные для ДДД и это не делает их ДДД
I>А кто-то говорит противоположное?
I>Очевидно, ты где то попутал Эванс использует многослойную архитектуру и рич-модель только по той причине, что это самые популярные, доминирующие решения.
Это ничего не меняет. По каким именно причинам он использовал именно такую архитектура абсолютно не важно. Важно, что он ее использовал и она — ричь.
I>Описывать ДДД подход на всех пригодных архитектурах просто не хватит времени и потому он просто указывает, что ДДД может быть использован в любой архитектуре, главное что бы можно было отделить саму модель.
Кто именно это оспаривал, Павел? Не верьте этому человеку, он редиска.
Здравствуйте, Lloyd, Вы писали:
L>Где передергвание? Это практически прямая цитата.
Синклер сделал вывод исходя из того что пишет Алан Кей, а не из тех посылок которые ты приплёл в виде факт 1 и факт 2.
I>>Т.е. ты ни много ни мало, вывод(следствие) попутал со входной установкой Точнее — ты намеренно смешал всё в кучу. L>Вы бы Павел, лучше свои посты перечитывали, а не обвиняли других.
Ню-ню
I>>То есть, когда Кей говорит про объекты, он говорит не про состояние, а про сообщения и в его трактовке состояние наименее важная часть в объекте.
L>А теперь сравниваем с оспариваемой формулировкой: L>
L>ООП — оно целиком про поведение
L>Вы действительно не видите разницы?
Синклер утрировал высказывание Кея. Есть такой приём в риторике, как гипербола.
Здравствуйте, Lloyd, Вы писали:
I>>То есть, если он рассказывает ДДД на примере многослойной архитектуры с рич моделью, то стало быть, ДДД это и есть многослойная архитектура с рич моделью ?
L>Не надо передергивать, Павел. Он приводит свое представление о ddd-архитектуре, это предвставление — рич, следовательно ddd-архитектура по Эвансу — рич. Как еще проще-то объяснить?
А как сюда вписывается его утверждение, что архитектура может быть любой, если в ней можно отделить модель предметной области ?
L>Если в качестве первоисточника обращаться к эвансу, то ddd — это все-таки рич.
И Эванс говорит, что архитектура может иметь самые разные реализации. И модель может иметь самые разные реализации. Например он говорит чтомодель вовсем ожет и не быть ОО.
Шота первоисточник не подтверждает твои взгляды.
L>То, в чем вы нашли якобы противоречие со словами приведенными выше: L>
L>А кто-то говорит противоположное? Еще раз повторюсь ддд-архитектура, описанная у Эванса — рич. Точка.
L>Не могли бы вы прояснить, где это противоречие? Или вы опять что-то чутка попутали?
Уже пояснил.
I>>Очевидно, ты где то попутал Эванс использует многослойную архитектуру и рич-модель только по той причине, что это самые популярные, доминирующие решения.
L>Это ничего не меняет. По каким именно причинам он использовал именно такую архитектура абсолютно не важно. Важно, что он ее использовал и она — ричь.
Причины важны. Если он использовал конкретный пример для демонстрации ДДД, то это вовсе не значит что только такие примеры и есть ДДД.
I>>Описывать ДДД подход на всех пригодных архитектурах просто не хватит времени и потому он просто указывает, что ДДД может быть использован в любой архитектуре, главное что бы можно было отделить саму модель.
L>Кто именно это оспаривал, Павел? Не верьте этому человеку, он редиска.
Ты же сам оспаривал и оспариваешь: "следовательно ddd-архитектура по Эвансу — рич" Следовательно, тебе верить нельзя ибо с твоих же слов ты и есть редиска.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Lloyd, Вы писали:
L>>Где передергвание? Это практически прямая цитата.
I>Синклер сделал вывод исходя из того что пишет Алан Кей, а не из тех посылок которые ты приплёл в виде факт 1 и факт 2.
Да ну?! А как ты это определил?
Спасибо за доверие, но я тут ни при чём. Читайте изобретателя ООП — Алана Кея.
Кроме того, имеет смысл применять критическое мышление. К примеру, если вы видите, что предлагаемые кем-то правила неизменно приводят к плохому результату, то эти правила сами плохи.
Обратите внимание на "Кроме того" и "вы видите".
Вы все еще уверены, что не смотря на наличие указанных оборотов, вывод про плохие результаты сделан на основе чтения книжек, а не врезультате применения "критического мышления"?
I>>>То есть, когда Кей говорит про объекты, он говорит не про состояние, а про сообщения и в его трактовке состояние наименее важная часть в объекте.
L>>А теперь сравниваем с оспариваемой формулировкой: L>>
L>>ООП — оно целиком про поведение
L>>Вы действительно не видите разницы?
I>Синклер утрировал высказывание Кея. Есть такой приём в риторике, как гипербола.
Я так не думаю, я как раз придерживаюсь взгляда, что разнесение логики и данных — благо, я просто не разделяю взгляда, что это и есть тру-ооп.
Здравствуйте, Ikemefula, Вы писали:
I>>>То есть, если он рассказывает ДДД на примере многослойной архитектуры с рич моделью, то стало быть, ДДД это и есть многослойная архитектура с рич моделью ?
L>>Не надо передергивать, Павел. Он приводит свое представление о ddd-архитектуре, это предвставление — рич, следовательно ddd-архитектура по Эвансу — рич. Как еще проще-то объяснить?
I>А как сюда вписывается его утверждение, что архитектура может быть любой, если в ней можно отделить модель предметной области ?
Отлично вписывается.
Давай на простом примере (в стиле егэ):
у меня черные носки, но это не значит, что все носки черные.
DDD-архитектура по Эвансу — рич, но это не значит ...
Твоя задача — заполнить недостающую часть предложения.
L>>Если в качестве первоисточника обращаться к эвансу, то ddd — это все-таки рич.
I>И Эванс говорит, что архитектура может иметь самые разные реализации. И модель может иметь самые разные реализации. Например он говорит чтомодель вовсем ожет и не быть ОО.
I>Шота первоисточник не подтверждает твои взгляды.
первоисточник подтверждает мои взгляды: ddd-архитектура по Эвансу — рич. Открываем книжку и смотрим с 4 по 7-ю главы.
I>>>Очевидно, ты где то попутал Эванс использует многослойную архитектуру и рич-модель только по той причине, что это самые популярные, доминирующие решения.
L>>Это ничего не меняет. По каким именно причинам он использовал именно такую архитектура абсолютно не важно. Важно, что он ее использовал и она — ричь.
I>Причины важны. Если он использовал конкретный пример для демонстрации ДДД, то это вовсе не значит что только такие примеры и есть ДДД.
Да, совершенно верно. Это значит только то, что архитектура DDD по Эвансу — рич. И только это.
I>>>Описывать ДДД подход на всех пригодных архитектурах просто не хватит времени и потому он просто указывает, что ДДД может быть использован в любой архитектуре, главное что бы можно было отделить саму модель.
L>>Кто именно это оспаривал, Павел? Не верьте этому человеку, он редиска.
I>Ты же сам оспаривал и оспариваешь: "следовательно ddd-архитектура по Эвансу — рич" Следовательно, тебе верить нельзя ибо с твоих же слов ты и есть редиска.
Здравствуйте, Lloyd, Вы писали:
I>>Синклер сделал вывод исходя из того что пишет Алан Кей, а не из тех посылок которые ты приплёл в виде факт 1 и факт 2.
L>Да ну?! А как ты это определил?
Синклер сказал. Он вобщем то это и раньше говорил:
Читайте изобретателя ООП — Алана Кея.
I>>Синклер утрировал высказывание Кея. Есть такой приём в риторике, как гипербола.
L>Я так не думаю, я как раз придерживаюсь взгляда, что разнесение логики и данных — благо, я просто не разделяю взгляда, что это и есть тру-ооп.
Есть два основных варианта трактовки ООП. Один это классика Кея, второй это классика Симула. Как правило, вопли о несостоятельности ООП и тд и тд слышны в основном от сторонников второго варианта.
Здравствуйте, Lloyd, Вы писали:
I>>А как сюда вписывается его утверждение, что архитектура может быть любой, если в ней можно отделить модель предметной области ?
L>Отлично вписывается.
Не вписывается. Есть два взаимоисключающих утверждения:
"ddd-архитектура по Эвансу — рич"
"ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области "
Объясни, как архитектура может быть любой и одновременно только рич ?
L>первоисточник подтверждает мои взгляды: ddd-архитектура по Эвансу — рич. Открываем книжку и смотрим с 4 по 7-ю главы.
В 5й главе как раз и указывается, что архитектура может быть другой, а модель и вовсе не ОО, а парадигма — не ОО.
I>>Причины важны. Если он использовал конкретный пример для демонстрации ДДД, то это вовсе не значит что только такие примеры и есть ДДД.
L>Да, совершенно верно. Это значит только то, что архитектура DDD по Эвансу — рич. И только это.
Нет, это значит, что он описал ДДД только для наиболее популярных решений и пропустил все остальные.
Здравствуйте, Ikemefula, Вы писали:
L>>Да ну?! А как ты это определил?
I>Синклер сказал. Он вобщем то это и раньше говорил: I>
I>Читайте изобретателя ООП — Алана Кея.
Красавчик. Мне нравится твой способ ведения дискуссии. Тебе аргументы, а в ответ — повторение тем же незамутненным тоном тех не безосновательных аргументов.
L>>Я так не думаю, я как раз придерживаюсь взгляда, что разнесение логики и данных — благо, я просто не разделяю взгляда, что это и есть тру-ооп.
I>Есть два основных варианта трактовки ООП. Один это классика Кея, второй это классика Симула. Как правило, вопли о несостоятельности ООП и тд и тд слышны в основном от сторонников второго варианта.
Здравствуйте, Ikemefula, Вы писали:
L>>Отлично вписывается.
I>Не вписывается. Есть два взаимоисключающих утверждения: I>"ddd-архитектура по Эвансу — рич" I>"ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области "
I>Объясни, как архитектура может быть любой и одновременно только рич ?
Отлично вписывается, нету между ними противоречий, даже в твоей формулировке. Я тебе даже пример привел, где твоя ошибка.
L>>первоисточник подтверждает мои взгляды: ddd-архитектура по Эвансу — рич. Открываем книжку и смотрим с 4 по 7-ю главы.
I>В 5й главе как раз и указывается, что архитектура может быть другой, а модель и вовсе не ОО, а парадигма — не ОО.
Да, архитектура может быть любой, а архитектура ddd по Эвансу — рич.
I>>>Причины важны. Если он использовал конкретный пример для демонстрации ДДД, то это вовсе не значит что только такие примеры и есть ДДД.
L>>Да, совершенно верно. Это значит только то, что архитектура DDD по Эвансу — рич. И только это.
I>Нет, это значит, что он описал ДДД только для наиболее популярных решений и пропустил все остальные.
Нет, это значит только то, что архитектура DDD по Эвансу — рич.
Павел ты прикадываешься или действительно недогоняешь?
Здравствуйте, Lloyd, Вы писали:
I>>Не вписывается. Есть два взаимоисключающих утверждения: I>>"ddd-архитектура по Эвансу — рич" I>>"ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области " I>>Объясни, как архитектура может быть любой и одновременно только рич ? L>Отлично вписывается, нету между ними противоречий, даже в твоей формулировке. Я тебе даже пример привел, где твоя ошибка.
Ага, ты слился в аналогиях с носками
L>>>первоисточник подтверждает мои взгляды: ddd-архитектура по Эвансу — рич. Открываем книжку и смотрим с 4 по 7-ю главы. I>>В 5й главе как раз и указывается, что архитектура может быть другой, а модель и вовсе не ОО, а парадигма — не ОО. L>Да, архитектура может быть любой, а архитектура ddd по Эвансу — рич.
Нет. ДДД по Эвансу это значит, что архитектура может быть любой, если позволяет явно отделить модель предметной области. И нет такой вещи, как архитектура ДДД. Это следует из того, что ДДД может быть применен для самых разных архитектур.
Нельзя даже сказать, что ДДД лучше всего подходит для многослойной архитектуры с рич моделью Эванс нигде не говорит ничего подобного.
I>>Нет, это значит, что он описал ДДД только для наиболее популярных решений и пропустил все остальные. L>Нет, это значит только то, что архитектура DDD по Эвансу — рич.
Архитектура на которой Эванс демонстрирует примеры — рич. ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области.
L>Павел ты прикадываешься или действительно недогоняешь?
Тебе уже минимум пятеро человек указали на твои нестыковки Делай выводы.
Здравствуйте, Lloyd, Вы писали:
L>Красавчик. Мне нравится твой способ ведения дискуссии. Тебе аргументы, а в ответ — повторение тем же незамутненным тоном тех не безосновательных аргументов.
Перечитай что пишет Синклер.
L>>>Я так не думаю, я как раз придерживаюсь взгляда, что разнесение логики и данных — благо, я просто не разделяю взгляда, что это и есть тру-ооп.
I>>Есть два основных варианта трактовки ООП. Один это классика Кея, второй это классика Симула. Как правило, вопли о несостоятельности ООП и тд и тд слышны в основном от сторонников второго варианта.
L>Судя по вашему поведению, вы сторонник Симулы.
Здравствуйте, Ikemefula, Вы писали:
I>Нет. ДДД по Эвансу это значит, что архитектура может быть любой, если позволяет явно отделить модель предметной области. И нет такой вещи, как архитектура ДДД. Это следует из того, что ДДД может быть применен для самых разных архитектур.
1) Что такое DDD если не архитектура и дизайн?
2) Приведи пример не-rich DDD
Здравствуйте, Ikemefula, Вы писали:
I>>>В 5й главе как раз и указывается, что архитектура может быть другой, а модель и вовсе не ОО, а парадигма — не ОО. L>>Да, архитектура может быть любой, а архитектура ddd по Эвансу — рич.
I>Нет. ДДД по Эвансу это значит, что архитектура может быть любой, если позволяет явно отделить модель предметной области. И нет такой вещи, как архитектура ДДД. Это следует из того, что ДДД может быть применен для самых разных архитектур.
Архитектура ДДД по Эвансу — рич, в чем ты можешь убедиться в главах 4-7.
Но архитектура действительно может быть любой.
I>Нельзя даже сказать, что ДДД лучше всего подходит для многослойной архитектуры с рич моделью Эванс нигде не говорит ничего подобного.
Это как-то отменяет наличе глав 4-7?
I>>>Нет, это значит, что он описал ДДД только для наиболее популярных решений и пропустил все остальные. L>>Нет, это значит только то, что архитектура DDD по Эвансу — рич.
I>Архитектура на которой Эванс демонстрирует примеры — рич. ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области.
Кто спорит?
L>>Павел ты прикадываешься или действительно недогоняешь?
I>Тебе уже минимум пятеро человек указали на твои нестыковки Делай выводы.
Здравствуйте, Lloyd, Вы писали:
I>>Нет. ДДД по Эвансу это значит, что архитектура может быть любой, если позволяет явно отделить модель предметной области. И нет такой вещи, как архитектура ДДД. Это следует из того, что ДДД может быть применен для самых разных архитектур.
L>Архитектура ДДД по Эвансу — рич, в чем ты можешь убедиться в главах 4-7.
"Архитектура ДДД по Эвансу — рич" это значит, если по русски, что Эванс утверждает, что для ДДД годится исключительно рич модель или же рич модель даёт гарантировано наилучший результат. Или, например, под правила Эванса подходит только рич модель.
Если Эванс взял рич модель как пример, то это не даёт оснований говорить "Архитектура ДДД по Эвансу — рич", максимум — "в книге Эванса примеры — рич"
L>Но архитектура действительно может быть любой.
Соответсвенно это уже нестыкуется с высказыванием выше.
I>>Нельзя даже сказать, что ДДД лучше всего подходит для многослойной архитектуры с рич моделью Эванс нигде не говорит ничего подобного.
L>Это как-то отменяет наличе глав 4-7?
Это отменяет тот смысл который ты хочешь вложить в эти главы
I>>Архитектура на которой Эванс демонстрирует примеры — рич. ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области.
L>Кто спорит?
Здравствуйте, Lloyd, Вы писали:
L>Если честно, мне надоело доказывать, что Эванс описывает рич. Если считаешь, что там не ричь — пусть будет по-твоему.
Не ври. Ты говоришь не о том, что Эванс описывает, а приписываешь Эвансу определённые взгяды вроде " его мнение о ddd как архитектуре, а там — именно рич-модель."
Здравствуйте, Ikemefula, Вы писали:
L>>Архитектура ДДД по Эвансу — рич, в чем ты можешь убедиться в главах 4-7.
I>"Архитектура ДДД по Эвансу — рич" это значит, если по русски, что Эванс утверждает, что для ДДД годится исключительно рич модель или же рич модель даёт гарантировано наилучший результат. Или, например, под правила Эванса подходит только рич модель.
Нет, Павел, это не означает выводов сделаных вами. Я устал это повторять.
I>Если Эванс взял рич модель как пример, то это не даёт оснований говорить "Архитектура ДДД по Эвансу — рич", максимум — "в книге Эванса примеры — рич"
L>>Но архитектура действительно может быть любой.
I>Соответсвенно это уже нестыкуется с высказыванием выше.
Стыкуется, т.к. в формулировку выше — "Архитектура ДДД по Эвансу" , тут — просто "архитектура".
I>>>Нельзя даже сказать, что ДДД лучше всего подходит для многослойной архитектуры с рич моделью Эванс нигде не говорит ничего подобного.
L>>Это как-то отменяет наличе глав 4-7?
I>Это отменяет тот смысл который ты хочешь вложить в эти главы
да нет, это отментяет смысл, который ты мне приписываешь.
I>>>Архитектура на которой Эванс демонстрирует примеры — рич. ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области.
L>>Кто спорит?
I>Ты.
Здравствуйте, Lloyd, Вы писали:
L>Павел, ты надоел. Я не знаю как еще обяъснить, что то, что описано у Эванса — ричь.
Не ври. Ты объясняешь совсем другое, например "ddd — это не только принцип, но и архитектура с определенным разбиением "
Если Эванс использовал многослойную архитектуру и рич-модель, это еще не даёт повод называть эти две вещи ДДД-архитектурой. А ты именно так и называешь.
Здравствуйте, Ikemefula, Вы писали:
I>Если Эванс взял рич модель как пример, то это не даёт оснований говорить "Архитектура ДДД по Эвансу — рич", максимум — "в книге Эванса примеры — рич"
это одно и то же, потому что Эванс больше нигде не приводит примеры других архитектур.
Кстати отсутствие вообще каких либо примеров не-rich подхода при DDD наводит на мысль что такого не бывает в принципе.
Здравствуйте, Lloyd, Вы писали:
I>>"Архитектура ДДД по Эвансу — рич" это значит, если по русски, что Эванс утверждает, что для ДДД годится исключительно рич модель или же рич модель даёт гарантировано наилучший результат. Или, например, под правила Эванса подходит только рич модель.
L>Нет, Павел, это не означает выводов сделаных вами. Я устал это повторять.
Означает. По крайней мере в русском языке.
I>>Если Эванс взял рич модель как пример, то это не даёт оснований говорить "Архитектура ДДД по Эвансу — рич", максимум — "в книге Эванса примеры — рич" L>>>Но архитектура действительно может быть любой. I>>Соответсвенно это уже нестыкуется с высказыванием выше.
L>Стыкуется, т.к. в формулировку выше — "Архитектура ДДД по Эвансу" , тут — просто "архитектура".
Это твои уловки, ты то пишешь ДДД, то опускаешь эту аббревиатуру
I>>Ты.
L>Где?
Здравствуйте, gandjustas, Вы писали:
I>>Если Эванс взял рич модель как пример, то это не даёт оснований говорить "Архитектура ДДД по Эвансу — рич", максимум — "в книге Эванса примеры — рич" G>это одно и то же, потому что Эванс больше нигде не приводит примеры других архитектур.
Враньё. Он явно указыват что архитектура может быть отличной от многослойной и модель может быть совсем не рич а парадигма и вовсе не ОО.
G>Кстати отсутствие вообще каких либо примеров не-rich подхода при DDD наводит на мысль что такого не бывает в принципе.
Да, наводит на мысль. В своё время отсутствие самолётов наводило на мысль, что аппараты тяжелее воздуха невозможны в принципе. Кто ж спорит
Здравствуйте, Ikemefula, Вы писали:
L>>Павел, ты надоел. Я не знаю как еще обяъснить, что то, что описано у Эванса — ричь.
I>Не ври. Ты объясняешь совсем другое, например "ddd — это не только принцип, но и архитектура с определенным разбиением "
Ты пропустил "у Эванса".
I>Если Эванс использовал многослойную архитектуру и рич-модель, это еще не даёт повод называть эти две вещи ДДД-архитектурой. А ты именно так и называешь.
Нет, я этого не утверждал. Все что я говорю, что ДДД-архитектура по Эвансу — это рич. И только.
Из этого нельзя прийти к выводу, что "многослойную архитектуру и рич-модель" являются ДДД-архитектурой.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>Если Эванс взял рич модель как пример, то это не даёт оснований говорить "Архитектура ДДД по Эвансу — рич", максимум — "в книге Эванса примеры — рич" G>>это одно и то же, потому что Эванс больше нигде не приводит примеры других архитектур.
I>Враньё. Он явно указыват что архитектура может быть отличной от многослойной и модель может быть совсем не рич а парадигма и вовсе не ОО.
Это еще ни о чем не говорит. Или ты знаешь примеры где Эванс приводит примеры других архитектур?
В математике и физике вообще полно примеров когда выдумывались некоторые объекты, которые теоретически должны существовать, но реально не было обнаружено ни одного такого объекта.
G>>Кстати отсутствие вообще каких либо примеров не-rich подхода при DDD наводит на мысль что такого не бывает в принципе. I>Да, наводит на мысль. В своё время отсутствие самолётов наводило на мысль, что аппараты тяжелее воздуха невозможны в принципе. Кто ж спорит
Неправда, птицы тяжелее воздуха и тем не менее всегда летали. Таких мыслей ни у кого не было.
Кстати в отличие от физики в математике и программировании что-то доказать или опровергнуть гораздо проще, так как не требуется больших затрат энергии.
Если ты сичтаешь что возможна не-rich архитектура с DDD, то приведи пример.
Кстати, что такое тогда вообще DDD, если не архитектура?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Lloyd, Вы писали:
I>>>"Архитектура ДДД по Эвансу — рич" это значит, если по русски, что Эванс утверждает, что для ДДД годится исключительно рич модель или же рич модель даёт гарантировано наилучший результат. Или, например, под правила Эванса подходит только рич модель.
I>L>Нет, Павел, это не означает выводов сделаных вами. Я устал это повторять.
I>Означает. По крайней мере в русском языке.
Нет, Павел, не означает.
I>>>Если Эванс взял рич модель как пример, то это не даёт оснований говорить "Архитектура ДДД по Эвансу — рич", максимум — "в книге Эванса примеры — рич" L>>>>Но архитектура действительно может быть любой. I>>>Соответсвенно это уже нестыкуется с высказыванием выше.
L>>Стыкуется, т.к. в формулировку выше — "Архитектура ДДД по Эвансу" , тут — просто "архитектура".
I>Это твои уловки, ты то пишешь ДДД, то опускаешь эту аббревиатуру
Да, инода я пишу и ddd, возможно где-то даже пропустил, если этой действительно так, приношу вам самые искренние соболезнования, я не со зла.
I>>>Ты.
L>>Где?
I>Например в выделеной части.
I>>Архитектура на которой Эванс демонстрирует примеры — рич. ДДД по Эвансу — архитектура может быть любой, если в ней можно отделить модель предметной области.
L>Кто спорит?
Ты.
В процтированном утвеждении "Кто спорит?" означает "Кто спорит, что архитектура может быть любой?"
Здравствуйте, Lloyd, Вы писали:
I>>Не ври. Ты объясняешь совсем другое, например "ddd — это не только принцип, но и архитектура с определенным разбиением "
L>Ты пропустил "у Эванса".
Это подразумевается. Тем не менее ты споришь с самим Эвансом и умудряешься приписать ему своё понимаение
I>>Если Эванс использовал многослойную архитектуру и рич-модель, это еще не даёт повод называть эти две вещи ДДД-архитектурой. А ты именно так и называешь.
L>Нет, я этого не утверждал. Все что я говорю, что ДДД-архитектура по Эвансу — это рич. И только.
"по Эвансу", (по Бору, по Дарвину и тд) в русском языке имеет определённый смысл. В твоих высказываниях этого нет.
Здравствуйте, Ikemefula, Вы писали:
L>>Ты пропустил "у Эванса".
I>Это подразумевается.
Да, но если это опустить, то смысл меняется.
L>>Нет, я этого не утверждал. Все что я говорю, что ДДД-архитектура по Эвансу — это рич. И только.
I>"по Эвансу", (по Бору, по Дарвину и тд) в русском языке имеет определённый смысл. В твоих высказываниях этого нет.
Нету чего? Нету ""по Эвансу"" или нету "определённый смысл"?
Какой именно смысл это имеет в русском языке?
Если не сложно,выражайся яснее. Я уверен, этой дискуссии не было бы, если бы ты более отчетливо формулировал свои мысли и не пытался увидеть в моих постах то, чего в них нет.
Здравствуйте, gandjustas, Вы писали:
I>>Враньё. Он явно указыват что архитектура может быть отличной от многослойной и модель может быть совсем не рич а парадигма и вовсе не ОО. G>Это еще ни о чем не говорит. Или ты знаешь примеры где Эванс приводит примеры других архитектур?
Приводит пример или пишет книгу с использованием такого примера ?
G>>>Кстати отсутствие вообще каких либо примеров не-rich подхода при DDD наводит на мысль что такого не бывает в принципе. I>>Да, наводит на мысль. В своё время отсутствие самолётов наводило на мысль, что аппараты тяжелее воздуха невозможны в принципе. Кто ж спорит G>Неправда, птицы тяжелее воздуха и тем не менее всегда летали. Таких мыслей ни у кого не было.
Птица это не самолёт и даже не аппарат, но ты конечно можешь считать иначе. В свое время обозначеный вопрос всерьёз беспокоил людей и ему давали даже религиозное объяснение, дескать, бог послелил человека на земле и тому летать невозможно в принципе. Да-да.
Ну да хрен с ней, с птицей. Это ничего не меняет. Во все времена отсутствие положительных примеров не является доказательством отсутствия — это логика в чистом виде, т.к. отсутствие является необходимым, но не является необходимым и достаточным условием
А кого какие мысли посещают это уже совсем дело десятое.
G>Кстати в отличие от физики в математике и программировании что-то доказать или опровергнуть гораздо проще, так как не требуется больших затрат энергии.
Конечно. Берешь книу, читаешь в указаном месте -> профит. Но такой способ у тебя и Lloyd похоже не в ходу.
G>Если ты сичтаешь что возможна не-rich архитектура с DDD, то приведи пример.
В книге Эванса.
G>Кстати, что такое тогда вообще DDD, если не архитектура?
Я давал цитату самого Эванса. Если тебя это не устраивает, какие ко мне могут быть вопросы ?
Здравствуйте, Lloyd, Вы писали:
L>Да, но если это опустить, то смысл меняется.
В отрыве от контекста — да. Ты что, теряешь контекст каждый раз когда читаешь форум ?
I>>"по Эвансу", (по Бору, по Дарвину и тд) в русском языке имеет определённый смысл. В твоих высказываниях этого нет.
L>Нету чего? Нету ""по Эвансу"" или нету "определённый смысл"?
"определённый смысл"
L>Какой именно смысл это имеет в русском языке?
Я уже дал ответ на этот вопрос еще до того как ты задал его.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>Враньё. Он явно указыват что архитектура может быть отличной от многослойной и модель может быть совсем не рич а парадигма и вовсе не ОО. G>>Это еще ни о чем не говорит. Или ты знаешь примеры где Эванс приводит примеры других архитектур?
I>Приводит пример или пишет книгу с использованием такого примера ?
Без разницы, просто пример где есть DDD и нет rich. Даже не эванс подойдет.
G>>>>Кстати отсутствие вообще каких либо примеров не-rich подхода при DDD наводит на мысль что такого не бывает в принципе. I>>>Да, наводит на мысль. В своё время отсутствие самолётов наводило на мысль, что аппараты тяжелее воздуха невозможны в принципе. Кто ж спорит G>>Неправда, птицы тяжелее воздуха и тем не менее всегда летали. Таких мыслей ни у кого не было.
I>Птица это не самолёт и даже не аппарат, но ты конечно можешь считать иначе. В свое время обозначеный вопрос всерьёз беспокоил людей и ему давали даже религиозное объяснение, дескать, бог послелил человека на земле и тому летать невозможно в принципе. Да-да.
Да, человек самостоятельно не может летать никогда, но насчет того что невозможен полет потому что некоторое тело тяжелее воздуха — бред.
Ты тут, как и в других местах, перескакиваешь с общего на частное и делаешь вид что это что-то доказывает.
I>Ну да хрен с ней, с птицей. Это ничего не меняет. Во все времена отсутствие положительных примеров не является доказательством отсутствия — это логика в чистом виде, т.к. отсутствие является необходимым, но не является необходимым и достаточным условием
Но и не является доказательством существования А ты тут упорно пытаешься доказать обратное, что бывает не-rich DDD.
G>>Кстати в отличие от физики в математике и программировании что-то доказать или опровергнуть гораздо проще, так как не требуется больших затрат энергии. I>Конечно. Берешь книу, читаешь в указаном месте -> профит. Но такой способ у тебя и Lloyd похоже не в ходу.
Меня книга ни коем образом не интересует. Пусть эванс пишет что хочет, а ты его понимай как хочешь.
Но ответь на два вопроса:
1) Что такое DDD с технической точки зрения, то есть что нужно делать чтобы было DDD
2) Где посмотреть не-rich DDD.
G>>Если ты сичтаешь что возможна не-rich архитектура с DDD, то приведи пример. I>В книге Эванса.
Страница, параграф? Лучше сюда скопируй.
G>>Кстати, что такое тогда вообще DDD, если не архитектура? I>Я давал цитату самого Эванса. Если тебя это не устраивает, какие ко мне могут быть вопросы ?
Ссылку дай, я не читаю все что ты пишешь.
Здравствуйте, Ikemefula, Вы писали:
L>>Да, но если это опустить, то смысл меняется. I>В отрыве от контекста — да. Ты что, теряешь контекст каждый раз когда читаешь форум ?
Нет, это ты его теряешь, поэтому я постоянно и пишу "по Эвансу", но тебе даже и это не помогоает.
Видимо, у тебя какой-то свой глубоко личный контекст, из которого вас не вырвать даже многократным повторением.
L>>Какой именно смысл это имеет в русском языке? I>Я уже дал ответ на этот вопрос еще до того как ты задал его.
Упоминание про русский язык в данной дисскусси встречается дай бог если раз 5. И там нет определения смысла фразы "по Эвансу".
Здравствуйте, Lloyd, Вы писали:
L>Не, раз уж взялись аппелировать к авторитету, так уж будьте добры приводить ссылки на авторитет, а не на википедию. Ведь согласно вашей формулировке там "чушь".
Не, ну если вы настаиваете —
OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them.
http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en
Я не говорил, что всё в википедии — чушь. Я говорил, что конкретное определение, процитированное вами — чушь.
L>Это вы про Алана Кея?
Это я про всех, кто начинает цитировать Эванса, Фаулера, Буча, и вообще всех подряд, не давая себе труда разобраться в теме.
Я в этом форуме минимум трижды участвовал в затяжных флеймах про природу ООП и все аргументы уже минимум по два раза высказал.
L>не впеяатляет, ибо я и сам немногим позже начал его изучать, причем по тем же технологиям.
Вы не там делаете акцент. Дата начала неважна. Важно то, что
L>Только вот вывод вы из этого неправильный сделали. Ошибка — не в определении ООП как "моделирование объектов предметной области при помощи экземпляров классов", а в использовании ООП для "моделирования объектов предметной области".
Если исходить из такого определения, то как-то трудно использовать ООП для чего-то другого. Иименно исходя из него происходят совершенно идиотские примеры приложений из учебников ООП.
Равно как трудно построить какой-то работоспособный подход к ОО-дизайну, исходя из объекта как "сишного struct с указателем на VMT".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
L>>>Какой именно смысл это имеет в русском языке? I>>Я уже дал ответ на этот вопрос еще до того как ты задал его.
L>Упоминание про русский язык в данной дисскусси встречается дай бог если раз 5. И там нет определения смысла фразы "по Эвансу".
Цитирую себя "Архитектура ДДД по Эвансу — рич" это значит, если по русски, что Эванс утверждает, что для ДДД годится исключительно рич модель или же рич модель даёт гарантировано наилучший результат. Или, например, под правила Эванса подходит только рич модель. "
Здравствуйте, Sinclair, Вы писали:
L>>Не, раз уж взялись аппелировать к авторитету, так уж будьте добры приводить ссылки на авторитет, а не на википедию. Ведь согласно вашей формулировке там "чушь". S>Не, ну если вы настаиваете —
S>
S>OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them.
Однако, по-моему, "hiding of state-process" как-то не очень вяжется с "ООП — оно целиком про поведение".
Или я неправильно понимаю эту фразу?
Судя по всему, я не один такой:
"local retention" is a new notion to me in the context of OOP, and I assume it refers to state-process and means that an object is in possession of its state-process, so that the state of an object is kept locally with the object and not elsewhere.
Здравствуйте, Ikemefula, Вы писали:
L>>Упоминание про русский язык в данной дисскусси встречается дай бог если раз 5. И там нет определения смысла фразы "по Эвансу".
I>Цитирую себя "Архитектура ДДД по Эвансу — рич" это значит, если по русски, что Эванс утверждает, что для ДДД годится исключительно рич модель или же рич модель даёт гарантировано наилучший результат. Или, например, под правила Эванса подходит только рич модель. "
Сорри, пропистил.
Вы не правы, если считаете, что ваша трактовка "по Эвансу" — верна. Если бы я хотел сказать, что для "ДДД годится исключительно рич", я бы так и написал.
Я же написал, что "Архитектура ДДД по Эвансу — рич", что означет то, и только то, что там написано: есть архитектура ДДД по Эвансу (честно-честно есть, смотрите главы 4-7) и она — рич. Точка.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
L>>>Упоминание про русский язык в данной дисскусси встречается дай бог если раз 5. И там нет определения смысла фразы "по Эвансу".
I>>Цитирую себя "Архитектура ДДД по Эвансу — рич" это значит, если по русски, что Эванс утверждает, что для ДДД годится исключительно рич модель или же рич модель даёт гарантировано наилучший результат. Или, например, под правила Эванса подходит только рич модель. "
L>Сорри, пропистил. L>Вы не правы, если считаете, что ваша трактовка "по Эвансу" — верна. Если бы я хотел сказать, что для "ДДД годится исключительно рич", я бы так и написал. L>Я же написал, что "Архитектура ДДД по Эвансу — рич", что означет то, и только то, что там написано: есть архитектура ДДД по Эвансу (честно-честно есть, смотрите главы 4-7) и она — рич. Точка.
На сколько я помню, флейм пошел с тезиса о том что анемик не есть тру ООП. И вот только что наткнулся на то что Эванс, судя по всему, с этим согласен
Начало главы 5
Then there are those aspects of the domain that are more clearly expressed as actions or
operations, rather than as objects. Although it is a slight departure from object-oriented modeling
tradition, it is often best to express these as SERVICES, rather than forcing responsibility for an
operation onto some ENTITY or VALUE OBJECT. A SERVICE is something that is done for a client on
request. In the technical layers of the software, there are many SERVICES. They emerge in the
domain also, when some activity is modeled that corresponds to something the software must do,
but does not correspond with state.
There are inevitable situations in which the purity of the object model must be compromised, such
as for storage in a relational database. This chapter will lay out some guidelines for staying on
course when you are forced to deal with these messy realities.
В итоге сам Эванс, говорит о том что сервисы — это отступление от OOP, а анемик ведет нас к сервисам. С другой стороны, Эванс эти отступления считает находящимися в рамках DDD. Но опять таки, предлагает не углубляться в сторону процедурного программирования и не злоупотреблять толстыми сервисами. Именно так его интерпретирует Фаулер в статье, где утверждает что анемик есть антипаттерн:
Fowler>The key point here is that the Service Layer is thin — all the key logic lies in the domain layer. He reiterates this point in his service pattern:
Evans>Now, the more common mistake is to give up too easily on fitting the behavior into an appropriate object, gradually slipping toward procedural programming.
Мне кажется что Ф искажает изначальный посыл Э., который писал о том, что раз уж мы взялись с ООП конца, то давайте будем его придерживаться.
В конце главы 4 Э. ссылается на фразу Ф.
If the architecture isolates the domain-related code in a way that allows a cohesive domain design loosely coupled to the rest of the system, then that architecture can probably support domain-driven design
Это как раз об архитектурах, которые probably могут поддержать DDD. Необходимым условием обозначена изоляция доменного кода от остальной системы, что вряд ли можно сказать об анемике в общем случае.
Здравствуйте, Lloyd, Вы писали:
L>Однако, по-моему, "hiding of state-process" как-то не очень вяжется с "ООП — оно целиком про поведение". L>Или я неправильно понимаю эту фразу?
Всё прекрасно вяжется. Просто состояние в ООП вторично, оно нужно только для обеспечения поведения. И всё, о чём говорит Кей применительно к состоянию — это ограничение доступа к нему. Узнать состояние объекта можно только через его поведение.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>В конце главы 4 Э. ссылается на фразу Ф. S>
If the architecture isolates the domain-related code in a way that allows a cohesive domain design loosely coupled to the rest of the system, then that architecture can probably support domain-driven design
S>Это как раз об архитектурах, которые probably могут поддержать DDD. Необходимым условием обозначена изоляция доменного кода от остальной системы, что вряд ли можно сказать об анемике в общем случае.
С учетом того что не всегда ясно что есть "доменный код", эта фраза ни о чем вообще.
Например код выборки для отображения "топ5 покупаемых товаров за месяц" в интернет-магазине является доменным? Например Domain Expert сказал что наличие такого виджета на сайте является критичным. А как его сделать lossely coupled, но достаточно эффективным?
Здравствуйте, Sinclair, Вы писали:
L>>Однако, по-моему, "hiding of state-process" как-то не очень вяжется с "ООП — оно целиком про поведение". L>>Или я неправильно понимаю эту фразу? S>Всё прекрасно вяжется. Просто состояние в ООП вторично, оно нужно только для обеспечения поведения.
Эта формулировка все-таки существенно отличается от "ООП — оно целиком про поведение".
S>И всё, о чём говорит Кей применительно к состоянию — это ограничение доступа к нему. Узнать состояние объекта можно только через его поведение.
И это как-то отличается от того, как трактуют ООП "Эвансы, Фаулеры, Бучи"? Кей в приведенной фразе не говорит ничего кардинально отличающегося, про инкапсуляцию не пишет разве ленивый.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>В конце главы 4 Э. ссылается на фразу Ф. S>>
If the architecture isolates the domain-related code in a way that allows a cohesive domain design loosely coupled to the rest of the system, then that architecture can probably support domain-driven design
S>>Это как раз об архитектурах, которые probably могут поддержать DDD. Необходимым условием обозначена изоляция доменного кода от остальной системы, что вряд ли можно сказать об анемике в общем случае.
G>С учетом того что не всегда ясно что есть "доменный код", эта фраза ни о чем вообще.
Я ее вставил не потому что она мне нравится, а потому что видимо о ней говорил Ikemefula, утверждая что DDD вне архитектур.
G>Например код выборки для отображения "топ5 покупаемых товаров за месяц" в интернет-магазине является доменным? Например Domain Expert сказал что наличие такого виджета на сайте является критичным. А как его сделать lossely coupled, но достаточно эффективным?
Полагаю что в общем случае TOP 5 не является доменным без какой-то специфики вычисления для товаров в магазине, точно так же как .OrderBy(...).Take(5). Однако, если Domain Expert пожелает выполнять какую-то работу с доменом при покупке товара из TOP 5, то домену придется иметь дело с rest of the system, в случае если за top 5 будет отвечать что-то вне домена. При наличии в домене соответствующей абстракции можно добиться loose coupling. И эта абстракция будет уже "впереди" домена. Достигнув некоторой критической массы абстракций "впереди" домена, будет уже не вполне DDD.
Здравствуйте, samius, Вы писали:
G>>Например код выборки для отображения "топ5 покупаемых товаров за месяц" в интернет-магазине является доменным? Например Domain Expert сказал что наличие такого виджета на сайте является критичным. А как его сделать lossely coupled, но достаточно эффективным? S>Полагаю что в общем случае TOP 5 не является доменным без какой-то специфики вычисления для товаров в магазине, точно так же как .OrderBy(...).Take(5).
Domain — A sphere of knowledge, influence, or activity.
В данном случае есть knowledge о необходимости получать рейтинг покупаемости товаров за период.
S>Однако, если Domain Expert пожелает выполнять какую-то работу с доменом при покупке товара из TOP 5, то домену придется иметь дело с rest of the system, в случае если за top 5 будет отвечать что-то вне домена. При наличии в домене соответствующей абстракции можно добиться loose coupling. И эта абстракция будет уже "впереди" домена. Достигнув некоторой критической массы абстракций "впереди" домена, будет уже не вполне DDD.
То есть получается что почти все нетривиальные выборки данных будут не-DDD, даже если именно они являются основными задачами с точки зрения Domain Expert.
Возьмем бухгалтерию. Там есть сущности — "проводки", "первичные документы" итп, и есть выборки — "балансы", "обороты", "остатки", которые являются основными задачами для эксперта (бухгалтера).
Получается что полноценный DDD невозможен в такой задаче?
Тогда в чем вообще суть DDD? Для чего он нужен? Чем он помогает?
G>Возьмем бухгалтерию. Там есть сущности — "проводки", "первичные документы" итп, и есть выборки — "балансы", "обороты", "остатки", которые являются основными задачами для эксперта (бухгалтера).
G>Получается что полноценный DDD невозможен в такой задаче?
выборки нужны эксперту, но не системе. для системы они вообще ничего не значат и на логику, в данном случае, никакого воздействия не оказывают.
выборка — это не логика.
G>Тогда в чем вообще суть DDD? Для чего он нужен? Чем он помогает?
DDD помогает структурировать приложение и вынести логику отдельным слоем. плюс доменный язык.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Полагаю что в общем случае TOP 5 не является доменным без какой-то специфики вычисления для товаров в магазине, точно так же как .OrderBy(...).Take(5).
G>
G>Domain — A sphere of knowledge, influence, or activity.
G>Отсюда
G>В данном случае есть knowledge о необходимости получать рейтинг покупаемости товаров за период.
В таком случае никаких проблем с изоляцией domain от rest system в отношении TOP5 нет.
Но я бы TOP5 отнес к
Model — A system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain.
Отсюда
S>>Однако, если Domain Expert пожелает выполнять какую-то работу с доменом при покупке товара из TOP 5, то домену придется иметь дело с rest of the system, в случае если за top 5 будет отвечать что-то вне домена. При наличии в домене соответствующей абстракции можно добиться loose coupling. И эта абстракция будет уже "впереди" домена. Достигнув некоторой критической массы абстракций "впереди" домена, будет уже не вполне DDD.
G>То есть получается что почти все нетривиальные выборки данных будут не-DDD, даже если именно они являются основными задачами с точки зрения Domain Expert.
Это зависит от отношения к классификации. Как отступая от тру ООП в сторону процедурщины при создании сервиса (Эванс об этом пишет), мы остаемся в рамках ООП, так и при выпячивании абстракций впереди domain, можно считать что остаемся в рамках DDD. Как я понимаю, Ф. наличие таких абстракций нисколько не напрягает.
G>Возьмем бухгалтерию. Там есть сущности — "проводки", "первичные документы" итп, и есть выборки — "балансы", "обороты", "остатки", которые являются основными задачами для эксперта (бухгалтера).
G>Получается что полноценный DDD невозможен в такой задаче?
ненене. Невозможно решить эту задачу в рамках только лишь domain. Но позволяя domain дергать за абстракции, реализованные в rest system, можно решить эту задачу в DDD духе. То что я называю это не вполне DDD — это проблемы моего восприятия. Рулит-то все-таки domain, но он уже не первичен, т.к. не впереди. В итоге driven, но не driven...
G>Тогда в чем вообще суть DDD? Для чего он нужен? Чем он помогает?
Domain-driven design not a technology or a methodology. It is a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains.
http://domaindrivendesign.org/node/120
Как я понимаю, DDD это еще один способ не свалить все в одну кучу. Причем неважно, поклонник DDD или нет, если в голову приходят мысли не завязывать сильно (tight) domain на инфраструктуру, то это уже вполне себе DDD.
Здравствуйте, Enomay, Вы писали:
G>>Возьмем бухгалтерию. Там есть сущности — "проводки", "первичные документы" итп, и есть выборки — "балансы", "обороты", "остатки", которые являются основными задачами для эксперта (бухгалтера).
G>>Получается что полноценный DDD невозможен в такой задаче?
E>выборки нужны эксперту, но не системе. для системы они вообще ничего не значат и на логику, в данном случае, никакого воздействия не оказывают. E>выборка — это не логика.
Скажу по секрету: 98% работы enterprise application — выборки. Тогда "логика" — оставшиеся 2%, и нафига спрашивается ради двух процентов весь огород?
G>>Тогда в чем вообще суть DDD? Для чего он нужен? Чем он помогает? E>DDD помогает структурировать приложение и вынести логику отдельным слоем.
Конкретнее, примеры. Как будет выглядеть отдельный слой? Какие в нем будут классы?
E>плюс доменный язык.
А вот тут вы сами себе противоречите, потому что эксперты как раз говорят на языке выборок, срезов атрибутов, а не целостных сущностей. Особенно явно это прослеживается в бухгалтерии.
E>>выборки нужны эксперту, но не системе. для системы они вообще ничего не значат и на логику, в данном случае, никакого воздействия не оказывают. E>>выборка — это не логика. G>Скажу по секрету: 98% работы enterprise application — выборки. Тогда "логика" — оставшиеся 2%, и нафига спрашивается ради двух процентов весь огород?
98% работы приложения, возможно, но не логики. соответственно, весь огород ради 100% логики, но не выборок.
E>>DDD помогает структурировать приложение и вынести логику отдельным слоем. G>Конкретнее, примеры. Как будет выглядеть отдельный слой? Какие в нем будут классы?
вам не кажется что вы от всех слишком много требуете?
примеры есть в книги Эванса. но каждый волен делать так, как считает нужным.
E>>плюс доменный язык. G>А вот тут вы сами себе противоречите, потому что эксперты как раз говорят на языке выборок, срезов атрибутов, а не целостных сущностей. Особенно явно это прослеживается в бухгалтерии.
эксперты говорят на языке объектов. это с реляционной точки зрения "остатки" — выборка. для эксперта — это 1 отчёт по остаткам.
Здравствуйте, samius, Вы писали:
G>>То есть получается что почти все нетривиальные выборки данных будут не-DDD, даже если именно они являются основными задачами с точки зрения Domain Expert. S>Это зависит от отношения к классификации. Как отступая от тру ООП в сторону процедурщины при создании сервиса (Эванс об этом пишет), мы остаемся в рамках ООП, так и при выпячивании абстракций впереди domain, можно считать что остаемся в рамках DDD. Как я понимаю, Ф. наличие таких абстракций нисколько не напрягает.
Отношение к классификации как раз очень хорошо видно если почитать материалы на дважды упомянутом сайте. Почти все сводится к тому что сервисы (то есть инкапсулированное поведение без данных) — плохо, а rich-сущности — хорошо. Хотя в терминологии действительно все гладко, там четко не указано как строить модель, там лишь указано что она должна соответствовать домену. Хотя если посмотреть DDD_шный pattern language, то он как раз основывается на rich model.
G>>Возьмем бухгалтерию. Там есть сущности — "проводки", "первичные документы" итп, и есть выборки — "балансы", "обороты", "остатки", которые являются основными задачами для эксперта (бухгалтера).
G>>Получается что полноценный DDD невозможен в такой задаче? S>ненене. Невозможно решить эту задачу в рамках только лишь domain. Но позволяя domain дергать за абстракции, реализованные в rest system, можно решить эту задачу в DDD духе. То что я называю это не вполне DDD — это проблемы моего восприятия. Рулит-то все-таки domain, но он уже не первичен, т.к. не впереди. В итоге driven, но не driven... я **й че понял
G>>Тогда в чем вообще суть DDD? Для чего он нужен? Чем он помогает? S>
S>Domain-driven design not a technology or a methodology. It is a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains.
S>http://domaindrivendesign.org/node/120 S>Как я понимаю, DDD это еще один способ не свалить все в одну кучу. Причем неважно, поклонник DDD или нет, если в голову приходят мысли не завязывать сильно (tight) domain на инфраструктуру, то это уже вполне себе DDD.
Domain нельзя завязать на инфраструктуру, а domain model вроде как можно и тогда это будет не DDD.
НО. Что такое domain model и что такое инфраструктура. Берем например задачу смешанного документооборота (который полубумажный, как в большинстве госструктур), основная сущность у нас это "карточка документа". Эксперты изначально работают с некоторыми "каталогами", которые 1-в-1 отображаются на хранилище данных.
Так вот использование транзакций хранилища в БЛ будет ли смешением или нет?
А если оно выполняется атрибутами на методах?
Какая степень "привязки" domain model к инфраструктуре критична для DDD?
Здравствуйте, Enomay, Вы писали:
E>>>выборки нужны эксперту, но не системе. для системы они вообще ничего не значат и на логику, в данном случае, никакого воздействия не оказывают. E>>>выборка — это не логика. G>>Скажу по секрету: 98% работы enterprise application — выборки. Тогда "логика" — оставшиеся 2%, и нафига спрашивается ради двух процентов весь огород?
E>98% работы приложения, возможно, но не логики. соответственно, весь огород ради 100% логики, но не выборок.
То есть логика это то что не выборки? Но её действительно мало в среднем приложении.
E>>>DDD помогает структурировать приложение и вынести логику отдельным слоем. G>>Конкретнее, примеры. Как будет выглядеть отдельный слой? Какие в нем будут классы? E>вам не кажется что вы от всех слишком много требуете? E>примеры есть в книги Эванса. но каждый волен делать так, как считает нужным.
Примеры в книге эванса я видел и многократно приводил недостатки которые они в себе несут. На что мне отвечали что ценой этих проблем появляются какие-то преимущества. Но никто не смогу показать код, который наглядно эти преимущества демонстрирует.
E>>>плюс доменный язык. G>>А вот тут вы сами себе противоречите, потому что эксперты как раз говорят на языке выборок, срезов атрибутов, а не целостных сущностей. Особенно явно это прослеживается в бухгалтерии. E>эксперты говорят на языке объектов.
Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд.
E>это с реляционной точки зрения "остатки" — выборка. для эксперта — это 1 отчёт по остаткам.
И что из этого объект? И как ты будешь создавать классы в программе чтобы они отражали то что говорит эксперт?
E>>98% работы приложения, возможно, но не логики. соответственно, весь огород ради 100% логики, но не выборок. G>То есть логика это то что не выборки? Но её действительно мало в среднем приложении.
значит в приложении действительно мало логики.
E>>вам не кажется что вы от всех слишком много требуете? E>>примеры есть в книги Эванса. но каждый волен делать так, как считает нужным. G>Примеры в книге эванса я видел и многократно приводил недостатки которые они в себе несут. На что мне отвечали что ценой этих проблем появляются какие-то преимущества. Но никто не смогу показать код, который наглядно эти преимущества демонстрирует.
если для тебя DDD это сплошные недостатки, то возможно ты не понял то, что хотел передать Эванс, и значит оно тебе не нужно.
не забивай этим голову.
E>>эксперты говорят на языке объектов. G>Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд.
это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели.
E>>это с реляционной точки зрения "остатки" — выборка. для эксперта — это 1 отчёт по остаткам. G>И что из этого объект? И как ты будешь создавать классы в программе чтобы они отражали то что говорит эксперт?
эти классы будут не более чем DTO, без какой либо логики, так любимый и почетаемый тобой тип.
Здравствуйте, Enomay, Вы писали:
E>>>98% работы приложения, возможно, но не логики. соответственно, весь огород ради 100% логики, но не выборок. G>>То есть логика это то что не выборки? Но её действительно мало в среднем приложении. E>значит в приложении действительно мало логики.
А как быть с приложениями, где для некоторого изменения данных требуется выборка?
Например, для принятия решения какую делать скидку клиенту требуется посчитать сумму купленных им товаров без скидки за последний месяц.
Опять интересует как такое делать в рамках DDD, но при этом сохраняя высокую эффективность кода.
E>>>вам не кажется что вы от всех слишком много требуете? E>>>примеры есть в книги Эванса. но каждый волен делать так, как считает нужным. G>>Примеры в книге эванса я видел и многократно приводил недостатки которые они в себе несут. На что мне отвечали что ценой этих проблем появляются какие-то преимущества. Но никто не смогу показать код, который наглядно эти преимущества демонстрирует.
E>если для тебя DDD это сплошные недостатки, то возможно ты не понял то, что хотел передать Эванс, и значит оно тебе не нужно. E>не забивай этим голову.
Да вот как раз интересно что же хотел передать Эванс. Ты сможешь объяснить?
E>>>эксперты говорят на языке объектов. G>>Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд.
E>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели.
таким образом ты теряешь Ubiquitous Language, про который как раз пишет эванс.
E>>>это с реляционной точки зрения "остатки" — выборка. для эксперта — это 1 отчёт по остаткам. G>>И что из этого объект? И как ты будешь создавать классы в программе чтобы они отражали то что говорит эксперт?
E>эти классы будут не более чем DTO, без какой либо логики, так любимый и почетаемый тобой тип.
А причем тут DTO если тебе нужна выборка? Ну сделать класс "баланс" у тебя от этого будет считаться баланс? Вот именно это ведь именно это интересует. Как ты сделаешь расчет баланса в DDD?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Это зависит от отношения к классификации. Как отступая от тру ООП в сторону процедурщины при создании сервиса (Эванс об этом пишет), мы остаемся в рамках ООП, так и при выпячивании абстракций впереди domain, можно считать что остаемся в рамках DDD. Как я понимаю, Ф. наличие таких абстракций нисколько не напрягает.
G>Отношение к классификации как раз очень хорошо видно если почитать материалы на дважды упомянутом сайте. Почти все сводится к тому что сервисы (то есть инкапсулированное поведение без данных) — плохо, а rich-сущности — хорошо. Хотя в терминологии действительно все гладко, там четко не указано как строить модель, там лишь указано что она должна соответствовать домену. Хотя если посмотреть DDD_шный pattern language, то он как раз основывается на rich model.
Да, рич там любят. Но если все-таки мы возьмем типичный DDD и логику из рич сущностей перетащим в сервисы домена (именно домена), то это формально все еще будет DDD. Атипичный, но DDD.
G>>>Возьмем бухгалтерию. Там есть сущности — "проводки", "первичные документы" итп, и есть выборки — "балансы", "обороты", "остатки", которые являются основными задачами для эксперта (бухгалтера).
G>>>Получается что полноценный DDD невозможен в такой задаче? S>>ненене. Невозможно решить эту задачу в рамках только лишь domain. Но позволяя domain дергать за абстракции, реализованные в rest system, можно решить эту задачу в DDD духе. То что я называю это не вполне DDD — это проблемы моего восприятия. Рулит-то все-таки domain, но он уже не первичен, т.к. не впереди. В итоге driven, но не driven... G> я **й че понял
Неважно. Если проводка как сущность/сервис домена будет использовать абстракцию для получения необходимых ей данных — то формально DDD ни что не противоречит.
S>>Как я понимаю, DDD это еще один способ не свалить все в одну кучу. Причем неважно, поклонник DDD или нет, если в голову приходят мысли не завязывать сильно (tight) domain на инфраструктуру, то это уже вполне себе DDD. G>Domain нельзя завязать на инфраструктуру, а domain model вроде как можно и тогда это будет не DDD.
Формально зависит от weak/strong coupling.
G>НО. Что такое domain model и что такое инфраструктура. Берем например задачу смешанного документооборота (который полубумажный, как в большинстве госструктур), основная сущность у нас это "карточка документа". Эксперты изначально работают с некоторыми "каталогами", которые 1-в-1 отображаются на хранилище данных. G>Так вот использование транзакций хранилища в БЛ будет ли смешением или нет?
Если отнести транзакцию хранилища к Model и выделить абстракцию, то смешения не будет. Если абстракцию не выделить — то будет смешение. Грань тонка, но тут у поклонников DDD больше значит не формальность, а взгляд на вещи.
G>А если оно выполняется атрибутами на методах?
X3
G>Какая степень "привязки" domain model к инфраструктуре критична для DDD?
DDD это способ мышления. Как и OOP. Критичным является отношение разработчика к вопросу.
Т.е. количественные оценки тут уместны ровно так же как и в случае определения степени OOP-шности.
Я работал в одном НИИ, так там куча народу считает что использует C++ когда переименовывают *.c в *.cpp и заменяют malloc на new. Когда их спрашиваешь, на чем вы программируете — они хором безаппеляционно заявляют что на C++. Я с ними не согласен, но это сугубо мои проблемы.
E>>>>98% работы приложения, возможно, но не логики. соответственно, весь огород ради 100% логики, но не выборок. G>>>То есть логика это то что не выборки? Но её действительно мало в среднем приложении. E>>значит в приложении действительно мало логики. G>А как быть с приложениями, где для некоторого изменения данных требуется выборка? G>Например, для принятия решения какую делать скидку клиенту требуется посчитать сумму купленных им товаров без скидки за последний месяц. G>Опять интересует как такое делать в рамках DDD, но при этом сохраняя высокую эффективность кода.
решение обычно принимается продавцом. вот ему и будет отображен список покупок, допустим, если требуется, за последний месяц, и, при необходимости, вывести надпись о том, что сумма перевалила за какую-то отметку. и на основании этого продавец примет решение делать скидку или нет.
и вот когда он её сделает, то даст комаду домену посчитать стоимость заказа с учетом скидки.
E>>если для тебя DDD это сплошные недостатки, то возможно ты не понял то, что хотел передать Эванс, и значит оно тебе не нужно. E>>не забивай этим голову. G>Да вот как раз интересно что же хотел передать Эванс. Ты сможешь объяснить?
это бессмысленно. еще раз повторю, если ты не понял что говорит Эванс, значит оно тебе не нужно. пользуйся тем подходом, который тебе ближе, проще, удобнее.
E>>>>эксперты говорят на языке объектов. G>>>Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд. E>>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели. G>таким образом ты теряешь Ubiquitous Language, про который как раз пишет эванс.
нет, я ничего не теряю того, что не должен потерять. если ты внимательней прочтешь книгу, то увидишь что много времени уделяется дистиляции. а это значит что мы должны отбросить лишние, не интересующие нас вещи, что собственно мы и делаем.
в данном случае, все эти отчеты не являются какой либо логикой, а лишь выборки с каким-то критериями. значит в доменной модели эти понятия нас не интересуют.
E>>эти классы будут не более чем DTO, без какой либо логики, так любимый и почетаемый тобой тип. G>А причем тут DTO если тебе нужна выборка? Ну сделать класс "баланс" у тебя от этого будет считаться баланс? Вот именно это ведь именно это интересует. Как ты сделаешь расчет баланса в DDD?
баланс это выборка? выборка.
значит будет 1 метод у какого-то абстрактного класса, который сделает select, вызовет хранимую или сделает выборку с помощью linq, и вернет результат. DDD тут совершенно не причем.
Здравствуйте, Enomay, Вы писали:
E>>>>>98% работы приложения, возможно, но не логики. соответственно, весь огород ради 100% логики, но не выборок. G>>>>То есть логика это то что не выборки? Но её действительно мало в среднем приложении. E>>>значит в приложении действительно мало логики. G>>А как быть с приложениями, где для некоторого изменения данных требуется выборка? G>>Например, для принятия решения какую делать скидку клиенту требуется посчитать сумму купленных им товаров без скидки за последний месяц. G>>Опять интересует как такое делать в рамках DDD, но при этом сохраняя высокую эффективность кода.
E>решение обычно принимается продавцом. вот ему и будет отображен список покупок, допустим, если требуется, за последний месяц, и, при необходимости, вывести надпись о том, что сумма перевалила за какую-то отметку. и на основании этого продавец примет решение делать скидку или нет. E>и вот когда он её сделает, то даст комаду домену посчитать стоимость заказа с учетом скидки.
Интернет-магазин, продавца нет.
E>>>если для тебя DDD это сплошные недостатки, то возможно ты не понял то, что хотел передать Эванс, и значит оно тебе не нужно. E>>>не забивай этим голову. G>>Да вот как раз интересно что же хотел передать Эванс. Ты сможешь объяснить? E>это бессмысленно. еще раз повторю, если ты не понял что говорит Эванс, значит оно тебе не нужно. пользуйся тем подходом, который тебе ближе, проще, удобнее.
Мне интересно понять что же такого говорил эванс. Преим ущества использования подхода должны быть явны и перевешивать недостатки если таковые имеются. Преимущества
E>>>>>эксперты говорят на языке объектов. G>>>>Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд. E>>>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели. G>>таким образом ты теряешь Ubiquitous Language, про который как раз пишет эванс.
E>нет, я ничего не теряю того, что не должен потерять. если ты внимательней прочтешь книгу, то увидишь что много времени уделяется дистиляции. а это значит что мы должны отбросить лишние, не интересующие нас вещи, что собственно мы и делаем.
Тем не менее эксперты говорят на другом языке, это не отбросишь.
E>в данном случае, все эти отчеты не являются какой либо логикой, а лишь выборки с каким-то критериями. значит в доменной модели эти понятия нас не интересуют.
Не важно что тебя интересует, важно чтобы с экспертом на одном языке говорили.
E>>>эти классы будут не более чем DTO, без какой либо логики, так любимый и почетаемый тобой тип. G>>А причем тут DTO если тебе нужна выборка? Ну сделать класс "баланс" у тебя от этого будет считаться баланс? Вот именно это ведь именно это интересует. Как ты сделаешь расчет баланса в DDD?
E>баланс это выборка? выборка. E>значит будет 1 метод у какого-то абстрактного класса, который сделает select, вызовет хранимую или сделает выборку с помощью linq, и вернет результат. DDD тут совершенно не причем.
То есть DDD не при чем основной части домена? Тогда в чем ценность DDD?
E>>решение обычно принимается продавцом. вот ему и будет отображен список покупок, допустим, если требуется, за последний месяц, и, при необходимости, вывести надпись о том, что сумма перевалила за какую-то отметку. и на основании этого продавец примет решение делать скидку или нет. E>>и вот когда он её сделает, то даст комаду домену посчитать стоимость заказа с учетом скидки. G>Интернет-магазин, продавца нет.
получили общую сумму покупок за последний месяц и передали доменной модели.
так же эту сумму можно получить из объекта самого покупателя.
всё зависит от организации модели.
E>>это бессмысленно. еще раз повторю, если ты не понял что говорит Эванс, значит оно тебе не нужно. пользуйся тем подходом, который тебе ближе, проще, удобнее. G>Мне интересно понять что же такого говорил эванс. Преим ущества использования подхода должны быть явны и перевешивать недостатки если таковые имеются. Преимущества
ты их не видишь. другие их видят. не заморачивайся. возможно это придет, со временем. а возможно и нет.
E>>>>>>эксперты говорят на языке объектов. G>>>>>Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд. E>>>>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели. G>>>таким образом ты теряешь Ubiquitous Language, про который как раз пишет эванс.
E>>в данном случае, все эти отчеты не являются какой либо логикой, а лишь выборки с каким-то критериями. значит в доменной модели эти понятия нас не интересуют. G>Не важно что тебя интересует, важно чтобы с экспертом на одном языке говорили.
мы и говорим на одном языке с экспертами. о тех вещах, которые нас интересуют. и не говорим о тех, которые нас не интересуют.
E>>баланс это выборка? выборка. E>>значит будет 1 метод у какого-то абстрактного класса, который сделает select, вызовет хранимую или сделает выборку с помощью linq, и вернет результат. DDD тут совершенно не причем. G>То есть DDD не при чем основной части домена? Тогда в чем ценность DDD?
DDD не имеет отношения к построению отчетов, точнее даже, обычных выборок.
ты еще форматирование HTML на DDD возложи.
ценность DDD в организации и построении бизнес логики.
Здравствуйте, samius, Вы писали:
S>Но если все-таки мы возьмем типичный DDD и логику из рич сущностей перетащим в сервисы домена (именно домена), то это формально все еще будет DDD. Атипичный, но DDD.
G>>Так вот использование транзакций хранилища в БЛ будет ли смешением или нет? S>Если отнести транзакцию хранилища к Model и выделить абстракцию, то смешения не будет. Если абстракцию не выделить — то будет смешение. Грань тонка, но тут у поклонников DDD больше значит не формальность, а взгляд на вещи.
G>>А если оно выполняется атрибутами на методах? S>X3
G>>Какая степень "привязки" domain model к инфраструктуре критична для DDD? S>DDD это способ мышления. Как и OOP. Критичным является отношение разработчика к вопросу. S>Т.е. количественные оценки тут уместны ровно так же как и в случае определения степени OOP-шности.
Как раз ООП больше про инструменты, вроде классов, объектов, инкапсуляции и полиморфизма. А вот как "взгляд" на вещи ООП не прижился, сильно свое понимание у каждого. Как например что от чего наследовать в паре "круг" и "эллипс".
Что же такое DDD? Вроде не pattern language, несмотря на то что аплогеты очень активно его насаждают, вроде не дизайн, вроде не способ анализа и не методология.
S>Я работал в одном НИИ, так там куча народу считает что использует C++ когда переименовывают *.c в *.cpp и заменяют malloc на new. Когда их спрашиваешь, на чем вы программируете — они хором безаппеляционно заявляют что на C++. Я с ними не согласен, но это сугубо мои проблемы.
Да и пусть считают, они же не пытаются других учить писать на С++.
Здравствуйте, Enomay, Вы писали:
E>>>решение обычно принимается продавцом. вот ему и будет отображен список покупок, допустим, если требуется, за последний месяц, и, при необходимости, вывести надпись о том, что сумма перевалила за какую-то отметку. и на основании этого продавец примет решение делать скидку или нет. E>>>и вот когда он её сделает, то даст комаду домену посчитать стоимость заказа с учетом скидки. G>>Интернет-магазин, продавца нет.
E>получили общую сумму покупок за последний месяц и передали доменной модели.
Где получили? Кто получили?
E>так же эту сумму можно получить из объекта самого покупателя.
Каким образом? Выполнить запрос к хранилищу? Покупатель будет иметь ссылку на repository?
Или ты предложишь циклом ходить по orders, загружая всю историю заказов в память? и выполняя SELECT N+1
E>всё зависит от организации модели.
Ок, покажи как эффективно организовать модель в таком случае.
E>>>это бессмысленно. еще раз повторю, если ты не понял что говорит Эванс, значит оно тебе не нужно. пользуйся тем подходом, который тебе ближе, проще, удобнее. G>>Мне интересно понять что же такого говорил эванс. Преим ущества использования подхода должны быть явны и перевешивать недостатки если таковые имеются. Преимущества E>ты их не видишь. другие их видят. не заморачивайся. возможно это придет, со временем. а возможно и нет.
Так ты их назови хотя бы, а то даже с этим проблемы возникают.
E>>>>>>>эксперты говорят на языке объектов. G>>>>>>Где вы таких экспертов нашли? У меня куча бухгалтеров среди родственников и все говорят про обороты, остатки, балансы, сметы итд. E>>>>>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели. G>>>>таким образом ты теряешь Ubiquitous Language, про который как раз пишет эванс.
E>>>в данном случае, все эти отчеты не являются какой либо логикой, а лишь выборки с каким-то критериями. значит в доменной модели эти понятия нас не интересуют. G>>Не важно что тебя интересует, важно чтобы с экспертом на одном языке говорили.
E>мы и говорим на одном языке с экспертами. о тех вещах, которые нас интересуют. и не говорим о тех, которые нас не интересуют.
Тогда вы делаете программу, которая нужна вам, а не пользователям.
А обычно наоборот, слушают заказчиков\экспертов\пользователей.
E>>>баланс это выборка? выборка. E>>>значит будет 1 метод у какого-то абстрактного класса, который сделает select, вызовет хранимую или сделает выборку с помощью linq, и вернет результат. DDD тут совершенно не причем. G>>То есть DDD не при чем основной части домена? Тогда в чем ценность DDD?
E>DDD не имеет отношения к построению отчетов, точнее даже, обычных выборок.
То есть не имеет отношение к домену (той самой предметной области о которой тебе скажут бухгалтеры).
E>ценность DDD в организации и построении бизнес логики.
Так получение баланса и других данных для отчетов и есть та логика, которая нужна бизнесу. У тебя другое понимание бизнес-логики?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Какая степень "привязки" domain model к инфраструктуре критична для DDD? S>>DDD это способ мышления. Как и OOP. Критичным является отношение разработчика к вопросу. S>>Т.е. количественные оценки тут уместны ровно так же как и в случае определения степени OOP-шности.
G>Как раз ООП больше про инструменты, вроде классов, объектов, инкапсуляции и полиморфизма. А вот как "взгляд" на вещи ООП не прижился, сильно свое понимание у каждого. Как например что от чего наследовать в паре "круг" и "эллипс".
Вполне себе взгляд. Я могу взглянуть на WinAPI и посчитать "вполне себе ООП по Кею". Либо посмотреть на double и увидеть что он может принимать сообщения `+`(1), что он инкапсулирует состояние меняющееся при сообщении `=`(x).
Я не хочу спорить по этому поводу. Если сам Эванс говорит что DDD это не методология, то
G>Что же такое DDD? Вроде не pattern language, несмотря на то что аплогеты очень активно его насаждают, вроде не дизайн, вроде не способ анализа и не методология.
Пусть будет взглядом на организацию кода, а не на вещи.
S>>Я работал в одном НИИ, так там куча народу считает что использует C++ когда переименовывают *.c в *.cpp и заменяют malloc на new. Когда их спрашиваешь, на чем вы программируете — они хором безаппеляционно заявляют что на C++. Я с ними не согласен, но это сугубо мои проблемы. G>Да и пусть считают, они же не пытаются других учить писать на С++.
Еще как пытаются учить
E>>получили общую сумму покупок за последний месяц и передали доменной модели. G>Где получили? Кто получили?
тот, кто обращается к доменной модели.
E>>так же эту сумму можно получить из объекта самого покупателя. G>Каким образом? Выполнить запрос к хранилищу? Покупатель будет иметь ссылку на repository?
покупатель будет сформирован с полным набором необходимых данных при помощи доменного сервиса.
G>Или ты предложишь циклом ходить по orders, загружая всю историю заказов в память? и выполняя SELECT N+1
если доменная логика потребует проходиться циклом по ордерам, то так и будет.
и да, для этого необходимое кол-во ордеров будет загружено в память.
и да, вероятно будет select n+1.
это криминально? в бизнес приложениях — нет. в высоконагруженном сайте? возможно.
E>>всё зависит от организации модели. G>Ок, покажи как эффективно организовать модель в таком случае.
нужно исходить из задачи. а не абстрактного выдуманного примера.
и эффективная модель в каждом отдельном случаи будет различаться.
E>>ты их не видишь. другие их видят. не заморачивайся. возможно это придет, со временем. а возможно и нет. G>Так ты их назови хотя бы, а то даже с этим проблемы возникают.
преимущества в организации слоя бизнес логики, который отражает действительную проблему.
E>>мы и говорим на одном языке с экспертами. о тех вещах, которые нас интересуют. и не говорим о тех, которые нас не интересуют. G>Тогда вы делаете программу, которая нужна вам, а не пользователям. G>А обычно наоборот, слушают заказчиков\экспертов\пользователей.
тебе так кажется.
мы проектируем доменную модель, а значит логику. то, что в этой логике на текущий момент не используется, мы не рассматриваем.
но это не значит что нет других разработчиков, которые бездумно клепают отчеты.
E>>DDD не имеет отношения к построению отчетов, точнее даже, обычных выборок. G>То есть не имеет отношение к домену (той самой предметной области о которой тебе скажут бухгалтеры).
отображение отчета какого либо отчета, совершенно никак не влияет на алгоритм расчета зарплат, под который мы делаем доменную модель, а значит, в данном случае, это нас не интересует.
E>>ценность DDD в организации и построении бизнес логики. G>Так получение баланса и других данных для отчетов и есть та логика, которая нужна бизнесу. У тебя другое понимание бизнес-логики?
бизнесу нужна логика расчета данных, а их получение и отображение — это лишь следствие, и к логике никакого отношения уже не имеет.
Здравствуйте, Enomay, Вы писали:
E>>>получили общую сумму покупок за последний месяц и передали доменной модели. G>>Где получили? Кто получили?
E>тот, кто обращается к доменной модели.
E>>>так же эту сумму можно получить из объекта самого покупателя. G>>Каким образом? Выполнить запрос к хранилищу? Покупатель будет иметь ссылку на repository?
E>покупатель будет сформирован с полным набором необходимых данных при помощи доменного сервиса.
Да, при помощи сервиса, а сущность "покупателя" будет DTO. Это уже похоже на нормальный дизайн.
А он соотвествует DDD?
G>>Или ты предложишь циклом ходить по orders, загружая всю историю заказов в память? и выполняя SELECT N+1
E>если доменная логика потребует проходиться циклом по ордерам, то так и будет. E>и да, для этого необходимое кол-во ордеров будет загружено в память. E>и да, вероятно будет select n+1. E>это криминально? в бизнес приложениях — нет. в высоконагруженном сайте? возможно.
Значит DDD позволяет делать только тормозящее говно
Что и требовалось доказать.
Шучу конечно, но ощущение складывается именно такое.
E>>>всё зависит от организации модели. G>>Ок, покажи как эффективно организовать модель в таком случае.
E>нужно исходить из задачи. а не абстрактного выдуманного примера.
Расчет скидки — не выдуманный пример.
E>и эффективная модель в каждом отдельном случаи будет различаться.
Представь что такой же код находится внутри CRM, где для каждого кастомера сотни заказов и десятки тысяч позиций.
E>>>ты их не видишь. другие их видят. не заморачивайся. возможно это придет, со временем. а возможно и нет. G>>Так ты их назови хотя бы, а то даже с этим проблемы возникают. E>преимущества в организации слоя бизнес логики, который отражает действительную проблему.
Так в чем это преимущество?
Ты сейчас пытаешься мне показать в случая с бухгалтерией построение слоя бизнес-логики, который как раз действительные проблемы не отражает.
E>>>мы и говорим на одном языке с экспертами. о тех вещах, которые нас интересуют. и не говорим о тех, которые нас не интересуют. G>>Тогда вы делаете программу, которая нужна вам, а не пользователям. G>>А обычно наоборот, слушают заказчиков\экспертов\пользователей. E>тебе так кажется.
Ну конечно, только мне кажется что сделать успешный продукт можно только учитывая пожелания пользователей.
E>>>DDD не имеет отношения к построению отчетов, точнее даже, обычных выборок. G>>То есть не имеет отношение к домену (той самой предметной области о которой тебе скажут бухгалтеры).
E>отображение отчета какого либо отчета, совершенно никак не влияет на алгоритм расчета зарплат, под который мы делаем доменную модель, а значит, в данном случае, это нас не интересует.
А я не говорю про отображение, я говорю про получение данных. Баланс может и не отображаться, а сразу отправляться в налоговую.
E>>>ценность DDD в организации и построении бизнес логики. G>>Так получение баланса и других данных для отчетов и есть та логика, которая нужна бизнесу. У тебя другое понимание бизнес-логики? E>бизнесу нужна логика расчета данных, а их получение и отображение — это лишь следствие, и к логике никакого отношения уже не имеет.
Так я с этого и начал. Вот есть у бухгалтеров баланс, это не балансовая ведомость, а некоторые данные, соотвествующие определенным правилам. еще есть обороты, остатки — тоже наборы данных, формирующиеся по определенным правилам. Как и правильно отражать в программе с точки зрения DDD?
По сути они все являются выборками определенного вида.
G>select n+1 это проблема реализации, когда для получения дочерних сущностей необходимо выполнять по одному запросу в базу (удаленному вызову) для каждой родительской.
именно так. но никто, совершенно никто, не мешает делать выборку с join'ами, а после использовать её в DDD. одно другого совершенно не исключает.
Здравствуйте, Enomay, Вы писали:
E>DDD не предназначено для хоумпейджей, форумов, и в принципе, интернет магазинов. эта методология, как и всё остальное, не является серебряной пулей, и не может решать всех задач. но там, где это необходимо, DDD себя отлично показывает. E>Эванс, между прочим, об этом говорил.
Да, но они и другие не говорят для чего предназначен DDD. Потому что чем сложнее предметная область, там больше будет в ней выборок, для которых DDD не предназначен. Бухгалтерия — хороший пример.
E>>>нужно исходить из задачи. а не абстрактного выдуманного примера. G>>Расчет скидки — не выдуманный пример.
E>в этом нет ничего сложного даже применяя DDD методологию.
Ну ты уже показал что сделать это по DDD и эффективно нельзя? Или можно?
E>>>и эффективная модель в каждом отдельном случаи будет различаться. G>>Представь что такой же код находится внутри CRM, где для каждого кастомера сотни заказов и десятки тысяч позиций.
E>не представляю, потому что нет ни условий, ни задачи. значит представлять нечего. E>а для каждой конкретно задачи, существует отдельное, и не одно, решение.
Так задача простая: для расчета скидки покупателя надо получить сумму покупок без скидок за последний месяц.
G>>Так в чем это преимущество? G>>Ты сейчас пытаешься мне показать в случая с бухгалтерией построение слоя бизнес-логики, который как раз действительные проблемы не отражает.
E>преимущество применения DDD методологии в более красивом и структурированном объектно-ориентированном коде, который собой отражает проблему и её решение. E>это же очевидно. E>но я тебе уже советовал не заморачиваться, а продолжать использовать процедурный подход. он больше тебе подходит.
Что значит "красивом и структурированом"? Это в каких цифрах выражается, хотябы косвенно?
Кроме того "красивый и структурированный" ОО-код может вести к проблемам быстродейтсвия, это ты и сам показал.
Тогда в чем преимущество "красивости и структурированности"?
E>>>тебе так кажется. G>>Ну конечно, только мне кажется что сделать успешный продукт можно только учитывая пожелания пользователей.
E>DDD методология совершенно не обходит стороной пожелания пользователей. а наоборот. работает с ними на одном языке. E>а ты что-то опять путаешь.
Так ты мне доказывал что не надо учитывать "неудобные для DDD" требования пользователей. Как учесть требования получения в программе остатков и оборов по счетам для бухгалтерии? Ведь остатки и обороты это не сущности, а наборы данных.
E>>>отображение отчета какого либо отчета, совершенно никак не влияет на алгоритм расчета зарплат, под который мы делаем доменную модель, а значит, в данном случае, это нас не интересует. G>>А я не говорю про отображение, я говорю про получение данных. Баланс может и не отображаться, а сразу отправляться в налоговую.
E>получение данных — это лишь запрос в базу. сами данные при этом не меняются. а значит никакой логики в этом действии нет.
То есть "логика" это изменение данных? А если частью логики являются такие запросы?
Например те же самые скидки.
E>>>бизнесу нужна логика расчета данных, а их получение и отображение — это лишь следствие, и к логике никакого отношения уже не имеет. G>>Так я с этого и начал. Вот есть у бухгалтеров баланс, это не балансовая ведомость, а некоторые данные, соотвествующие определенным правилам. еще есть обороты, остатки — тоже наборы данных, формирующиеся по определенным правилам. Как и правильно отражать в программе с точки зрения DDD? G>>По сути они все являются выборками определенного вида.
E>они могут быть чем угодно. E>как выборками, в твоём случаи, E>так и просто полем объекта, которое изменяется каждый раз с приходом/уходом денег. соответственно нам нет необходимости пересчитывать баланс каждый раз. мы можем использовать готовое значение в нашей модели. проще говоря, для примера, это будет состояние объекта "баланс".
Это понятно, а как это будет выражаться в коде с точки зрения DDD?
Здравствуйте, Enomay, Вы писали:
G>>select n+1 это проблема реализации, когда для получения дочерних сущностей необходимо выполнять по одному запросу в базу (удаленному вызову) для каждой родительской.
E>именно так. но никто, совершенно никто, не мешает делать выборку с join'ами, а после использовать её в DDD. одно другого совершенно не исключает.
А куда эту выборку поместить? Ведь в сущностях иметь ссылку на repository — моветон, а если в сервисы, то получится anemic.
E>>Эванс, между прочим, об этом говорил. G>Да, но они и другие не говорят для чего предназначен DDD. Потому что чем сложнее предметная область, там больше будет в ней выборок, для которых DDD не предназначен. Бухгалтерия — хороший пример.
выборка не есть логика.
проблема совершенно не в DDD, а в непонимании тобой это методологии.
в очередной раз советую вернутся к процедурному программированию и не забивать голову лишними вещами.
E>>в этом нет ничего сложного даже применяя DDD методологию. G>Ну ты уже показал что сделать это по DDD и эффективно нельзя? Или можно?
конечно можно.
E>>не представляю, потому что нет ни условий, ни задачи. значит представлять нечего. E>>а для каждой конкретно задачи, существует отдельное, и не одно, решение. G>Так задача простая: для расчета скидки покупателя надо получить сумму покупок без скидок за последний месяц.
решение не менее простое.
E>>преимущество применения DDD методологии в более красивом и структурированном объектно-ориентированном коде, который собой отражает проблему и её решение. E>>это же очевидно. E>>но я тебе уже советовал не заморачиваться, а продолжать использовать процедурный подход. он больше тебе подходит. G>Что значит "красивом и структурированом"? Это в каких цифрах выражается, хотябы косвенно?
не все можно выразить цифрами.
G>Кроме того "красивый и структурированный" ОО-код может вести к проблемам быстродейтсвия, это ты и сам показал.
иногда. но в большинстве случаев он легче масштабируется, что решает проблемы быстродействия.
G>Тогда в чем преимущество "красивости и структурированности"?
в том же, в чем и любого другого хорошего кода, конечно же.
неужели это так не очевидно?
E>>DDD методология совершенно не обходит стороной пожелания пользователей. а наоборот. работает с ними на одном языке. E>>а ты что-то опять путаешь. G>Так ты мне доказывал что не надо учитывать "неудобные для DDD" требования пользователей. Как учесть требования получения в программе остатков и оборов по счетам для бухгалтерии? Ведь остатки и обороты это не сущности, а наборы данных.
ты глупости говоришь.
я не доказывал, но пытался дать понять, что те вещи, которые не требуются при разработке модели, нужно опускать.
и остатки и обороты можно представить сущностями, пользуясь DDD методологией. но ты идешь от обратного, потому для тебя это наборы данных, и DDD скорее всего, как и ООП в целом, ты понять не сможешь, так как мыслишь с "процедурной" точки зрения.
E>>получение данных — это лишь запрос в базу. сами данные при этом не меняются. а значит никакой логики в этом действии нет. G>То есть "логика" это изменение данных? А если частью логики являются такие запросы? G>Например те же самые скидки.
для расчета скидки, нам нужно знать, делать её, или нет. как мы получим этот признак, нас не итересует.
ты сделаешь выборку в очередной раз, и передашь это значение.
кто-то другой возьмет готовый признак из объекта покупателя, который туда заносится после каждой совершенной покупки, и не требует пересчета каждый раз, как в твоём случае.
вариантов достаточное кол-во.
и ни один из них не делает DDD лучше или хуже.
E>>они могут быть чем угодно. E>>как выборками, в твоём случаи, E>>так и просто полем объекта, которое изменяется каждый раз с приходом/уходом денег. соответственно нам нет необходимости пересчитывать баланс каждый раз. мы можем использовать готовое значение в нашей модели. проще говоря, для примера, это будет состояние объекта "баланс". G>Это понятно, а как это будет выражаться в коде с точки зрения DDD?
так, как ты это реализуешь.
самые простые 2 варианта, на которые собственно должно было натолкнуть предыдущее предложение.
а) сервис расчитывает баланс и передает его доменному объекту при его создании, после чего тот выполняет свою логику с учетом этих данных
б) загружаем доменный объект из базы при помощи ORM и передаем ему управление.
оба варианта очень похожи, и по сути одинаковы, различия лишь в реализации.
и того имеем все данные и логику в доменной модели, что не противоречит DDD.
E>>именно так. но никто, совершенно никто, не мешает делать выборку с join'ами, а после использовать её в DDD. одно другого совершенно не исключает.
G>А куда эту выборку поместить? Ведь в сущностях иметь ссылку на repository — моветон, а если в сервисы, то получится anemic.
anemic получится лишь в том случаи, если в модели не будет логики, а вся она будет в сервисах. в данном же случаи, в сервисах нет бизнес логики. там только загрузка данных. вся логика в модели.
впрочем, по DDD, доменные сервисы вполне себе могут нести эту самую логику, если так будет необходимо. в том числе и подгрузку данных. а сервисы можно вызывать из доменных объектов.
впрочем, о том, что использования репозиториев в объектах домена — моветон, выдумки, ведь ни Фаулер, ни Эванс, об этом ничего не пишут.
а репозиторий не более чем коллекция, с точки зрения использования. а ведь коллекции нам никто не запрещает юзать в домене.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, Enomay, Вы писали:
E>>и того имеем все данные и логику в доменной модели, что не противоречит DDD. G>Она становится размазанной по нескольким объектам. Материализация объектов избыточна получается в данном случае, она нужна только чтобы вызывать логику. Тогда логику лучше поместить вне этих объектов.
Мало материализовать, надо еще и напичкать ссылками на используемые в логике объекта сервисы, репозитории...
E>>выборка не есть логика. G>То есть логика только в изменении данных?
вывод списка строк не есть логика.
G>Тогда задача получения суммы покупок для расчета скидки не является логикой, а сам расчет скидки является?
получение суммы покупок — это извлечение одного поля из базы данных.
это логика?
G>Какая-то фейерическая глупость чтобы оправдать проблемы.
какие проблемы? у меня нет проблем. для меня DDD вполне эффективная методология.
для тебя нет. но ты пытаешься, пыжишься. для чего только, не ясно.
E>>проблема совершенно не в DDD, а в непонимании тобой это методологии. G>Ну так попытайся объяснить в чем состоит методология DDD.
Эванс пытался. если у него не удалось, то у меня не выйдет тем более.
да и незачем мне этим заниматься.
G>Каким образом? G>Покажи его, чтобы оно было DDD и при этом достаточно эффективно.
я уже приводил пару возможных примеров.
E>>не все можно выразить цифрами. G>Если ты не можешь выразить цифрами значит в этом нет реального value.
ты наверное один из тех, кто эффективность разработчика меряет кол-вом строк кода?
G>Как раз в большинстве случаев ОО-код хуже масштабируется. Потому что: G>1) Надо таскать identity G>2) Надо материализовывать объекты потому что поведение внутри объектов
какое это имеет отношение к масштабированию?
G>Очень хорошо масштабируется SOA, причем как вверх, так и вниз. Там как раз отказ от identity и создания объектов, там только сервисы и данные (DTO).
вертикальное масштабирование имеет предел.
E>>в том же, в чем и любого другого хорошего кода, конечно же. E>>неужели это так не очевидно? G>Совсем не очевидно, потому что понятие "красивости" у каждого сильно свое и никак не коррелирует с качеством кода (объемом, плотностью багов, сложностью поддержки итп).
разве я говорил о эстетической красоте?
конечно же имелось ввиду простота поддержки и расширения существующего кода. а для этого он должен быть не похож на говно.
E>>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели. G>Ты сказал что то что говорят эксперты не надо рассматривать при построении модели.
ты опять говоришь глупости и перевираешь мои слова. перечитай еще раз про дистилляцию.
E>>я не доказывал, но пытался дать понять, что те вещи, которые не требуются при разработке модели, нужно опускать. G>Если о чем-то говорит эксперт, то это должно быть в модели, потому что иначе не будет Ubiquitous Language, к которому стремится DDD. G>Иначе вам придется переучивать эксперта, а это сложно.
прочти книгу Эванса, и убедись в том, что написанное тобой лишь плод твоего воображения.
он там приводит отличные примеры того, когда они накосячили из-за того, что слушали всё подряд.
E>>и остатки и обороты можно представить сущностями, пользуясь DDD методологией. но ты идешь от обратного, потому для тебя это наборы данных, и DDD скорее всего, как и ООП в целом, ты понять не сможешь, так как мыслишь с "процедурной" точки зрения. G>Ну покажи как их представить сущностями и как с ними работать в программе. (у тебя получится anemic)
у тебя получится anemic, у меня будет домен.
E>>для расчета скидки, нам нужно знать, делать её, или нет. как мы получим этот признак, нас не итересует. G>Нам важна величина скидки, а не вопрос делать её или нет.
это в данном случае не важно. мы можем передать признак, можем передать число, равняющееся сумме предыдущих покупок, на основании которого будем делать скидку.
в обоих случаях подход и суть та же.
E>>а) сервис расчитывает баланс и передает его доменному объекту при его создании, после чего тот выполняет свою логику с учетом этих данных G>Браво, расчет скидки размазан по двум объектам.
нет, расчет скидки реализуется одним объектом.
E>>б) загружаем доменный объект из базы при помощи ORM и передаем ему управление. G>Какой объект, нет объекта "скидка", потому что она требует расчета на момент покупки.
ты очень невнимателен. а ведь я уже писал.
проще говоря, добавь покупателю поле с суммой покупок, и получай её сразу с покупателем.
можешь хранить его целиком, можешь расчитывать на момент получения покупателя. (в твоём случае ты ведь и будешь его всегда считать).
она же и будет использоваться для расчета скидки этого покупателя.
E>>оба варианта очень похожи, и по сути одинаковы, различия лишь в реализации. G>И оба они хуже, чем помещение всего алгоритма расчета в сервис.
хуже для тебя. потому что процедурный стиль программирования тебе ближе.
в целом же, с точки зрения ООП, это правильная реализация. а DDD как раз более чем придерживается ООП парадигмы.
E>>и того имеем все данные и логику в доменной модели, что не противоречит DDD. G>Она становится размазанной по нескольким объектам. Материализация объектов избыточна получается в данном случае, она нужна только чтобы вызывать логику. Тогда логику лучше поместить вне этих объектов.
для того что бы наложить какую-то логику на что-то, тебе это что-то нужно получить.
в твоём случае это будет anemic модель. но её так же придется материализовать.
верно и обратное, что в DDD не всегда и всё необходимо материализовывать. при необходимости, мы без проблем можем вызвать сервис, который сделает update с условием.
насчет размазывания логики по нескольки объектам, ну так это ж банальный принцип "ответственности" из SOLID, да и ООП в целом. так что это правильная реализация.
Здравствуйте, Enomay, Вы писали:
E>>>именно так. но никто, совершенно никто, не мешает делать выборку с join'ами, а после использовать её в DDD. одно другого совершенно не исключает.
G>>А куда эту выборку поместить? Ведь в сущностях иметь ссылку на repository — моветон, а если в сервисы, то получится anemic.
E>anemic получится лишь в том случаи, если в модели не будет логики, а вся она будет в сервисах. в данном же случаи, в сервисах нет бизнес логики. там только загрузка данных. вся логика в модели. E>впрочем, по DDD, доменные сервисы вполне себе могут нести эту самую логику, если так будет необходимо. в том числе и подгрузку данных. а сервисы можно вызывать из доменных объектов.
Вот, прекрасно. Получяется схема
[сервисы -> доменные объекты -> доменные сервисы] причем последние как раз не содержат данных и обращаются к данным доменных объектов
тогда лучше убрать лишние уровни косвенности и получить
[сервисы -> доменные сервисы], сервисы будут получать данные из базы и передавать доменным сервисам
тогда в большинстве случаев можно поместить код доменных сервисов в сами сервисы, а вместо получения доменных объектов получать проекции из базы, содержащие ровно столько данных сколько необходимо. Таким образом часть вычислений можно также перенести в БД, заставляя запросы делать агрегацию данных. И это будет максимально эффективным решением.
E>впрочем, о том, что использования репозиториев в объектах домена — моветон, выдумки, ведь ни Фаулер, ни Эванс, об этом ничего не пишут.
Фаулер пишет, почитай внимательно главу про Domain Model в PoEAA
E>а репозиторий не более чем коллекция, с точки зрения использования. а ведь коллекции нам никто не запрещает юзать в домене.
Ага, добавляй ссылки на репозитарии к доменным объектам, получай ball-of-mud архитектуру.
Здравствуйте, gandjustas, Вы писали:
I>>select n+1 это проблема не ДДД, а предметной области. Ты никуда от неё не денешься. G>Полнейший бред. select n+1 это проблема реализации, когда для получения дочерних сущностей необходимо выполнять по одному запросу в базу (удаленному вызову) для каждой родительской. Если написать один запрос, который получает все данные, то это работает на порядок эффективнее.
То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ? Я немного не точно выразился, selеct n+1 это проблема реализации, но это пробема вторичная, реальная причина в самой предметной области, т.е. в той задаче которую хочет решить заказчик — слишком большой объём выборки для вычисления определенной функции. Слишкой большой это относительно возможностей современных технологий.
Какой бы инструмент ты не выбрал, там будет тоже самое — слишком большой объём выборки для вычисления определенной функции.
I>>Преимущество заключается в том, что все операции которые зависят от домена, становятся предельно простыми. G>За счет чего? Приведи пример.
См. пример про смешение цветов в книге Эванса.
G>>>Ну конечно, только мне кажется что сделать успешный продукт можно только учитывая пожелания пользователей. I>>С таким подходом можно делать только хилые продукты. Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг G>Ты хочешь сказать что можно сделать хороший продукт не учитывая пожелания пользователей?
Все что я хотел сказать, я уже сказал : "Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг"
Хочешь опровергнуть это, покажи пример грузового-легкового минивена-родстера
I>>Тебе покажется странным, но ДДД очень сильно похоже на то, что на этом форуме называется "функциональный дизайн". G>Вполне может быть что это так, вот только об этом никто не говорит. Или у тебя есть ссылки на подобные высказывания со стороны апологетов DDD?
Здравствуйте, Enomay, Вы писали:
E>>>выборка не есть логика. G>>То есть логика только в изменении данных?
E>вывод списка строк не есть логика.
А я не говорил про вывод, я говорю что выборка нужна для расчета суммы скидки, сами строки никуда не выводятся.
G>>Тогда задача получения суммы покупок для расчета скидки не является логикой, а сам расчет скидки является?
E>получение суммы покупок — это извлечение одного поля из базы данных. E>это логика?
Не одного, а суммы множества полей по определенным критериям. Хранить ты его не можешь, как как нужна сумма за месяц с текущего момента.
G>>Какая-то фейерическая глупость чтобы оправдать проблемы.
E>какие проблемы? у меня нет проблем. для меня DDD вполне эффективная методология.
В чем её эффективность? Есть выражение этой эффективности в цифрах? Я пока вижу проблемы с быстродейтсвием.
E>для тебя нет. но ты пытаешься, пыжишься. для чего только, не ясно.
Эффективность или есть или её нет, не бывает что для кого-то она есть, а для другого нет.
E>>>проблема совершенно не в DDD, а в непонимании тобой это методологии. G>>Ну так попытайся объяснить в чем состоит методология DDD. E>Эванс пытался. если у него не удалось, то у меня не выйдет тем более. E>да и незачем мне этим заниматься.
То есть ты не знаешь в чем заключается методология DDD?
G>>Каким образом? G>>Покажи его, чтобы оно было DDD и при этом достаточно эффективно. E>я уже приводил пару возможных примеров.
Оба гораздо менее эффективны чем могли бы быть.
E>>>не все можно выразить цифрами. G>>Если ты не можешь выразить цифрами значит в этом нет реального value. E>ты наверное один из тех, кто эффективность разработчика меряет кол-вом строк кода?
Нет, я один из тех для кого эффективность разработчика меряется количеством заработанных денег. Причем если зарабатыввает много денег, но пишет мало кода то это очень хорошо.
G>>Как раз в большинстве случаев ОО-код хуже масштабируется. Потому что: G>>1) Надо таскать identity G>>2) Надо материализовывать объекты потому что поведение внутри объектов E>какое это имеет отношение к масштабированию?
Самое прямое.
G>>Очень хорошо масштабируется SOA, причем как вверх, так и вниз. Там как раз отказ от identity и создания объектов, там только сервисы и данные (DTO).
E>вертикальное масштабирование имеет предел.
Я не про масштабирование ресурсов, я про масштабрирование задачи. SOA-подход работает как на простой задаче, выполняющийся на одной машине, так и в сильно распределенной среде. В отличие от ООП. Объекты распределять крайне неэффективно.
E>>>в том же, в чем и любого другого хорошего кода, конечно же. E>>>неужели это так не очевидно? G>>Совсем не очевидно, потому что понятие "красивости" у каждого сильно свое и никак не коррелирует с качеством кода (объемом, плотностью багов, сложностью поддержки итп).
E>разве я говорил о эстетической красоте? E>конечно же имелось ввиду простота поддержки и расширения существующего кода. а для этого он должен быть не похож на говно.
В среднем anemic кода получается меньше, чем rich при той же задаче. О какой простоте поддержки ты говоришь?
E>>>это и есть предметы разговора, которые можно включить в язык, при необходимости, если над ними происходят какие-то действия. если они нужны только конечному пользователю, то в таком виде они могут не рассматриваются при построении доменной модели. G>>Ты сказал что то что говорят эксперты не надо рассматривать при построении модели. E>ты опять говоришь глупости и перевираешь мои слова. перечитай еще раз про дистилляцию.
Читал, и что? Дистиллируй сколько хочешь, но если эксперт говорит что-то, то это надо или учитывать в модели или переучивать эксперта.
E>>>я не доказывал, но пытался дать понять, что те вещи, которые не требуются при разработке модели, нужно опускать. G>>Если о чем-то говорит эксперт, то это должно быть в модели, потому что иначе не будет Ubiquitous Language, к которому стремится DDD. G>>Иначе вам придется переучивать эксперта, а это сложно.
E>прочти книгу Эванса, и убедись в том, что написанное тобой лишь плод твоего воображения. E>он там приводит отличные примеры того, когда они накосячили из-за того, что слушали всё подряд.
Думаешь если не слушать все вероятность ошибок уменьшится? Думаешь если ты при построении модели для бухгалтерии отбросишь обороты и потом совершенно случайно не сделаешь их, то пользователи останутся довольны?
E>>>и остатки и обороты можно представить сущностями, пользуясь DDD методологией. но ты идешь от обратного, потому для тебя это наборы данных, и DDD скорее всего, как и ООП в целом, ты понять не сможешь, так как мыслишь с "процедурной" точки зрения. G>>Ну покажи как их представить сущностями и как с ними работать в программе. (у тебя получится anemic) E>у тебя получится anemic, у меня будет домен.
Приведи пример, посмотрим.
E>>>для расчета скидки, нам нужно знать, делать её, или нет. как мы получим этот признак, нас не итересует. G>>Нам важна величина скидки, а не вопрос делать её или нет.
E>это в данном случае не важно. мы можем передать признак, можем передать число, равняющееся сумме предыдущих покупок, на основании которого будем делать скидку.
Это как раз важно, откуда мы передадим это число?
E>проще говоря, добавь покупателю поле с суммой покупок, и получай её сразу с покупателем.
Нельзя, потому что требуется сумма покупок за последний месяц, то есть вычисление на момент покупки, хранить значение ты не сможешь.
E>>>оба варианта очень похожи, и по сути одинаковы, различия лишь в реализации. G>>И оба они хуже, чем помещение всего алгоритма расчета в сервис. E>хуже для тебя. потому что процедурный стиль программирования тебе ближе. E>в целом же, с точки зрения ООП, это правильная реализация. а DDD как раз более чем придерживается ООП парадигмы.
То есть единственная цель "придерживаться ООП парадигмы" чего бы оно не стоило?
E>>>и того имеем все данные и логику в доменной модели, что не противоречит DDD. G>>Она становится размазанной по нескольким объектам. Материализация объектов избыточна получается в данном случае, она нужна только чтобы вызывать логику. Тогда логику лучше поместить вне этих объектов. E>для того что бы наложить какую-то логику на что-то, тебе это что-то нужно получить. E>в твоём случае это будет anemic модель. но её так же придется материализовать.
В данном случае мне надо получить число. Ровно одно число, и все. Мне не нужен объект кастомера со всеми его свойствами чтобы считать скидку.
E>верно и обратное, что в DDD не всегда и всё необходимо материализовывать. при необходимости, мы без проблем можем вызвать сервис, который сделает update с условием.
Да, и это уже будет anemic, потому что есть сервис и нет "доменных объектов".
E>насчет размазывания логики по нескольки объектам, ну так это ж банальный принцип "ответственности" из SOLID, да и ООП в целом. так что это правильная реализация.
В SOLID куча других принципов, да и за пределами SOLID тоже, и DDD, как его описывает эванс, многое нарушает.
E>>получение суммы покупок — это извлечение одного поля из базы данных. E>>это логика? G>Не одного, а суммы множества полей по определенным критериям.
да это не важно в общем-то. доменная модель имеет эти сведения.
G>Хранить ты его не можешь, как как нужна сумма за месяц с текущего момента.
в сиквеле, нет, в документной базе, без проблем в общем-то.
G>>>Какая-то фейерическая глупость чтобы оправдать проблемы.
E>>какие проблемы? у меня нет проблем. для меня DDD вполне эффективная методология. G>В чем её эффективность? Есть выражение этой эффективности в цифрах? Я пока вижу проблемы с быстродейтсвием.
это от того, что ты не понимаешь как это можно применять.
на деле же, это можно развернуть как в масштабируемое приложение, так и пожертвовать быстродействием, если оно нас не волнует.
E>>для тебя нет. но ты пытаешься, пыжишься. для чего только, не ясно. G>Эффективность или есть или её нет, не бывает что для кого-то она есть, а для другого нет.
человек умеет работать каким-то инструментом.
есть другой инструмент, более высокотехнологический, который позволяет повысить эффективность в 2 раза.
но человек не умеет им пользоваться, и получает производительность в 2 раза ниже, от производительности своего более простого инструмента.
ясно?
G>То есть ты не знаешь в чем заключается методология DDD?
ты волен считать так, как тебе больше нравится
G>>>Каким образом? G>>>Покажи его, чтобы оно было DDD и при этом достаточно эффективно. E>>я уже приводил пару возможных примеров. G>Оба гораздо менее эффективны чем могли бы быть.
они достаточно эффективны с точки зрения реализации бизнес логики. остальное — технические детали.
G>>>Как раз в большинстве случаев ОО-код хуже масштабируется. Потому что: G>>>1) Надо таскать identity G>>>2) Надо материализовывать объекты потому что поведение внутри объектов E>>какое это имеет отношение к масштабированию? G>Самое прямое.
совершенно никакого. но тебе наверняка виднее.
G>Я не про масштабирование ресурсов, я про масштабрирование задачи. SOA-подход работает как на простой задаче, выполняющийся на одной машине, так и в сильно распределенной среде. В отличие от ООП. Объекты распределять крайне неэффективно.
объекты распределять и не требуется.
более того, в реализацию SOA вполне может лечь ООП. а это значит, что там может быть использован DDD.
G>В среднем anemic кода получается меньше, чем rich при той же задаче. О какой простоте поддержки ты говоришь?
а говорил строками код не меряешь.
но меньше кода, не значит лучше.
E>>ты опять говоришь глупости и перевираешь мои слова. перечитай еще раз про дистилляцию. G>Читал, и что? Дистиллируй сколько хочешь, но если эксперт говорит что-то, то это надо или учитывать в модели или переучивать эксперта.
я уже давно понял почему DDD методология для тебя не эффективна, но ты в очередной раз доказываешь мою правоту.
G>Думаешь если не слушать все вероятность ошибок уменьшится? Думаешь если ты при построении модели для бухгалтерии отбросишь обороты и потом совершенно случайно не сделаешь их, то пользователи останутся довольны?
ты мешаешь всё подряд. у тебя каша в голове.
E>>у тебя получится anemic, у меня будет домен. G>Приведи пример, посмотрим.
ты слишком много хочешь.
примеров, полный гугл.
E>>это в данном случае не важно. мы можем передать признак, можем передать число, равняющееся сумме предыдущих покупок, на основании которого будем делать скидку. G>Это как раз важно, откуда мы передадим это число?
ты в 10 раз задаешь один и тот же вопрос. перечитай тред, ответ там есть.
E>>проще говоря, добавь покупателю поле с суммой покупок, и получай её сразу с покупателем. G>Нельзя, потому что требуется сумма покупок за последний месяц, то есть вычисление на момент покупки, хранить значение ты не сможешь.
смогу.
E>>хуже для тебя. потому что процедурный стиль программирования тебе ближе. E>>в целом же, с точки зрения ООП, это правильная реализация. а DDD как раз более чем придерживается ООП парадигмы. G>То есть единственная цель "придерживаться ООП парадигмы" чего бы оно не стоило?
цель — использовать преимущества ООП парадигмы при решении задач. а так же DDD методологии.
но для кого-то функциональное программирование кажется лучшим решением. это его право. и это 2 совершенно разных подхода.
G>В данном случае мне надо получить число. Ровно одно число, и все. Мне не нужен объект кастомера со всеми его свойствами чтобы считать скидку.
не вижу никаких проблем что бы при DDD подходе получить 1 число. и ни Фаулер, ни Эванс, этого не запрещают.
E>>верно и обратное, что в DDD не всегда и всё необходимо материализовывать. при необходимости, мы без проблем можем вызвать сервис, который сделает update с условием. G>Да, и это уже будет anemic, потому что есть сервис и нет "доменных объектов".
ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать.
E>>насчет размазывания логики по нескольки объектам, ну так это ж банальный принцип "ответственности" из SOLID, да и ООП в целом. так что это правильная реализация. G>В SOLID куча других принципов, да и за пределами SOLID тоже, и DDD, как его описывает эванс, многое нарушает.
нет, DDD это классическое ООП, и ничего не нарушает.
а вот anemic, в общем-то, не является ООП подходом.
разные реализации. ты используешь процедурный подход, мы ООП.
в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно.
Здравствуйте, Lloyd, Вы писали:
L>Вы не правы, если считаете, что ваша трактовка "по Эвансу" — верна. Если бы я хотел сказать, что для "ДДД годится исключительно рич", я бы так и написал.
Ты даже больше сказал — ДДД это рич
Смотри свои высказывания:
1 "ddd — это не только принцип, но и архитектура с определенным разбиением ..."
2 "примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель"
3 "Если в качестве первоисточника обращаться к эвансу, то ddd — это все-таки рич."
Эванс пишет чуток другое
1 ДДД это принцип, который можно применить к разным архитектурам
2 примеры приведены только для самой популярной модели
3 в книге про ДДД, примеры — рич, но из этого никак не следует, что ДДД это рич.
L>Я же написал, что "Архитектура ДДД по Эвансу — рич", что означет то, и только то, что там написано: есть архитектура ДДД по Эвансу (честно-честно есть, смотрите главы 4-7) и она — рич. Точка.
То есть, ты хотел сказать, что ДДД по Эвансу это ДДД по Эвансу ? Спасибо, Капитан
Здравствуйте, Ikemefula, Вы писали:
L>>Вы не правы, если считаете, что ваша трактовка "по Эвансу" — верна. Если бы я хотел сказать, что для "ДДД годится исключительно рич", я бы так и написал.
I>Ты даже больше сказал — ДДД это рич
Это твои фантазии и только. Все что я писал — это что ddd-архитектура по Эванс — рич. Ничего более.
I>Смотри свои высказывания: I>1 "ddd — это не только принцип, но и архитектура с определенным разбиением ..." I>2 "примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель" I>3 "Если в качестве первоисточника обращаться к эвансу, то ddd — это все-таки рич."
I>Эванс пишет чуток другое
I>1 ДДД это принцип, который можно применить к разным архитектурам
Кэп?
I>2 примеры приведены только для самой популярной модели
Это несомненно делает их не рич, не так ли?
I>3 в книге про ДДД, примеры — рич, но из этого никак не следует, что ДДД это рич.
Да, не следует. Сколько раз мне с этим нужно согласиться, чтобы ты перестал это повторять?
L>>Я же написал, что "Архитектура ДДД по Эвансу — рич", что означет то, и только то, что там написано: есть архитектура ДДД по Эвансу (честно-честно есть, смотрите главы 4-7) и она — рич. Точка.
I>То есть, ты хотел сказать, что ДДД по Эвансу это ДДД по Эвансу ? Спасибо, Капитан
Нет, я хотел сказать (и сказал), что "архитектура ДДД по Эвансу — рич". Но до тебя все никак не дойдет.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>select n+1 это проблема не ДДД, а предметной области. Ты никуда от неё не денешься. G>>Полнейший бред. select n+1 это проблема реализации, когда для получения дочерних сущностей необходимо выполнять по одному запросу в базу (удаленному вызову) для каждой родительской. Если написать один запрос, который получает все данные, то это работает на порядок эффективнее.
I>То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ?
Да, причем это математически доказано.
I>Я немного не точно выразился, selеct n+1 это проблема реализации, но это пробема вторичная, реальная причина в самой предметной области, т.е. в той задаче которую хочет решить заказчик — слишком большой объём выборки для вычисления определенной функции. Слишкой большой это относительно возможностей современных технологий.
Ни разу он не большой. I>Какой бы инструмент ты не выбрал, там будет тоже самое — слишком большой объём выборки для вычисления определенной функции.
Фигня, SQL Server сам такие вычисления легко делает, он для этого и проектировался.
G>>>>Ну конечно, только мне кажется что сделать успешный продукт можно только учитывая пожелания пользователей. I>>>С таким подходом можно делать только хилые продукты. Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг G>>Ты хочешь сказать что можно сделать хороший продукт не учитывая пожелания пользователей?
I>Все что я хотел сказать, я уже сказал : "Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг"
Ну ты просто пытаешься с себя снять ответственность за некоторый класс ошибок — неблагородно.
I>Хочешь опровергнуть это, покажи пример грузового-легкового минивена-родстера
А зачем такая машина нужна? Лучше иметь несколько разных машин.
I>>>Тебе покажется странным, но ДДД очень сильно похоже на то, что на этом форуме называется "функциональный дизайн". G>>Вполне может быть что это так, вот только об этом никто не говорит. Или у тебя есть ссылки на подобные высказывания со стороны апологетов DDD? I>Об этом говорит сам Эванс и этого достаточно
Ну, ссылку, цитату. Я видел обратное.
Здравствуйте, Enomay, Вы писали:
G>>И это будет максимально эффективным решением.
E>ровно до тех пор, пока это будет оставаться небольшим интернет-магазином.
I>>Смотри свои высказывания: I>>1 "ddd — это не только принцип, но и архитектура с определенным разбиением ..." I>>2 "примеры, которые он приводит, демонстрируют его мнение о ddd как архитектуре, а там — именно рич-модель" I>>3 "Если в качестве первоисточника обращаться к эвансу, то ddd — это все-таки рич."
I>>Эванс пишет чуток другое
I>>1 ДДД это принцип, который можно применить к разным архитектурам L>Кэп?
"ddd — это все-таки рич" и "ddd — это разные архитектуры"
I>>2 примеры приведены только для самой популярной модели L>Это несомненно делает их не рич, не так ли?
Ты же про его мнение пишешь, а не про примеры.
I>>3 в книге про ДДД, примеры — рич, но из этого никак не следует, что ДДД это рич.
L>Да, не следует. Сколько раз мне с этим нужно согласиться, чтобы ты перестал это повторять?
Ты не только соглашаешься но и продолжаешь утверждать прямо противоположные вещи
L>>>Я же написал, что "Архитектура ДДД по Эвансу — рич", что означет то, и только то, что там написано: есть архитектура ДДД по Эвансу (честно-честно есть, смотрите главы 4-7) и она — рич. Точка.
I>>То есть, ты хотел сказать, что ДДД по Эвансу это ДДД по Эвансу ? Спасибо, Капитан
L>Нет, я хотел сказать (и сказал), что "архитектура ДДД по Эвансу — рич". Но до тебя все никак не дойдет.
Ты за столько сообщений так и не пояснил, что же ты хотел этим сказать. Что примеры там рич ?
I>>То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ? G>Да, причем это математически доказано.
иногда эти запросы становятся огромными, сложными, и не эффективными, что даже у сиквела срывает крышу, и порой проще сделать 3 запроса более точечных и простых, нежели 1 тяжелый.
I>>Какой бы инструмент ты не выбрал, там будет тоже самое — слишком большой объём выборки для вычисления определенной функции. G>Фигня, SQL Server сам такие вычисления легко делает, он для этого и проектировался.
SQL Server у нас ложился про подсчете уникальных посетителей сайта. а это очень простая операция.
так что, как показывает практика, не так уж легко он делает вычисления.
Здравствуйте, gandjustas, Вы писали:
I>>То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ? G>Да, причем это математически доказано.
Неужели математической доказательство может отметить сложности технической реализации ? Каюсь, не знал. Я то думал на каждую операцию надо время, хотя бы и маленькое, а оказывается математика может _любую_ операцию сделать равной нулю по затратам времени. Не подскажешь, почему эта математика не может сделать так, что бы твой комп хотя бы загружался или просыпался за ровно 0 секунд ?
I>>Я немного не точно выразился, selеct n+1 это проблема реализации, но это пробема вторичная, реальная причина в самой предметной области, т.е. в той задаче которую хочет решить заказчик — слишком большой объём выборки для вычисления определенной функции. Слишкой большой это относительно возможностей современных технологий. G>Ни разу он не большой.
Это в твоих задачах объёмы небольшие.
I>>Какой бы инструмент ты не выбрал, там будет тоже самое — слишком большой объём выборки для вычисления определенной функции. G>Фигня, SQL Server сам такие вычисления легко делает, он для этого и проектировался.
Какие такие ? Ты уверен, что за 0.5с для реакции на мышиный клик, твой SQL Server подтянет любое необходимое количество инфы, которую нужно будет еще процессить дополнительно ? Чудеса, ты нашел сервер с бесконечно высокой скоростью, ну ка, поделись этой пулькой
Я вот точно знаю, что для многих задач даже секунд будет недостаточно даже для того, что бы только подтянуть инфу, а у тебя какое то чудо выходит
I>>Все что я хотел сказать, я уже сказал : "Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг" G>Ну ты просто пытаешься с себя снять ответственность за некоторый класс ошибок — неблагородно.
Наоборот, я говорю о том, что часть пожеланий никогда не будет учтена и это осознанный выбор. Например если часть пользователей будет ныть и требовать что бы сайт работал под ихним древним железом P-100 + ИЕ4 Win-98, то маркетинг смело посылает таких пользователей нахрен.
I>>Хочешь опровергнуть это, покажи пример грузового-легкового минивена-родстера G>А зачем такая машина нужна? Лучше иметь несколько разных машин.
Автомобилисты как правило достаточно грамотные относительно пользователей софта, тем не менее и там встречается целая куча пожеланий, которые никто никогда в своём уме не будет учитывать.
G>>>Вполне может быть что это так, вот только об этом никто не говорит. Или у тебя есть ссылки на подобные высказывания со стороны апологетов DDD? I>>Об этом говорит сам Эванс и этого достаточно G>Ну, ссылку, цитату. Я видел обратное.
Здравствуйте, Ikemefula, Вы писали:
I>>>Эванс пишет чуток другое
I>>>1 ДДД это принцип, который можно применить к разным архитектурам L>>Кэп?
I>"ddd — это все-таки рич" и "ddd — это разные архитектуры"
А ты не вырывай из контекста.
I>>>2 примеры приведены только для самой популярной модели L>>Это несомненно делает их не рич, не так ли?
I>Ты же про его мнение пишешь, а не про примеры.
Я не знаю его мнения, я знаю только то, что написано в книге. А там описана вполне определенная архитектура.
I>>>3 в книге про ДДД, примеры — рич, но из этого никак не следует, что ДДД это рич.
L>>Да, не следует. Сколько раз мне с этим нужно согласиться, чтобы ты перестал это повторять?
I>Ты не только соглашаешься но и продолжаешь утверждать прямо противоположные вещи
Ты просто постарайся не вырывать куски и тогда никаких противоположных вещей не будет. Это просто, главное начать.
L>>>>Я же написал, что "Архитектура ДДД по Эвансу — рич", что означет то, и только то, что там написано: есть архитектура ДДД по Эвансу (честно-честно есть, смотрите главы 4-7) и она — рич. Точка.
I>>>То есть, ты хотел сказать, что ДДД по Эвансу это ДДД по Эвансу ? Спасибо, Капитан
L>>Нет, я хотел сказать (и сказал), что "архитектура ДДД по Эвансу — рич". Но до тебя все никак не дойдет.
I>Ты за столько сообщений так и не пояснил, что же ты хотел этим сказать. Что примеры там рич ?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ? G>>Да, причем это математически доказано.
I>Неужели математической доказательство может отметить сложности технической реализации ?
Разве это отменяет возможность?
I>Каюсь, не знал. Я то думал на каждую операцию надо время, хотя бы и маленькое, а оказывается математика может _любую_ операцию сделать равной нулю по затратам времени. Не подскажешь, почему эта математика не может сделать так, что бы твой комп хотя бы загружался или просыпался за ровно 0 секунд ?
А ты считаешь что другие способы обработки большого объема данных будут быстрее? Написать sum в запросе гораздо проще, чем циклы и if_ы которые суммируют числа.
I>>>Я немного не точно выразился, selеct n+1 это проблема реализации, но это пробема вторичная, реальная причина в самой предметной области, т.е. в той задаче которую хочет решить заказчик — слишком большой объём выборки для вычисления определенной функции. Слишкой большой это относительно возможностей современных технологий. G>>Ни разу он не большой. I>Это в твоих задачах объёмы небольшие.
Какая разница? Это отменяет тот факт что select n+1 — проблема реализации?
I>>>Какой бы инструмент ты не выбрал, там будет тоже самое — слишком большой объём выборки для вычисления определенной функции. G>>Фигня, SQL Server сам такие вычисления легко делает, он для этого и проектировался.
I>Какие такие ? Ты уверен, что за 0.5с для реакции на мышиный клик, твой SQL Server подтянет любое необходимое количество инфы, которую нужно будет еще процессить дополнительно ? Чудеса, ты нашел сервер с бесконечно высокой скоростью, ну ка, поделись этой пулькой I>Я вот точно знаю, что для многих задач даже секунд будет недостаточно даже для того, что бы только подтянуть инфу, а у тебя какое то чудо выходит
Конечно получить список заказов для кастомера за последний месяц и всех его позиций с суммированием по цене SQL Server сделает достаточно быстро, чтобы уложиться в 0.5 сек. Главное сделать индексы правильные.
I>>>Все что я хотел сказать, я уже сказал : "Пожелания нужно рассматривать и анализировать,а учитывать или нет — это решает маркетинг" G>>Ну ты просто пытаешься с себя снять ответственность за некоторый класс ошибок — неблагородно.
I>Наоборот, я говорю о том, что часть пожеланий никогда не будет учтена и это осознанный выбор. Например если часть пользователей будет ныть и требовать что бы сайт работал под ихним древним железом P-100 + ИЕ4 Win-98, то маркетинг смело посылает таких пользователей нахрен.
Нет, в выделенном ты сказал то что не ты отвечаешь за функционал и снял с себя ответственность за это. Что ты имел ввиду мне неинтересно.
G>>>>Вполне может быть что это так, вот только об этом никто не говорит. Или у тебя есть ссылки на подобные высказывания со стороны апологетов DDD? I>>>Об этом говорит сам Эванс и этого достаточно G>>Ну, ссылку, цитату. Я видел обратное.
I>См. пример про смешение цветов.
Здравствуйте, Enomay, Вы писали:
I>>>То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ? G>>Да, причем это математически доказано.
E>иногда эти запросы становятся огромными, сложными, и не эффективными, что даже у сиквела срывает крышу, и порой проще сделать 3 запроса более точечных и простых, нежели 1 тяжелый.
Ну так делай.
I>>>Какой бы инструмент ты не выбрал, там будет тоже самое — слишком большой объём выборки для вычисления определенной функции. G>>Фигня, SQL Server сам такие вычисления легко делает, он для этого и проектировался.
E>SQL Server у нас ложился про подсчете уникальных посетителей сайта. а это очень простая операция. E>так что, как показывает практика, не так уж легко он делает вычисления.
Ты бы хоть понимал что пишешь...
Подсчет уникальных значений делается при помощи сортировки исходного набора данных, которая n*log(n) как минимум и удаления дубликатов. так что это ни разу не простая операция, несмотря на то что тебе так кажется.
Если сделать индекс по значению, которое должно быть уникальным, то сэкономишь на на сортировке, но все равно потребуется вытянуть все строкни с диска чтобы удалить дубликаты.
А если ты сделаешь таблицу, куда всех пользователей записывать по одному разу, и на нее ссылаться из таблицы визитов, то подсчет количества можно сделать индексом, в идеале индексированным представлением.
E>>SQL Server у нас ложился про подсчете уникальных посетителей сайта. а это очень простая операция. E>>так что, как показывает практика, не так уж легко он делает вычисления.
G>
G>Ты бы хоть понимал что пишешь... G>Подсчет уникальных значений делается при помощи сортировки исходного набора данных, которая n*log(n) как минимум и удаления дубликатов. так что это ни разу не простая операция, несмотря на то что тебе так кажется.
G>Если сделать индекс по значению, которое должно быть уникальным, то сэкономишь на на сортировке, но все равно потребуется вытянуть все строкни с диска чтобы удалить дубликаты.
G>А если ты сделаешь таблицу, куда всех пользователей записывать по одному разу, и на нее ссылаться из таблицы визитов, то подсчет количества можно сделать индексом, в идеале индексированным представлением.
когда у тебя будут такие объемы, будешь рассказывать как нужно делать. а пока у тебя интернет магазинчик, твоё мнение ниразу не интересно.
а то оно конечно классно рассуждать. индексов напихать, а потом выгребать на вставке, с учетом того, что у нас пишется около 20к записей в секунду
Здравствуйте, Enomay, Вы писали:
E>>>SQL Server у нас ложился про подсчете уникальных посетителей сайта. а это очень простая операция. E>>>так что, как показывает практика, не так уж легко он делает вычисления.
G>>
G>>Ты бы хоть понимал что пишешь... G>>Подсчет уникальных значений делается при помощи сортировки исходного набора данных, которая n*log(n) как минимум и удаления дубликатов. так что это ни разу не простая операция, несмотря на то что тебе так кажется.
G>>Если сделать индекс по значению, которое должно быть уникальным, то сэкономишь на на сортировке, но все равно потребуется вытянуть все строкни с диска чтобы удалить дубликаты.
G>>А если ты сделаешь таблицу, куда всех пользователей записывать по одному разу, и на нее ссылаться из таблицы визитов, то подсчет количества можно сделать индексом, в идеале индексированным представлением.
E>когда у тебя будут такие объемы, будешь рассказывать как нужно делать. а пока у тебя интернет магазинчик, твоё мнение ниразу не интересно.
У меня нет инетрнет-магазина, к сожалению, хотя я их немало сделал.
E>а то оно конечно классно рассуждать. индексов напихать, а потом выгребать на вставке, с учетом того, что у нас пишется около 20к записей в секунду
На 20к в секунду от записи база ляжет в первую очередь. Тогда просто подключайте OLAP и будет счастье.
G>>>Хранить ты его не можешь, как как нужна сумма за месяц с текущего момента. E>>в сиквеле, нет, в документной базе, без проблем в общем-то. G>Каким образом? Покажи как по изменяющемуся критерию хранить значение?
для этого есть доменная модель, которая этим занимается.
у тебя проблемы с проектированием такой вещи?
E>>это от того, что ты не понимаешь как это можно применять. E>>на деле же, это можно развернуть как в масштабируемое приложение, так и пожертвовать быстродействием, если оно нас не волнует. G>За счет чего? Что ты в DDD масштабировать будешь?
о CQRS слышал? одни из наиболее эффективных систем для высоконагруженных решений с достаточно хорошим масштабированием, применяемая в большом кол-ве проектов. и о ужас! в основе её лежит доменная модель!!!
но раз ты сказал что DDD говно, они обязательно все перепишут.
G>Человек может научиться, а могие чем больше узнают DDD, тем больше понимают его неэффективность. Какая обратная зависимость в отличие от "инструмента".
человек, если у него руки не из того места, может и не научится.
касательно многих, то 95% людей идиоты. и если они не понимают преимущества DDD, то это не делает саму методологию хуже, но определенным образом характеризует людей.
G>>>То есть ты не знаешь в чем заключается методология DDD? E>>ты волен считать так, как тебе больше нравится G>Ты скажи. Мне интересно твое мнение, а то ты говоришь "методология DDD", но не можешь её описать.
своё мнение я сделал сам. и оно меня вполне устраивает.
рекомендую тебе заняться тем же самым.
E>>они достаточно эффективны с точки зрения реализации бизнес логики. остальное — технические детали. G> G>То есть тормозное говно, и ты с этим согласен.
ты читаешь между строк, и видишь только то, что хочешь видеть.
но пусть будет так. если тебя это радует
G>>>Я не про масштабирование ресурсов, я про масштабрирование задачи. SOA-подход работает как на простой задаче, выполняющийся на одной машине, так и в сильно распределенной среде. В отличие от ООП. Объекты распределять крайне неэффективно. E>>объекты распределять и не требуется. G>А что будет распределяться?
в интернете этого добра хватает. вон Грег Янг ездит с докладами по миру. сходи, послушай.
E>>более того, в реализацию SOA вполне может лечь ООП. а это значит, что там может быть использован DDD. G>Не может, ООП как подход проектированию не совместим с SOA, а вот сделать сервисы SOA из классов, вполне может быть, только не ООП это. G>И где там может быть использован DDD? Покажешь пример?
опять какие-то глупости пошли.
в основе сервисов лежит DDD. это даже у Эванса есть.
а иначе что делает сервис? тупо возвращает данные?
возможно. в таком случае домен может быть на другой стороне этой цепочки.
G>>>В среднем anemic кода получается меньше, чем rich при той же задаче. О какой простоте поддержки ты говоришь? E>>а говорил строками код не меряешь. E>>но меньше кода, не значит лучше. G>Да, лучше больше функционала, вот anemic и позволяет получить больше функционала за меньше строк (почему-то сходу написал "денег"). G>А что для тебя "лучше"?
без проблем. используй анемик. разве тебя кто-то заставляет писать по другому?
тебя даже никто не пытается переубедить.
G>>>Думаешь если не слушать все вероятность ошибок уменьшится? Думаешь если ты при построении модели для бухгалтерии отбросишь обороты и потом совершенно случайно не сделаешь их, то пользователи останутся довольны? E>>ты мешаешь всё подряд. у тебя каша в голове. G>Это я пытаюсь из твоей каши хоть какую-то информацию достать, а то ты вещаешь лозунги с первой страницы domaindrivendesign.org и других сайентологов, не особо вникая о чем они.
я просто троллю. а ты пыжишься чего-то.
E>>>>у тебя получится anemic, у меня будет домен. G>>>Приведи пример, посмотрим. E>>ты слишком много хочешь. E>>примеров, полный гугл. G>Дай ссылку чтоли.
забанили в гугле?
E>>>>это в данном случае не важно. мы можем передать признак, можем передать число, равняющееся сумме предыдущих покупок, на основании которого будем делать скидку. G>>>Это как раз важно, откуда мы передадим это число? E>>ты в 10 раз задаешь один и тот же вопрос. перечитай тред, ответ там есть. G>да, ответ там есть: мы число получим в сервисе, а потом передадим в объект, это менее эффективно чем считать скидку в сервисе. Ведь можно получить ту же скидку, не материализуя объект. ты не согласен и сам продолжаешь ходить по-кругу, пытаясь найти преимущества материализации объектов. G>Вот только нет этих преимуществ.
реализация логики в сервисе, это конечно можно. для процедурного программирования. но ООП как бы говорит о другом. и я придерживаюсь последнего подхода, в отличии от тебя.
эффективности при решении задач оно не убавляет. для больших проектов выгода очевидна.
и опять ты кидаешься в крайности. для тебя если DDD, то материализовать всё. но это не так.
E>>>>проще говоря, добавь покупателю поле с суммой покупок, и получай её сразу с покупателем. G>>>Нельзя, потому что требуется сумма покупок за последний месяц, то есть вычисление на момент покупки, хранить значение ты не сможешь. E>>смогу. G>Ок, покажи как.
ты и такую задачу реализовать не можешь?
E>>цель — использовать преимущества ООП парадигмы при решении задач. а так же DDD методологии. E>>но для кого-то функциональное программирование кажется лучшим решением. это его право. и это 2 совершенно разных подхода. G>Какие это преимущества, ты так и не ответил. У тебя получается преимущество ООП в использовании ООП. Остальное только недостатки.
о преимуществах написано в соответствующих книгах. я не собираюсь дублировать тут написанное. достаточно прочесть, понять и применять. либо не понять, и распинаться на форуме о том, какое это говно.
правда хуже оно от того не становится
E>>ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать. G>Каким образом решают? Пример кода приведешь?
я кажется начинаю понимать. ты прочел Эванса, по диагонали, но как применять не понял. теперь от всех требуешь примеры кода. я угадал?
E>>нет, DDD это классическое ООП, и ничего не нарушает. G> G>Само по себе конечно не нарушает. Но если следовать фаулеру, то нарушает. Domain Model нарушает SRP как минимум.А если выносить из доменных объектов всю логику в "доменные сервисы", то нарушает принцип бритвы оккама.
опять глупости понеслись. Domain Model как раз очень четко вписывается в SRP, в отличии от твоих сервисов.
E>>а вот anemic, в общем-то, не является ООП подходом. G>Почему не является? Там есть классы, есть поведение, инкапсулированное в классах, там есть полиморфизм, основанный на реализации интерфейсов. Вот и докажи что ООП нет? Может быть там нет ОО-дизайна, описанного Бучем и Мейером, так уже давно известно что они довольно плохой дизайн описали по куче формальных признаков.
на самом деле наличие классов, наследование, полиморфизм и инкапсуляция, абсолютно не делают подход объектно ориентированным. у тебя класс это лишь объединение подобных по смыслу функций.
а вот поведения объектов у тебя нет.
только не нужно говорить про состояния, и в паскале были глобальные переменные.
но зато ты и сам подтвердил свою причину непонимания DDD — ты не знаешь что такое ООП и не умеешь его применять на практике. отсюда и процедурный подход, которым ты так гордишься.
E>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. G>Не очевидно, докажи.
если тебе это не очевидно, могу только по соболезновать.
E>>а то оно конечно классно рассуждать. индексов напихать, а потом выгребать на вставке, с учетом того, что у нас пишется около 20к записей в секунду G>На 20к в секунду от записи база ляжет в первую очередь.
конечно ляжет. потому у нас их кластер.
вот только тут твои методы и подходы уже перестают работать.
G>Тогда просто подключайте OLAP и будет счастье.
Здравствуйте, gandjustas, Вы писали:
I>>Неужели математической доказательство может отметить сложности технической реализации ? G>Разве это отменяет возможность?
Я то говорил про сложность
I>>Каюсь, не знал. Я то думал на каждую операцию надо время, хотя бы и маленькое, а оказывается математика может _любую_ операцию сделать равной нулю по затратам времени. Не подскажешь, почему эта математика не может сделать так, что бы твой комп хотя бы загружался или просыпался за ровно 0 секунд ? G>А ты считаешь что другие способы обработки большого объема данных будут быстрее? Написать sum в запросе гораздо проще, чем циклы и if_ы которые суммируют числа.
Ты еще 2+2 предложи в качестве примера Я считаю, что издержки select N+1 запросто могут быть наименьшими сравнивая с другими решениемя.
I>>>>Я немного не точно выразился, selеct n+1 это проблема реализации, но это пробема вторичная, реальная причина в самой предметной области, т.е. в той задаче которую хочет решить заказчик — слишком большой объём выборки для вычисления определенной функции. Слишкой большой это относительно возможностей современных технологий. G>>>Ни разу он не большой. I>>Это в твоих задачах объёмы небольшие. G>Какая разница? Это отменяет тот факт что select n+1 — проблема реализации?
Читай выделеное.
I>>Какие такие ? Ты уверен, что за 0.5с для реакции на мышиный клик, твой SQL Server подтянет любое необходимое количество инфы, которую нужно будет еще процессить дополнительно ? Чудеса, ты нашел сервер с бесконечно высокой скоростью, ну ка, поделись этой пулькой I>>Я вот точно знаю, что для многих задач даже секунд будет недостаточно даже для того, что бы только подтянуть инфу, а у тебя какое то чудо выходит G>Конечно получить список заказов для кастомера за последний месяц и всех его позиций с суммированием по цене SQL Server сделает достаточно быстро, чтобы уложиться в 0.5 сек. Главное сделать индексы правильные.
Я и говорю — это в твоих задачах надо мелочовку таскать вроде заказов за месяц.
I>>Наоборот, я говорю о том, что часть пожеланий никогда не будет учтена и это осознанный выбор. Например если часть пользователей будет ныть и требовать что бы сайт работал под ихним древним железом P-100 + ИЕ4 Win-98, то маркетинг смело посылает таких пользователей нахрен. G>Нет, в выделенном ты сказал то что не ты отвечаешь за функционал и снял с себя ответственность за это. Что ты имел ввиду мне неинтересно.
Наоборот, мы полностью берем ответсвенность на себя, когда даём отлуп определенным пользователям.
I>>См. пример про смешение цветов.
G>Скопируй сюда чтоли, у меня книги под рукой нет.
Здравствуйте, Enomay, Вы писали:
G>>>>Хранить ты его не можешь, как как нужна сумма за месяц с текущего момента. E>>>в сиквеле, нет, в документной базе, без проблем в общем-то. G>>Каким образом? Покажи как по изменяющемуся критерию хранить значение? E>для этого есть доменная модель, которая этим занимается. E>у тебя проблемы с проектированием такой вещи?
ну смотри, есть запрос вроде
select sum(ol.Price*ol.Quantity) as [Sum]
from Orders o
join OrderLines ol on o.Id = ol.OrderId
where ol.HasDiscount = 0 and o.CustomerId=@param
ando.Date>DATEADD(m,-1,GETDATE())
Как ты такое будешь хранить? Это надо вычислять.
E>>>это от того, что ты не понимаешь как это можно применять. E>>>на деле же, это можно развернуть как в масштабируемое приложение, так и пожертвовать быстродействием, если оно нас не волнует. G>>За счет чего? Что ты в DDD масштабировать будешь?
E>о CQRS слышал? одни из наиболее эффективных систем для высоконагруженных решений с достаточно хорошим масштабированием, применяемая в большом кол-ве проектов.
Конечно и ничего нового в этой аббривеатуре нет, очереди + воркеры.
E>и о ужас! в основе её лежит доменная модель!!!
не-а, в её основе лежать очереди и воркеры, а доступ к данным может быть абсолютно любым.
E>но раз ты сказал что DDD говно, они обязательно все перепишут.
Нет, переписывать — экономически неэффективное занятие почти всегда.
G>>Человек может научиться, а могие чем больше узнают DDD, тем больше понимают его неэффективность. Какая обратная зависимость в отличие от "инструмента".
E>человек, если у него руки не из того места, может и не научится. E>касательно многих, то 95% людей идиоты. и если они не понимают преимущества DDD, то это не делает саму методологию хуже, но определенным образом характеризует людей.
Ага, прям как коммунизм
G>>>>То есть ты не знаешь в чем заключается методология DDD? E>>>ты волен считать так, как тебе больше нравится G>>Ты скажи. Мне интересно твое мнение, а то ты говоришь "методология DDD", но не можешь её описать.
E>своё мнение я сделал сам. и оно меня вполне устраивает. E>рекомендую тебе заняться тем же самым.
Так ты его озвучь, а то получается разговор с голосами в твоей голове, которые никто кроме тебя не слышит.
G>>>>Я не про масштабирование ресурсов, я про масштабрирование задачи. SOA-подход работает как на простой задаче, выполняющийся на одной машине, так и в сильно распределенной среде. В отличие от ООП. Объекты распределять крайне неэффективно. E>>>объекты распределять и не требуется. G>>А что будет распределяться? E>в интернете этого добра хватает. вон Грег Янг ездит с докладами по миру. сходи, послушай.
Слушал, такой бред рассказывает что смешно.
E>>>более того, в реализацию SOA вполне может лечь ООП. а это значит, что там может быть использован DDD. G>>Не может, ООП как подход проектированию не совместим с SOA, а вот сделать сервисы SOA из классов, вполне может быть, только не ООП это. G>>И где там может быть использован DDD? Покажешь пример?
E>опять какие-то глупости пошли. E>в основе сервисов лежит DDD. это даже у Эванса есть.
А у меня нет, у меня сервиcы без DDD.
E>а иначе что делает сервис? тупо возвращает данные?
Когда надо возвращать — возвращает. Когда надо изменять — изменяет.
E>возможно. в таком случае домен может быть на другой стороне этой цепочки.
На какой другой? На одной стороне хранилище, на другой UI. Идет передача информации от одного к другому.
G>>>>В среднем anemic кода получается меньше, чем rich при той же задаче. О какой простоте поддержки ты говоришь? E>>>а говорил строками код не меряешь. E>>>но меньше кода, не значит лучше. G>>Да, лучше больше функционала, вот anemic и позволяет получить больше функционала за меньше строк (почему-то сходу написал "денег"). G>>А что для тебя "лучше"? E>без проблем. используй анемик. разве тебя кто-то заставляет писать по другому? E>тебя даже никто не пытается переубедить.
Я хочу понять зачем использовать rich.
G>>>>Думаешь если не слушать все вероятность ошибок уменьшится? Думаешь если ты при построении модели для бухгалтерии отбросишь обороты и потом совершенно случайно не сделаешь их, то пользователи останутся довольны? E>>>ты мешаешь всё подряд. у тебя каша в голове. G>>Это я пытаюсь из твоей каши хоть какую-то информацию достать, а то ты вещаешь лозунги с первой страницы domaindrivendesign.org и других сайентологов, не особо вникая о чем они. E>я просто троллю. а ты пыжишься чего-то.
Заметно.
E>>>>>у тебя получится anemic, у меня будет домен. G>>>>Приведи пример, посмотрим. E>>>ты слишком много хочешь. E>>>примеров, полный гугл. G>>Дай ссылку чтоли. E>забанили в гугле?
нет, мне лениво. Дай ссылку и я даже почитаю. А пока твои слова не весомее воздуха.
E>>>>>это в данном случае не важно. мы можем передать признак, можем передать число, равняющееся сумме предыдущих покупок, на основании которого будем делать скидку. G>>>>Это как раз важно, откуда мы передадим это число? E>>>ты в 10 раз задаешь один и тот же вопрос. перечитай тред, ответ там есть. G>>да, ответ там есть: мы число получим в сервисе, а потом передадим в объект, это менее эффективно чем считать скидку в сервисе. Ведь можно получить ту же скидку, не материализуя объект. ты не согласен и сам продолжаешь ходить по-кругу, пытаясь найти преимущества материализации объектов. G>>Вот только нет этих преимуществ.
E>реализация логики в сервисе, это конечно можно. для процедурного программирования. но ООП как бы говорит о другом. и я придерживаюсь последнего подхода, в отличии от тебя.
А зачем ты его придерживаешься, что оно тебе дает?
E>эффективности при решении задач оно не убавляет. для больших проектов выгода очевидна.
Убавляет, тупо потому что больше кода писать надо.
E>и опять ты кидаешься в крайности. для тебя если DDD, то материализовать всё. но это не так.
Ок, приведи пример где это не так. У тебя же логика в классах и без ссылки на класс ты её вызывать не можешь.
E>>>>>проще говоря, добавь покупателю поле с суммой покупок, и получай её сразу с покупателем. G>>>>Нельзя, потому что требуется сумма покупок за последний месяц, то есть вычисление на момент покупки, хранить значение ты не сможешь. E>>>смогу. G>>Ок, покажи как. E>ты и такую задачу реализовать не можешь?
См SQL выше. Его же можно с помощью LINQ нагенерить (что я собственно и сделал в подобной задаче).
E>>>цель — использовать преимущества ООП парадигмы при решении задач. а так же DDD методологии. E>>>но для кого-то функциональное программирование кажется лучшим решением. это его право. и это 2 совершенно разных подхода. G>>Какие это преимущества, ты так и не ответил. У тебя получается преимущество ООП в использовании ООП. Остальное только недостатки. E>о преимуществах написано в соответствующих книгах. я не собираюсь дублировать тут написанное. достаточно прочесть, понять и применять. либо не понять, и распинаться на форуме о том, какое это говно. E>правда хуже оно от того не становится
Так ты опиши их вкратце, а то книги большие, воды там много.
В чем ты видишь преимущества, желательно в цифрах? Или ты просто тупо следуешь тому что в книгах пишут?
E>>>ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать. G>>Каким образом решают? Пример кода приведешь? E>я кажется начинаю понимать. ты прочел Эванса, по диагонали, но как применять не понял. теперь от всех требуешь примеры кода. я угадал?
Нет, я требую примеры кода от таких троллей, которые пишут лозунги и после каждого второго слова ссылаются на эванса, фаулера или еще кого.
Code talks.
E>>>нет, DDD это классическое ООП, и ничего не нарушает. G>> G>>Само по себе конечно не нарушает. Но если следовать фаулеру, то нарушает. Domain Model нарушает SRP как минимум.А если выносить из доменных объектов всю логику в "доменные сервисы", то нарушает принцип бритвы оккама. E>опять глупости понеслись. Domain Model как раз очень четко вписывается в SRP, в отличии от твоих сервисов.
Ага, особенно одновременное совмещение задач по переносу данных и БЛ. Ведь ты можешь разделить эти обязанности без потери других характеристик, это само существование anemic показывает.
E>>>а вот anemic, в общем-то, не является ООП подходом. G>>Почему не является? Там есть классы, есть поведение, инкапсулированное в классах, там есть полиморфизм, основанный на реализации интерфейсов. Вот и докажи что ООП нет? Может быть там нет ОО-дизайна, описанного Бучем и Мейером, так уже давно известно что они довольно плохой дизайн описали по куче формальных признаков. E>на самом деле наличие классов, наследование, полиморфизм и инкапсуляция, абсолютно не делают подход объектно ориентированным. у тебя класс это лишь объединение подобных по смыслу функций.
Да, это называется "инкапсуляция поведения".
E>а вот поведения объектов у тебя нет.
Есть, у меня данных в этих объектах нет.
E>но зато ты и сам подтвердил свою причину непонимания DDD — ты не знаешь что такое ООП и не умеешь его применять на практике. отсюда и процедурный подход, которым ты так гордишься.
Ты расстроешься, но я прекрасно знаю ООП во всех его инкарнациях, именно поэтому оно не вызывает у меня такой бури юношеских эмоций как у тебя.
E>>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. G>>Не очевидно, докажи. E>если тебе это не очевидно, могу только по соболезновать.
Это тебе соболезновать надо. Ты говоришь глупость, сам в нее свято веришь и при этом не понимаешь тех кто не верит в нее.
Такое бывает у сектантов и у сумасшедших. Хотя апологеты DDD проявляют черты и тех и других
G>Как ты такое будешь хранить? Это надо вычислять.
совершенно необязательно. это достаточно вычислять 1 раз при оформлении пользовательского заказа.
E>>и о ужас! в основе её лежит доменная модель!!! G>не-а, в её основе лежать очереди и воркеры, а доступ к данным может быть абсолютно любым.
вот видишь. то потому что ты видишь только то, что хочешь.
но открою секрет, в середине лежит домен, который обрабатывает команды.
посмотрю любую схему CQRS. там по центру есть такое, Domain Model называется.
E>>своё мнение я сделал сам. и оно меня вполне устраивает. E>>рекомендую тебе заняться тем же самым. G>Так ты его озвучь, а то получается разговор с голосами в твоей голове, которые никто кроме тебя не слышит.
я и не нуждаюсь в том, что бы их кто-то слышал. а вот ты все время добиваешься этого.
G>Слушал, такой бред рассказывает что смешно.
а ты наверное умнее?
E>>опять какие-то глупости пошли. E>>в основе сервисов лежит DDD. это даже у Эванса есть. G>А у меня нет, у меня сервиcы без DDD.
не могу сказать что рад за тебя, но зачем мне эта информация?
E>>а иначе что делает сервис? тупо возвращает данные? G>Когда надо возвращать — возвращает. Когда надо изменять — изменяет.
а логика изменения данных где лежит?
E>>возможно. в таком случае домен может быть на другой стороне этой цепочки. G>На какой другой? На одной стороне хранилище, на другой UI. Идет передача информации от одного к другому.
на третьей, очевидно же.
E>>без проблем. используй анемик. разве тебя кто-то заставляет писать по другому? E>>тебя даже никто не пытается переубедить. G>Я хочу понять зачем использовать rich.
так попробуй понять это. напряги мозг, подумай. иначе никак не получится. никто тебе тут в примерах и сравнениях не покажет чем одно лучше другого, особенно когда оппонент не способен адекватно воспринимать информацию.
E>>>>>>у тебя получится anemic, у меня будет домен. G>>>>>Приведи пример, посмотрим. E>>>>ты слишком много хочешь. E>>>>примеров, полный гугл. G>>>Дай ссылку чтоли. E>>забанили в гугле? G>нет, мне лениво. Дай ссылку и я даже почитаю. А пока твои слова не весомее воздуха.
я кажется и не требовал признания тобой моих слов)
то тебе лень гуглить, то ты пишешь что хочешь понять зачем использовать рич. так хочешь все же, или лень?
E>>реализация логики в сервисе, это конечно можно. для процедурного программирования. но ООП как бы говорит о другом. и я придерживаюсь последнего подхода, в отличии от тебя. G>А зачем ты его придерживаешься, что оно тебе дает?
ответ на этот вопрос уже звучал в этом треде.
так же можешь почитать что-то на тему ООП, наверняка там будут описаны профиты.
E>>эффективности при решении задач оно не убавляет. для больших проектов выгода очевидна. G>Убавляет, тупо потому что больше кода писать надо.
выигрыш не в кол-ве строк, а в гибкости архитектуры.
убавляет только в случаи непонимания ООП и только.
E>>и опять ты кидаешься в крайности. для тебя если DDD, то материализовать всё. но это не так. G>Ок, приведи пример где это не так. У тебя же логика в классах и без ссылки на класс ты её вызывать не можешь.
в CQRS модели шлем команду, обработчик которой вытаскивает при необходимости из базы дополнительные данные и передаёт все это модели, та уже выполняет логику. но варианты могут быть и другие.
E>>ты и такую задачу реализовать не можешь? G>См SQL выше. Его же можно с помощью LINQ нагенерить (что я собственно и сделал в подобной задаче).
это же можно использовать и в DDD. ничто не мешает.
E>>о преимуществах написано в соответствующих книгах. я не собираюсь дублировать тут написанное. достаточно прочесть, понять и применять. либо не понять, и распинаться на форуме о том, какое это говно. E>>правда хуже оно от того не становится G>Так ты опиши их вкратце, а то книги большие, воды там много. G>В чем ты видишь преимущества, желательно в цифрах? Или ты просто тупо следуешь тому что в книгах пишут?
очень тяжело что-то объяснять человеку, который совершенно не понимает ООП, более того, считает при этом его ущербным. это как минимум бесполезное занятие.
по этой причине я не стану ничего писать. но ты можешь прочесть пару книг, возможно это тебе поможет.
G>Нет, я требую примеры кода от таких троллей, которые пишут лозунги и после каждого второго слова ссылаются на эванса, фаулера или еще кого. G>Code talks.
может быть ты начнешь приводить свой код уже? а так же то, как ты видишь, оно должно выглядеть с точки зрения DDD, в твоей интерпретации. тогда предметно поговорим.
E>>опять глупости понеслись. Domain Model как раз очень четко вписывается в SRP, в отличии от твоих сервисов. G>Ага, особенно одновременное совмещение задач по переносу данных и БЛ. Ведь ты можешь разделить эти обязанности без потери других характеристик, это само существование anemic показывает.
доменная модель не переносит никакие данные. она лишь хранит собственное состояние.
тебе уже намекали не один раз, твоя проблема — ты идешь от данных. в ООП нужно идти от модели. по этой причине ты не можешь понять.
E>>на самом деле наличие классов, наследование, полиморфизм и инкапсуляция, абсолютно не делают подход объектно ориентированным. у тебя класс это лишь объединение подобных по смыслу функций. G>Да, это называется "инкапсуляция поведения".
поведение не бывает без состояния, а у тебя его нет, так как ты работаешь в основном с внешними данными.
в конце концов, прочти хотя бы основные паттерны проектирования, и ты поймешь, что они не ложатся на анемичную модель.
а вот структурное программирование более чем.
E>>а вот поведения объектов у тебя нет. G>Есть, у меня данных в этих объектах нет.
я писал выше. у тебя не объект, а сборище методов. в паскале это называлось — модуль.
E>>но зато ты и сам подтвердил свою причину непонимания DDD — ты не знаешь что такое ООП и не умеешь его применять на практике. отсюда и процедурный подход, которым ты так гордишься. G>Ты расстроешься, но я прекрасно знаю ООП во всех его инкарнациях, именно поэтому оно не вызывает у меня такой бури юношеских эмоций как у тебя.
у меня оно вызывает понимание проблемы и её решение. а ты остался на уровне турбо паскаля, чем жутко гордишься. но это твоё дело.
E>>>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. G>>>Не очевидно, докажи. E>>если тебе это не очевидно, могу только по соболезновать. G>Это тебе соболезновать надо. Ты говоришь глупость, сам в нее свято веришь и при этом не понимаешь тех кто не верит в нее. G>Такое бывает у сектантов и у сумасшедших. Хотя апологеты DDD проявляют черты и тех и других
вот видишь, от собственного бессилия ты начал переходить на личности и хамить. что в очередной раз подтверждает моё мнение о тебе, как довольно слабом программисте.
впрочем, интернет магазины тоже кто-то должен писать.
E>>ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать. S>Ваши доменные объекты занимаются делами вовсе не предметной области.
я разве писал что доменный объект сделает update в базе?
E>>а вот anemic, в общем-то, не является ООП подходом. S>С этого и начали этот флейм. Не согласен с категоричностью. Анемик он лишь о сущностях домена а не вцелом о подходе.
смысл фразы ускользает от меня
E>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. S>
S>очевидно — в знач. сказуемого совершенно ясно, не вызывает сомнений
S>Я не первый, у кого вышеописанное вызывает сомнения.
я не видел таких примеров.
хотя знаю попытки этим заниматься. пока неудачные.
есть примеры реализации 90% логики в базе данных. я считаю это так же можно отнести к процедурному подходу. очень плохое решение, хочу я вам сказать.
Здравствуйте, Enomay, Вы писали:
E>>>ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать. S>>Ваши доменные объекты занимаются делами вовсе не предметной области.
E>я разве писал что доменный объект сделает update в базе?
Что он решает где и какой update сделать.
E>>>а вот anemic, в общем-то, не является ООП подходом. S>>С этого и начали этот флейм. Не согласен с категоричностью. Анемик он лишь о сущностях домена а не вцелом о подходе.
E>смысл фразы ускользает от меня
Смысл в том, что в анемике поведением не обладают лишь объекты домена, что в общем случае не классифицирует анемик как не ООП.
E>>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. S>>
S>>очевидно — в знач. сказуемого совершенно ясно, не вызывает сомнений
S>>Я не первый, у кого вышеописанное вызывает сомнения.
E>я не видел таких примеров.
Я не видел крокодилов. Очевидно, их нет
E>хотя знаю попытки этим заниматься. пока неудачные. E>есть примеры реализации 90% логики в базе данных. я считаю это так же можно отнести к процедурному подходу. очень плохое решение, хочу я вам сказать.
Очевидно что нет, но сами приводите пример что есть. Пусть и неудачный.
E>>я разве писал что доменный объект сделает update в базе? S>Что он решает где и какой update сделать.
вызов update как следствие работы доменной модели, но не на прямую, конечно же.
E>>смысл фразы ускользает от меня S>Смысл в том, что в анемике поведением не обладают лишь объекты домена, что в общем случае не классифицирует анемик как не ООП.
возьмем 10 процедур. 3 структуры. они друг с другом взаимодействуют. все это написано на Object Pascal. Будет ли это ООП?
взять хотя бы википедию
Объект — некоторая сущность в виртуальном пространстве, обладающая определённым состоянием и поведением, имеет заданные значения свойств (атрибутов) и операций над ними (методов)[1]. Как правило, при рассмотрении объектов выделяется то, что объекты принадлежат одному или нескольким классам, которые в свою очередь определяют поведение (являются моделью) объекта.
я считаю что работа с анемиками в том виде, в котором его тут пропагандируют — это процедурное программирование. если вы считаете иначе, это ваше право. и мне, впрочем, нет никакого до этого дела.
E>>я не видел таких примеров. S>Я не видел крокодилов. Очевидно, их нет
приписываете себе логику блондинки
я о них даже не слышал. и пример никто привести не может. вывод напрашивается сам собой.
Здравствуйте, Enomay, Вы писали:
E>>>я разве писал что доменный объект сделает update в базе? S>>Что он решает где и какой update сделать.
E>вызов update как следствие работы доменной модели, но не на прямую, конечно же.
Это значит что модель предметной области не решает, где и какой update делать? Или решает таки?
S>>Смысл в том, что в анемике поведением не обладают лишь объекты домена, что в общем случае не классифицирует анемик как не ООП.
E>возьмем 10 процедур. 3 структуры. они друг с другом взаимодействуют. все это написано на Object Pascal. Будет ли это ООП?
Ответ на этот вопрос зависит не от количества процедур, структур, и не от языка, на котором выполнено взаимодействие. Построенное определенным образом взаимодействие вполне можно будет квалифицировать как ООП.
В вашем DDD (в вашей трактовке его) кроме объектов домена разве нет других объектов? На каком основании вы полагаете что раз у объектов домена не наблюдается поведение, то вся программа будет состоять из процедур и структур? Или вы так не считаете? К чему тогда пример с Object Pascal-ем?
E>взять хотя бы википедию E>
E>Объект — некоторая сущность в виртуальном пространстве, обладающая определённым состоянием и поведением, имеет заданные значения свойств (атрибутов) и операций над ними (методов)[1]. Как правило, при рассмотрении объектов выделяется то, что объекты принадлежат одному или нескольким классам, которые в свою очередь определяют поведение (являются моделью) объекта.
Нечего тут брать. Некоторая сущность... обладающая определенным состоянием и поведенеим... Как правило....
А вот по мнению Кея "Все является объектом".
E>я считаю что работа с анемиками в том виде, в котором его тут пропагандируют — это процедурное программирование. если вы считаете иначе, это ваше право. и мне, впрочем, нет никакого до этого дела.
Если вы классифицируете программы только по исполнению модели предметной области — то это ваше право...
E>>>я не видел таких примеров. S>>Я не видел крокодилов. Очевидно, их нет
E>приписываете себе логику блондинки
Я воспользовался вашей логикой. А теперь ей воспользовались снова вы: E>я о них даже не слышал. и пример никто привести не может. вывод напрашивается сам собой.
, сделав вывод из того о чем даже не слышали.
E>>вызов update как следствие работы доменной модели, но не на прямую, конечно же. S>Это значит что модель предметной области не решает, где и какой update делать? Или решает таки?
вызов update — это следствие работы доменной модели.
E>>возьмем 10 процедур. 3 структуры. они друг с другом взаимодействуют. все это написано на Object Pascal. Будет ли это ООП? S>Ответ на этот вопрос зависит не от количества процедур, структур, и не от языка, на котором выполнено взаимодействие. Построенное определенным образом взаимодействие вполне можно будет квалифицировать как ООП.
мне кажется количество как раз не является решающим фактором. 10 классов не делает подход более ООП, чем 2.
а вот взаимодействие, бесспорно. может.
но мы говорим о конкретной реализации — энемичной модели.
а она, реализации, как раз на ООП не особо то и похожа, на мой взгляд.
S>В вашем DDD (в вашей трактовке его) кроме объектов домена разве нет других объектов? На каком основании вы полагаете что раз у объектов домена не наблюдается S>поведение, то вся программа будет состоять из процедур и структур? Или вы так не считаете? К чему тогда пример с Object Pascal-ем?
разве я говорил что других объектов нет? конечно же есть. но мы говорим о ядре, как я понимаю.
но вполне вероятно, если человек использует процедурный подход для реализации бизнес логики, то он придерживается этого стиля и в остальных частях.
E>>взять хотя бы википедию E>>
E>>Объект — некоторая сущность в виртуальном пространстве, обладающая определённым состоянием и поведением, имеет заданные значения свойств (атрибутов) и операций над ними (методов)[1]. Как правило, при рассмотрении объектов выделяется то, что объекты принадлежат одному или нескольким классам, которые в свою очередь определяют поведение (являются моделью) объекта.
S>Нечего тут брать. Некоторая сущность... обладающая определенным состоянием и поведенеим... Как правило.... S>А вот по мнению Кея "Все является объектом".
у Кея, имхо, правильная трактовка, но дополнения, мне кажется, были введены для разграничения ООП (DDD) от не ООП (анемик)
S>Если вы классифицируете программы только по исполнению модели предметной области — то это ваше право...
не нужно мне приписывать чужого. я не классифицировал программы.
мы говорим о вариантах реализаций. при том беспредметно. весь этот тред, в общем-то, ни о чем.
E>>приписываете себе логику блондинки S>Я воспользовался вашей логикой. А теперь ей воспользовались снова вы: E>>я о них даже не слышал. и пример никто привести не может. вывод напрашивается сам собой. S>, сделав вывод из того о чем даже не слышали.
я обязательно изменю своё мнение, когда увижу эфективную реализацию БЛ на функциональных, а так же процедурных языках. а пока....
Лойда часто минусуют, но я с ним полностью согласен. Приятно видеть человека, который чётко и правильно что-то для себя осознал (что такое ООП) и может это продемонстрировать.
Для нас [Thompson, Rob Pike, Robert Griesemer] это было просто исследование. Мы собрались вместе и решили, что ненавидим C++ [смех].
Здравствуйте, Enomay, Вы писали:
G>>Как ты такое будешь хранить? Это надо вычислять.
E>совершенно необязательно. это достаточно вычислять 1 раз при оформлении пользовательского заказа.
Это надо вычислять постоянно, чтобы пользователь видел какую сумму он заплатит.
E>>>и о ужас! в основе её лежит доменная модель!!! G>>не-а, в её основе лежать очереди и воркеры, а доступ к данным может быть абсолютно любым.
E>вот видишь. то потому что ты видишь только то, что хочешь. E>но открою секрет, в середине лежит домен, который обрабатывает команды. E>посмотрю любую схему CQRS. там по центру есть такое, Domain Model называется.
Я за схемами еще и суть вижу. Думаешь если заменить domain model на обычные сервисы, которые ставят сообщения в очереди что-нить изменится? Ничего не изменится, только код проще станет. Я такое уже писал лет 5 назад и искренне смеялся когда увидел пафос вокруг CQRS.
Хотя domain model без CQRS плохо живется, как раз по причине того что в честном domain model просто так произвольный запрос не сделаешь.
G>>Слушал, такой бред рассказывает что смешно. E>а ты наверное умнее?
Нет, я такой бред не рассказываю на конференциях.
E>>>опять какие-то глупости пошли. E>>>в основе сервисов лежит DDD. это даже у Эванса есть. G>>А у меня нет, у меня сервиcы без DDD. E>не могу сказать что рад за тебя, но зачем мне эта информация?
Затем чтобы ты понимал что для сервиов ddd не нужен. DDD вообще не ненужен.
E>>>а иначе что делает сервис? тупо возвращает данные? G>>Когда надо возвращать — возвращает. Когда надо изменять — изменяет E>а логика изменения данных где лежит?
не поверишь — тоже в сервисах.
E>>>без проблем. используй анемик. разве тебя кто-то заставляет писать по другому? E>>>тебя даже никто не пытается переубедить. G>>Я хочу понять зачем использовать rich.
E>так попробуй понять это. напряги мозг, подумай. иначе никак не получится. никто тебе тут в примерах и сравнениях не покажет чем одно лучше другого, особенно когда оппонент не способен адекватно воспринимать информацию.
То есть явных преимуществ нет, и каждый должен их сам выдумывать чтоли?
E>я кажется и не требовал признания тобой моих слов) E>то тебе лень гуглить, то ты пишешь что хочешь понять зачем использовать рич. так хочешь все же, или лень?
Не выкручивайся, дай ссылку просто.
E>>>реализация логики в сервисе, это конечно можно. для процедурного программирования. но ООП как бы говорит о другом. и я придерживаюсь последнего подхода, в отличии от тебя. G>>А зачем ты его придерживаешься, что оно тебе дает?
E>ответ на этот вопрос уже звучал в этом треде. E>так же можешь почитать что-то на тему ООП, наверняка там будут описаны профиты.
То есть ты не знаешь.
E>>>эффективности при решении задач оно не убавляет. для больших проектов выгода очевидна. G>>Убавляет, тупо потому что больше кода писать надо.
E>выигрыш не в кол-ве строк, а в гибкости архитектуры.
И в гибкости архитектуры тоже. Например для масштабирования не надо прикручивать CQRS. SOA и так прекрасно масштабируется.
E>>>и опять ты кидаешься в крайности. для тебя если DDD, то материализовать всё. но это не так. G>>Ок, приведи пример где это не так. У тебя же логика в классах и без ссылки на класс ты её вызывать не можешь.
E>в CQRS модели шлем команду, обработчик которой вытаскивает при необходимости из базы дополнительные данные и передаёт все это модели, та уже выполняет логику. но варианты могут быть и другие.
Да сервис "шлет команду" (по сути ставит в очередь), другой сервис по этой "команде" запускается, выполняет обработку и сохраняет данные. Может еще другие "команды" слать. Это давно известная архитектура.
E>>>ты и такую задачу реализовать не можешь? G>>См SQL выше. Его же можно с помощью LINQ нагенерить (что я собственно и сделал в подобной задаче). E>это же можно использовать и в DDD. ничто не мешает.
В каком месте писать запрос? Внутри доменного объекта? Это неправильно с точки зрения DDD. В отдельном сервисе? Тогда зачем доменные объекты?
E>очень тяжело что-то объяснять человеку, который совершенно не понимает ООП, более того, считает при этом его ущербным. это как минимум бесполезное занятие.
Ты сам себе противоречишь. Чтобы считать что-то ущербным надо это понимать.
E>по этой причине я не стану ничего писать. но ты можешь прочесть пару книг, возможно это тебе поможет.
Я много книг прочитал, корреляция прочитанного с опытом показывает ущербность. Ты не видишь ущербности потому что у тебя достаточно опыта нету.
G>>Нет, я требую примеры кода от таких троллей, которые пишут лозунги и после каждого второго слова ссылаются на эванса, фаулера или еще кого. G>>Code talks.
E>может быть ты начнешь приводить свой код уже? а так же то, как ты видишь, оно должно выглядеть с точки зрения DDD, в твоей интерпретации. тогда предметно поговорим.
Так вот я и не знаю как оно должно выглядеть в DDD чтобы быть DDD , но достаточно эффективным. Все подходы эванса и фаулера веду к неэффективному коду, а мне тут постоянно доказывают что код будет эффективен.
E>>>опять глупости понеслись. Domain Model как раз очень четко вписывается в SRP, в отличии от твоих сервисов. G>>Ага, особенно одновременное совмещение задач по переносу данных и БЛ. Ведь ты можешь разделить эти обязанности без потери других характеристик, это само существование anemic показывает.
E>доменная модель не переносит никакие данные. она лишь хранит собственное состояние.
Да, а как состояние моедли отображается на экране? Создаются DTO для этого, которые в точности копируют структуру модели? Или как еще?
E>тебе уже намекали не один раз, твоя проблема — ты идешь от данных. в ООП нужно идти от модели. по этой причине ты не можешь понять.
Это не проблема, это преимущество, позволяющее писать меньше кода и сделать его более эффективным.
E>>>на самом деле наличие классов, наследование, полиморфизм и инкапсуляция, абсолютно не делают подход объектно ориентированным. у тебя класс это лишь объединение подобных по смыслу функций. G>>Да, это называется "инкапсуляция поведения".
E>поведение не бывает без состояния
Кто тебе такую глупость сказал?
E>а у тебя его нет, так как ты работаешь в основном с внешними данными
Именно, и ты тоже работаешь с внешними данными
E>в конце концов, прочти хотя бы основные паттерны проектирования, и ты поймешь, что они не ложатся на анемичную модель.
Не говори глупости наиболее востребованные паттерны: стратегия, команда, фабрика, декоратор, медиатор, composite, proxy и многие другие. Они как раз про поведение, а не про состояние. Среди большинства паттернов про состояние только builder и то целью его является переход от mutable к immutable, что вообще говоря является особенностью поведения.
E>>>а вот поведения объектов у тебя нет. G>>Есть, у меня данных в этих объектах нет. E>я писал выше. у тебя не объект, а сборище методов. в паскале это называлось — модуль.
да, это и есть модуль. Но в ОО-яызках есть интерфейсы, позволяющие делать loose coupling между модулями. Это очень хорошо.
E>>>но зато ты и сам подтвердил свою причину непонимания DDD — ты не знаешь что такое ООП и не умеешь его применять на практике. отсюда и процедурный подход, которым ты так гордишься. G>>Ты расстроешься, но я прекрасно знаю ООП во всех его инкарнациях, именно поэтому оно не вызывает у меня такой бури юношеских эмоций как у тебя. E>у меня оно вызывает понимание проблемы и её решение.
Эта тема началась с того что человек не смог с помощью ООП придумать решение конкретной проблемы.
Может ты расскажешь как с помощью ООП спроектировать анализатор трафика?
E>>>>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. G>>>>Не очевидно, докажи. E>>>если тебе это не очевидно, могу только по соболезновать. G>>Это тебе соболезновать надо. Ты говоришь глупость, сам в нее свято веришь и при этом не понимаешь тех кто не верит в нее. G>>Такое бывает у сектантов и у сумасшедших. Хотя апологеты DDD проявляют черты и тех и других
E>вот видишь, от собственного бессилия ты начал переходить на личности и хамить.
Если что это ты первый начал, но я решил тебя носом в это не тыкать.
Тем не менее это не отменяет факт твоего поведения близкого к сектантскому.
E>что в очередной раз подтверждает моё мнение о тебе, как довольно слабом программисте. впрочем, интернет магазины тоже кто-то должен писать.
Ты много интернет магазинов сделал? Наверное стоит пробовать устриц чтобы рассуждать об их вкусе.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>Неужели математической доказательство может отметить сложности технической реализации ? G>>Разве это отменяет возможность?
I>Я то говорил про сложность
Не выкручивайся.
I>То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ?
Где тут упоминание про сложность?
I>>>Каюсь, не знал. Я то думал на каждую операцию надо время, хотя бы и маленькое, а оказывается математика может _любую_ операцию сделать равной нулю по затратам времени. Не подскажешь, почему эта математика не может сделать так, что бы твой комп хотя бы загружался или просыпался за ровно 0 секунд ? G>>А ты считаешь что другие способы обработки большого объема данных будут быстрее? Написать sum в запросе гораздо проще, чем циклы и if_ы которые суммируют числа.
I>Ты еще 2+2 предложи в качестве примера
Так в том и прикол что запросы к БД обычно достаточно простые, а если попытаться сделать тоже самое в коде будет гораздо больше писаниниы.
I>Я считаю, что издержки select N+1 запросто могут быть наименьшими сравнивая с другими решениемя.
Предложи другое решение. Задача: для получения величины скидки необходимо получить сумму всех покупок без скидок за последний месяц.
I>>>>>Я немного не точно выразился, selеct n+1 это проблема реализации, но это пробема вторичная, реальная причина в самой предметной области, т.е. в той задаче которую хочет решить заказчик — слишком большой объём выборки для вычисления определенной функции. Слишкой большой это относительно возможностей современных технологий. G>>>>Ни разу он не большой. I>>>Это в твоих задачах объёмы небольшие. G>>Какая разница? Это отменяет тот факт что select n+1 — проблема реализации? I>Читай выделеное.
Слишком большой объем выборки — твоя выдумка.
I>>>Какие такие ? Ты уверен, что за 0.5с для реакции на мышиный клик, твой SQL Server подтянет любое необходимое количество инфы, которую нужно будет еще процессить дополнительно ? Чудеса, ты нашел сервер с бесконечно высокой скоростью, ну ка, поделись этой пулькой I>>>Я вот точно знаю, что для многих задач даже секунд будет недостаточно даже для того, что бы только подтянуть инфу, а у тебя какое то чудо выходит G>>Конечно получить список заказов для кастомера за последний месяц и всех его позиций с суммированием по цене SQL Server сделает достаточно быстро, чтобы уложиться в 0.5 сек. Главное сделать индексы правильные.
I>Я и говорю — это в твоих задачах надо мелочовку таскать вроде заказов за месяц.
Что ты этим хочешь сказать? Задача есть, она хорошо решается запросом и плохо решается кодом. Причем объемы обрабатываемых данных ограничен сверху, так как один клиент не будет больше какого количества в месяц покупать.
I>>>См. пример про смешение цветов. G>>Скопируй сюда чтоли, у меня книги под рукой нет. I>Книга у меня бумажная и дома, где нет компа
ну тогда вкратце суть. Я тоже не дома и книга от меня далеко.
E>>совершенно необязательно. это достаточно вычислять 1 раз при оформлении пользовательского заказа. G>Это надо вычислять постоянно, чтобы пользователь видел какую сумму он заплатит.
вычислять нужно скидку, а сумму заказов за текущий месяц достаточно вычислять только на момент оформления очередного заказа.
G>Я за схемами еще и суть вижу. Думаешь если заменить domain model на обычные сервисы, которые ставят сообщения в очереди что-нить изменится? Ничего не G>изменится, только код проще станет. Я такое уже писал лет 5 назад и искренне смеялся когда увидел пафос вокруг CQRS.
да да, ты гениален. только о тебе никто не знает. и мнение твое никого не волнует.
G>Хотя domain model без CQRS плохо живется, как раз по причине того что в честном domain model просто так произвольный запрос не сделаешь.
в домене не нужно делать произвольные запросы. они делаются до нее.
E>>не могу сказать что рад за тебя, но зачем мне эта информация? G>Затем чтобы ты понимал что для сервиов ddd не нужен. DDD вообще не ненужен.
тебе — не нужен. людям понимающим что это, и умеющим это применять — нужен.
все же просто.
E>>а логика изменения данных где лежит? G>не поверишь — тоже в сервисах.
тоесть, в процедурах. впрочем, об этом я уже говорил.
E>>так попробуй понять это. напряги мозг, подумай. иначе никак не получится. никто тебе тут в примерах и сравнениях не покажет чем одно лучше другого, особенно когда оппонент не способен адекватно воспринимать информацию. G>То есть явных преимуществ нет, и каждый должен их сам выдумывать чтоли?
что бы понять приимущства — нужно понять её. а непонимание и неумении её применять — не делает её говном. да. но ты все никак не хочешь этого понять.
E>>ответ на этот вопрос уже звучал в этом треде. E>>так же можешь почитать что-то на тему ООП, наверняка там будут описаны профиты. G>То есть ты не знаешь.
твое право считать как хочешь
E>>в CQRS модели шлем команду, обработчик которой вытаскивает при необходимости из базы дополнительные данные и передаёт все это модели, та уже выполняет логику. но варианты могут быть и другие. G>Да сервис "шлет команду" (по сути ставит в очередь), другой сервис по этой "команде" запускается, выполняет обработку и сохраняет данные. Может еще другие "команды" слать. Это давно известная архитектура.
конечно известная. просто в основе лежат разные принципы и разные реализации.
E>>это же можно использовать и в DDD. ничто не мешает. G>В каком месте писать запрос? Внутри доменного объекта? Это неправильно с точки зрения DDD. В отдельном сервисе? Тогда зачем доменные объекты?
для инкапсуляции логики, конечно же.
E>>очень тяжело что-то объяснять человеку, который совершенно не понимает ООП, более того, считает при этом его ущербным. это как минимум бесполезное занятие. G>Ты сам себе противоречишь. Чтобы считать что-то ущербным надо это понимать.
или наоборот, не понимать.
E>>по этой причине я не стану ничего писать. но ты можешь прочесть пару книг, возможно это тебе поможет. G>Я много книг прочитал, корреляция прочитанного с опытом показывает ущербность. Ты не видишь ущербности потому что у тебя достаточно опыта нету.
о да. ты конечно же можешь судить о моем опыте
а может быть ты считаешь это ущербной технологией, потому что ума не хватает понять ее?)
ведь на бейсике писать может каждый. а применять ООП увы.
E>>может быть ты начнешь приводить свой код уже? а так же то, как ты видишь, оно должно выглядеть с точки зрения DDD, в твоей интерпретации. тогда предметно поговорим. G>Так вот я и не знаю как оно должно выглядеть в DDD чтобы быть DDD , но достаточно эффективным. Все подходы эванса и фаулера веду к неэффективному коду, а мне тут постоянно доказывают что код будет эффективен.
это потому что ты не способен написать эффективный код.
начал бы приводить то что получается, возможно тебе бы подсказали, в каком месте ты ошибаешься.
E>>доменная модель не переносит никакие данные. она лишь хранит собственное состояние. G>Да, а как состояние моедли отображается на экране? Создаются DTO для этого, которые в точности копируют структуру модели? Или как еще?
зависит от потребностей. в некоторых случаях модель себя никак не отображает на экране. для этого есть собственно query, в СQRS.
E>>тебе уже намекали не один раз, твоя проблема — ты идешь от данных. в ООП нужно идти от модели. по этой причине ты не можешь понять. G>Это не проблема, это преимущество, позволяющее писать меньше кода и сделать его более эффективным.
не всегда в основе логики лежат данные, в том виде, в котором ты их воспринимаешь.
твое преимущество выплывает лишь в написании интернет магазинов.
E>>поведение не бывает без состояния G>Кто тебе такую глупость сказал?
поведение основано на каких-то данных, на основе которых принимается решение. а иначе это банальное действие.
E>>а у тебя его нет, так как ты работаешь в основном с внешними данными G>Именно, и ты тоже работаешь с внешними данными
нет. это ты смотришь на все данные — как на внешние, потому что во главе твоей архитектуры база данных.
E>>в конце концов, прочти хотя бы основные паттерны проектирования, и ты поймешь, что они не ложатся на анемичную модель. G>Не говори глупости наиболее востребованные паттерны: стратегия, команда, фабрика, декоратор, медиатор, composite, proxy и многие другие. Они как раз про поведение, а не про состояние. Среди большинства паттернов про состояние только builder и то целью его является переход от mutable к immutable, что вообще говоря является особенностью поведения.
они работают с объектами, которые имеют состояние. ты опять смотришь с другой стороны.
E>>я писал выше. у тебя не объект, а сборище методов. в паскале это называлось — модуль. G>да, это и есть модуль. Но в ОО-яызках есть интерфейсы, позволяющие делать loose coupling между модулями. Это очень хорошо.
ООП это не прибавляет)
G>Эта тема началась с того что человек не смог с помощью ООП придумать решение конкретной проблемы. G>Может ты расскажешь как с помощью ООП спроектировать анализатор трафика?
для анализатора трафика совершенно не обязательно применять ООП.
это же как микроскопом гвозди забивать.
E>>вот видишь, от собственного бессилия ты начал переходить на личности и хамить. G>Если что это ты первый начал, но я решил тебя носом в это не тыкать. G>Тем не менее это не отменяет факт твоего поведения близкого к сектантскому.
нет. я просто троллю, а ты впадаешь в крайности считая свой подход единственно верным.
E>>что в очередной раз подтверждает моё мнение о тебе, как довольно слабом программисте. впрочем, интернет магазины тоже кто-то должен писать. G>Ты много интернет магазинов сделал? Наверное стоит пробовать устриц чтобы рассуждать об их вкусе.
и не только магазинов. но к делу это не относится.
Здравствуйте, Enomay, Вы писали:
E>>>вызов update как следствие работы доменной модели, но не на прямую, конечно же. S>>Это значит что модель предметной области не решает, где и какой update делать? Или решает таки?
E>вызов update — это следствие работы доменной модели.
Весьма туманно
E>>>возьмем 10 процедур. 3 структуры. они друг с другом взаимодействуют. все это написано на Object Pascal. Будет ли это ООП? S>>Ответ на этот вопрос зависит не от количества процедур, структур, и не от языка, на котором выполнено взаимодействие. Построенное определенным образом взаимодействие вполне можно будет квалифицировать как ООП.
E>мне кажется количество как раз не является решающим фактором. 10 классов не делает подход более ООП, чем 2. E>а вот взаимодействие, бесспорно. может.
Я об этом и написал, разве нет?
E>но мы говорим о конкретной реализации — энемичной модели. E>а она, реализации, как раз на ООП не особо то и похожа, на мой взгляд.
На мой взгляд программа состоит не только из модели предметной области.
S>>В вашем DDD (в вашей трактовке его) кроме объектов домена разве нет других объектов? На каком основании вы полагаете что раз у объектов домена не наблюдается S>поведение, то вся программа будет состоять из процедур и структур? Или вы так не считаете? К чему тогда пример с Object Pascal-ем?
E>разве я говорил что других объектов нет? конечно же есть. но мы говорим о ядре, как я понимаю.
Слово ядро впервые упомянуто в этом топике. Напротив, вы тут приводили аналогии с Object Pascal-ем где не было разделения 10 процедур на ядро и остальное. E>но вполне вероятно, если человек использует процедурный подход для реализации бизнес логики, то он придерживается этого стиля и в остальных частях.
S>>Нечего тут брать. Некоторая сущность... обладающая определенным состоянием и поведенеим... Как правило.... S>>А вот по мнению Кея "Все является объектом".
E>у Кея, имхо, правильная трактовка, но дополнения, мне кажется, были введены для разграничения ООП (DDD) от не ООП (анемик)
Такого разграничения нет. Есть rich vs anemic. DDD типично строится на rich модели, но не ограничена ею со слов Э. и Ф.
S>>Если вы классифицируете программы только по исполнению модели предметной области — то это ваше право... E>не нужно мне приписывать чужого. я не классифицировал программы.
прошу прощения, подходы
а вот anemic, в общем-то, не является ООП подходом.
E>мы говорим о вариантах реализаций. при том беспредметно. весь этот тред, в общем-то, ни о чем.
Верно. И в том что он ни о чем — частично и ваша заслуга. Вы делаете сильные утвреждения и подтверждаете их фразами "я не слышал" и "вероятно".
S>>, сделав вывод из того о чем даже не слышали.
E>я обязательно изменю своё мнение, когда увижу эфективную реализацию БЛ на функциональных, а так же процедурных языках. а пока....
Раньше об эффективности не было ни слова. По вашему их просто не существовало...
Ну что же, а я не видел эффективных реализаций БЛ на рич DDD, таких, что нельзя было бы сделать эффективнее, перейдя к анемику, процедурщине, функциональщине. Но я из этого не делаю никаких выводов
Здравствуйте, gandjustas, Вы писали:
I>>>>Неужели математической доказательство может отметить сложности технической реализации ? G>>>Разве это отменяет возможность? I>>Я то говорил про сложность G>Не выкручивайся.
Я и не выкручиваюсь, если прочтешь выделеное внимательно, сам всё поймёшь.
G>
I>>То есть ты уверен, что всегда есть возможность написать один запрос который получает все данные ?
G>Где тут упоминание про сложность?
Это намёк такой, что есть задачи посложнее тех с которыми ты имел дело.
I>>Ты еще 2+2 предложи в качестве примера G>Так в том и прикол что запросы к БД обычно достаточно простые, а если попытаться сделать тоже самое в коде будет гораздо больше писаниниы.
Думаешь если запросы простые так и задача будет простой ?
I>>Я считаю, что издержки select N+1 запросто могут быть наименьшими сравнивая с другими решениемя. G>Предложи другое решение. Задача: для получения величины скидки необходимо получить сумму всех покупок без скидок за последний месяц.
Это ж ты говоришь, что select N+1 означает что ДДД может рожать только тормозные решения. Вот и предлагай решение
Я говорю о том, что проблема select N+1 есть следствие сложности задачи и вполне может быть приемлимой по издержкам относительно других способов.
I>>>>Это в твоих задачах объёмы небольшие. G>>>Какая разница? Это отменяет тот факт что select n+1 — проблема реализации? I>>Читай выделеное. G>Слишком большой объем выборки — твоя выдумка.
Не выдумка а факты. Я понимаю, что ты не веришь ни во что, кроме своих задач Но это ж не оправдание.
I>>Я и говорю — это в твоих задачах надо мелочовку таскать вроде заказов за месяц.
G>Что ты этим хочешь сказать? Задача есть, она хорошо решается запросом и плохо решается кодом. Причем объемы обрабатываемых данных ограничен сверху, так как один клиент не будет больше какого количества в месяц покупать.
Я ж сказал — это мелочовка.
I>>Книга у меня бумажная и дома, где нет компа G>ну тогда вкратце суть. Я тоже не дома и книга от меня далеко.
Не, ты ведь рассказывал что прочёл книгу ? И вдруг оказыается что даже вспомнить не можешь
Здравствуйте, Enomay, Вы писали:
E>>>насчет размазывания логики по нескольки объектам, ну так это ж банальный принцип "ответственности" из SOLID, да и ООП в целом. так что это правильная реализация. G>>В SOLID куча других принципов, да и за пределами SOLID тоже, и DDD, как его описывает эванс, многое нарушает.
E>нет, DDD это классическое ООП, и ничего не нарушает.
Эванс сам говорит, что для ДДД не важна ни архитектура, ни парадигма
E>>вызов update — это следствие работы доменной модели. S>Весьма туманно
проблема DDD ненавистников в том, что Эванс не разжевал и не разложил по полочкам, в том числе и на примерах кода, жизненный цикл программы. Кто, кого и зачем вызывает.
Он лишь даёт общие рекомендации. А вот кто и как это реализует, другое дело.
И люди часто прочитав Эванса, который описывает DDD методологию как решающую определенный набор проблем, замечу, не серебряную пулю, воодушевившись этим, пытаются применять написанное, не понимая что к чему. Толи опыт, толи еще что)
отсюда, после и берутся такие как мой оппонент, требующие! примеры реализаций, потому что сами не в состоянии этого сделать. они не хотят думать и эксперементировать, учиться новом, они хотят что бы им прямо показали почему оно лучше. но ведь так не бывает.
E>>но мы говорим о конкретной реализации — энемичной модели. E>>а она, реализации, как раз на ООП не особо то и похожа, на мой взгляд. S>На мой взгляд программа состоит не только из модели предметной области.
конечно! более того, DDD не является панацеей и для решения многих задач вообще не приемлема. как и ООП в целом. но те кто узко мыслит, думает что раз Эванс сказал — DDD — это круто, значит это должно быть круто и его нужно пихать куда попало. но не получается.
E>>у Кея, имхо, правильная трактовка, но дополнения, мне кажется, были введены для разграничения ООП (DDD) от не ООП (анемик) S>Такого разграничения нет. Есть rich vs anemic. DDD типично строится на rich модели, но не ограничена ею со слов Э. и Ф.
возможно и не ограничена. я реализаций не встречал. возможно они будут эффективны. не знаю.
E>>мы говорим о вариантах реализаций. при том беспредметно. весь этот тред, в общем-то, ни о чем. S>Верно. И в том что он ни о чем — частично и ваша заслуга. Вы делаете сильные утвреждения и подтверждаете их фразами "я не слышал" и "вероятно".
я лишь троллю своего оппонента и это довольно забавно. но я ни в коем случаи не пытаюсь тут что-то доказать, и даже не делал никаких безапелляционных громогласных заявлений. и не пытаюсь сравнивать две архитектуры.
не скрою, данная тема мне была бы интересна, будь она основана на чем-то. а так, как я уже писал, это легкий троллинг)
при этом, оппонент пытается мне доказать что-то, что мне совершенно не нужно и не интересно.
но это все лирика.
Здравствуйте, Enomay, Вы писали:
E>>>вызов update — это следствие работы доменной модели. S>>Весьма туманно
E>проблема DDD ненавистников в том
лирика. Но разве поклонникам DDD яснее, что означает "вызов update — это следствие работы доменной модели" после утвреждения что именно объект предметной области решает когда и как вызвать update?
E>>>но мы говорим о конкретной реализации — энемичной модели. E>>>а она, реализации, как раз на ООП не особо то и похожа, на мой взгляд. S>>На мой взгляд программа состоит не только из модели предметной области.
E>конечно! более того, DDD не является панацеей и для решения многих задач вообще не приемлема. как и ООП в целом. но те кто узко мыслит, думает что раз Эванс сказал — DDD — это круто, значит это должно быть круто и его нужно пихать куда попало. но не получается.
Я не пытался соскочить из области традиционного применения DDD куда-нибудь в компиляторостроение или компьютерное зрение. Я лишь отметил что считаю что в программе кроме модели предметной области есть и другие вещи. В ответ получил лирику про то что DDD не панацея.
S>>Такого разграничения нет. Есть rich vs anemic. DDD типично строится на rich модели, но не ограничена ею со слов Э. и Ф.
E>возможно и не ограничена. я реализаций не встречал. возможно они будут эффективны. не знаю.
Отлично. Я тоже не встречал. Более того, совершенно не представляю как по исходникам проекта написанного в DDD стиле но не в рич или вообще не в ООП, понять что он написан в духе DDD. Да и с ричем тоже. Проект может обладать свойствами, характерными для DDD в то время как его авторы даже не слышали о нем. Так же может не обладать свойствами DDD, даже в том случае если авторы думали что писали его в духе DDD.
E>>>мы говорим о вариантах реализаций. при том беспредметно. весь этот тред, в общем-то, ни о чем. S>>Верно. И в том что он ни о чем — частично и ваша заслуга. Вы делаете сильные утвреждения и подтверждаете их фразами "я не слышал" и "вероятно".
E>я лишь троллю своего оппонента и это довольно забавно.
Тогда я завязываю попытки докопаться до смысла ваших утвреждений, либо добиться смягчения их формы. Развлекайтесь
Здравствуйте, Sinclair, Вы писали:
L>>Эта формулировка все-таки существенно отличается от "ООП — оно целиком про поведение". S>Ну так я и не статью в рецензируемый журнал пишу.
Понимаешь в чем цимес, если выпячивать только эту сторону, то выходит, что процедурный подход более ООПшен, чем ОО, ибо в процедурах кроме поведения нет вообще ничего.
В ветке, где обсуждается процедурность vs объектная-ориентированность более логично подчеркивать тот аспект которые отличает эти две парадигмы, а не тот, что их сближает.
В этом отношении определение ООП из википедии вполне корректно, а цитаты Алана Кея — совсем неуместны.
Здравствуйте, Lloyd, Вы писали:
L>>>Эта формулировка все-таки существенно отличается от "ООП — оно целиком про поведение". S>>Ну так я и не статью в рецензируемый журнал пишу.
L>Понимаешь в чем цимес, если выпячивать только эту сторону, то выходит, что процедурный подход более ООПшен, чем ОО, ибо в процедурах кроме поведения нет вообще ничего.
А покажи-ка процедурную реализацию стека.
L>В ветке, где обсуждается процедурность vs объектная-ориентированность более логично подчеркивать тот аспект которые отличает эти две парадигмы, а не тот, что их сближает.
Вот вот, покажи пример со стеком и тебе сразу станет всё понятно.
Здравствуйте, Ikemefula, Вы писали:
L>>Понимаешь в чем цимес, если выпячивать только эту сторону, то выходит, что процедурный подход более ООПшен, чем ОО, ибо в процедурах кроме поведения нет вообще ничего.
I>А покажи-ка процедурную реализацию стека.
Сам осилишь: cтруктурка с указателем на вершину стека + пачка методов.
Здравствуйте, samius, Вы писали:
E>>возьмем 10 процедур. 3 структуры. они друг с другом взаимодействуют. все это написано на Object Pascal. Будет ли это ООП? S>Ответ на этот вопрос зависит не от количества процедур, структур, и не от языка, на котором выполнено взаимодействие. Построенное определенным образом взаимодействие вполне можно будет квалифицировать как ООП.
Это будет не ООП, а эмуляция ООП или ООП-стиль. Во всех букварях подробно объясняется, почему такой подход будет не ООП
Здравствуйте, Enomay, Вы писали:
E>ошибаешься, доменные объекты есть. именно они и решают где и какой update сделать.
E>а вот anemic, в общем-то, не является ООП подходом. E>разные реализации. ты используешь процедурный подход, мы ООП. E>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно.
Вы неправильно понимаете ООП. Анемик ничуть не менее ООП, чем рич. Вы просто ищете объекты не там, где надо.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
E>>а вот anemic, в общем-то, не является ООП подходом. E>>разные реализации. ты используешь процедурный подход, мы ООП. E>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. S>Вы неправильно понимаете ООП. Анемик ничуть не менее ООП, чем рич. Вы просто ищете объекты не там, где надо.
возможно. но мне почему-то казалось что подсчетом стоимости заказов должен заниматься объект Order, а не OrderService.
E>>возможно. но мне почему-то казалось что подсчетом стоимости заказов должен заниматься объект Order, а не OrderService. S>А можно пояснить, почему вам так казалось? S>1. Является ли подсчёт стоимости неотъемлемой частью поведения заказа?
я считаю что стоимость заказа — это свойство самого заказа, и логично если оно будет находится в нем. расчет же этой стоимости происходит, грубо говоря, суммированием всех продуктов в заказе.
S>2. Необходим ли для подсчёта стоимости заказа доступ к непубличной части его состояния?
исходя из вышесказанного, ему не требуется доступ за пределы себя самого, все необходимое он имеет.
S>3. Есть ли причины полагать, что для разных наследников класса Order будут реализованы разные способы подсчёта стоимости? (Реализацию моков в расчёт не берём — это артефакты процесса производства)
нет, ордер есть и будет оставаться всегда одним. он не содержит хитрых алгоритмов, он лишь суммирует кол-во записей внутри себя. а вот какую цифру вернут эти записи, зависит исключительно от них. и это уже зависит от внутренней реализации.
S>Вообще, в целом, какие конкретные преимущества даст внесение метода подсчёта стоимости заказа внутрь Order, по сравнению с размещением его снаружи? Желательно — конкретно. Ну там, если преимущество "гибкость" — то в чём именно, если "масштабируемость" — то каким образом она достигнется и т.д.
тем, что мы имеем иерархию классов, приблизительно такую
Order — OrderLine — Product
каждое звено в цепочке несет ответственность за себя. продукт знает свою цену. он же может вернуть свою цену со скидкой, если его взяли более 2х штук. например. или потому что сегодня вторник. все зависит от условий.
но в данном случае для изменения расчета скидки на продукт, нам нужно будет изменить только класс конкретного продукта, а не перелопачивать весь метод сервиса, который в итоге обрастет кучей if/case.
а класс Order останется неизменным.
SRP как бы
Здравствуйте, Enomay, Вы писали:
E>>>в корпоративном секторе ни процедурного, ни функционального подхода для реализации БЛ нет. что очевидно. S>>Вы неправильно понимаете ООП. Анемик ничуть не менее ООП, чем рич. Вы просто ищете объекты не там, где надо.
E>возможно. но мне почему-то казалось что подсчетом стоимости заказов должен заниматься объект Order, а не OrderService.
Почему же обязательно должен ? Представь себе, что есть заказы в разных валютах, есть всякие скидки — на конкретные товары, у кастомера, у менеджера, сезонная и тд и тд.
Теперь получается, что такой объект Ордер должен знать про всё на свете — про курсы валют, про все сущности которые имеют отношение к скидками. В итоге получается нарушение инкапсуляции — изменение логики скажем скидок влияет на Ордер.
Конечно, подсчёт стоимости заказа можно спокойно оставить в Ордер, но только в том случае, если для этого нужны исключительно объекты вроде OrderItem.
I>Почему же обязательно должен ? Представь себе, что есть заказы в разных валютах, есть всякие скидки — на конкретные товары, у кастомера, у менеджера, сезонная и тд и тд.
I>Теперь получается, что такой объект Ордер должен знать про всё на свете — про курсы валют, про все сущности которые имеют отношение к скидками. В итоге получается нарушение инкапсуляции — изменение логики скажем скидок влияет на Ордер.
I>Конечно, подсчёт стоимости заказа можно спокойно оставить в Ордер, но только в том случае, если для этого нужны исключительно объекты вроде OrderItem.
там рядом есть мой ответ на этот счет. я не говорил что ордер содержит алгоритм расчета. но он знает как получить общую стоимость.
а как это будет выглядеть в случаи с внешними сервисами?
Здравствуйте, Lloyd, Вы писали:
L>>>Понимаешь в чем цимес, если выпячивать только эту сторону, то выходит, что процедурный подход более ООПшен, чем ОО, ибо в процедурах кроме поведения нет вообще ничего.
I>>А покажи-ка процедурную реализацию стека.
L>Сам осилишь: cтруктурка с указателем на вершину стека + пачка методов.
И где же здесь "более ООПшен, чем ОО" ? Ни по одной версии, Симула или Кея, это не будет ООП. Для Симуловской классики инкапсуляция отсутствует начисто, полиморфизм невозможен в принципе(разве что через void**). Для Кеевской нужна мессагинг + идентити.
Здравствуйте, Enomay, Вы писали:
I>>Конечно, подсчёт стоимости заказа можно спокойно оставить в Ордер, но только в том случае, если для этого нужны исключительно объекты вроде OrderItem.
E>там рядом есть мой ответ на этот счет. я не говорил что ордер содержит алгоритм расчета. но он знает как получить общую стоимость.
"он же может вернуть свою цену со скидкой, если его взяли более 2х штук. например. или потому что сегодня вторник"
"возьми два ведра джек дениэлс и получи третье бесплатно" как продукт сможет узнать, что он в заказе у конкретного кастомера, который заказал его дважды ?
"для изменения расчета скидки на продукт, нам нужно будет изменить только класс конкретного продукта"
А кто будет знать, где какие скидки ? Вот например скидка "возьми разных товаров на сумму > 100$" => "получи доставку бесплатно". Как это сделать в продукте ?
Ордеры, ордерайтемы, продукты остаются, зато скидки и вся логика вокруг продаж может меняться сколько угодно.
E>а как это будет выглядеть в случаи с внешними сервисами?
В случае с сервисами логика скидок может меняться как угодно независимо от сущностей в модели. Параметры для сервиса скидок можно хранить в базе, но только параметры. Объекты-сущености ничего не будут знать ни про скидки, ни про то, кто и как вычисляет скидку.
Здравствуйте, Ikemefula, Вы писали:
L>>Павел, читайте пост, на который отвечаете. Не в первый раз уже советуют.
I>Ты слишком часто забываешь про что шла речь.
I>Ты сказал "процедурный подход более ООПшен, чем ОО"
Нет, Павел, я этого не говорил. Еще раз, Павел, повторюсь, не стоит вырывать слова из контекста, а уж из предложения и подавно не стоит.
E>>там рядом есть мой ответ на этот счет. я не говорил что ордер содержит алгоритм расчета. но он знает как получить общую стоимость. I>"возьми два ведра джек дениэлс и получи третье бесплатно" как продукт сможет узнать, что он в заказе у конкретного кастомера, который заказал его дважды ?
OrderLine знает кол-во этого продукта. он и передаст.
I>"для изменения расчета скидки на продукт, нам нужно будет изменить только класс конкретного продукта" I>А кто будет знать, где какие скидки ? Вот например скидка "возьми разных товаров на сумму > 100$" => "получи доставку бесплатно". Как это сделать в продукте ?
это уже будет в ордере.
I>Ордеры, ордерайтемы, продукты остаются, зато скидки и вся логика вокруг продаж может меняться сколько угодно.
E>>а как это будет выглядеть в случаи с внешними сервисами? I>В случае с сервисами логика скидок может меняться как угодно независимо от сущностей в модели. Параметры для сервиса скидок можно хранить в базе, но только параметры. Объекты-сущености ничего не будут знать ни про скидки, ни про то, кто и как вычисляет скидку.
ну, давайте на примере кода тогда, как все вышеперечисленное ляжет в него.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
E>>>возьмем 10 процедур. 3 структуры. они друг с другом взаимодействуют. все это написано на Object Pascal. Будет ли это ООП? S>>Ответ на этот вопрос зависит не от количества процедур, структур, и не от языка, на котором выполнено взаимодействие. Построенное определенным образом взаимодействие вполне можно будет квалифицировать как ООП.
I>Это будет не ООП, а эмуляция ООП или ООП-стиль. Во всех букварях подробно объясняется, почему такой подход будет не ООП
Мне лень перечитывать все буквари, попробую угадать. Потому что метод вызывается не через точку/стрелочку?
Здравствуйте, samius, Вы писали:
I>>Это будет не ООП, а эмуляция ООП или ООП-стиль. Во всех букварях подробно объясняется, почему такой подход будет не ООП S>Мне лень перечитывать все буквари, попробую угадать. Потому что метод вызывается не через точку/стрелочку?
Сообщения, идентити, инкапсуляция... Где это всё ?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>Это будет не ООП, а эмуляция ООП или ООП-стиль. Во всех букварях подробно объясняется, почему такой подход будет не ООП S>>Мне лень перечитывать все буквари, попробую угадать. Потому что метод вызывается не через точку/стрелочку?
I>Сообщения, идентити, инкапсуляция... Где это всё ?
Почем я знаю? Спроси себя. Я написал "определенное взаимодействие", ты что-то там выдумал и стал это выдуманное оспаривать.
Здравствуйте, Lloyd, Вы писали:
I>>Ты сказал "процедурный подход более ООПшен, чем ОО"
L>Нет, Павел, я этого не говорил. Еще раз, Павел, повторюсь, не стоит вырывать слова из контекста, а уж из предложения и подавно не стоит.
Процитированая фраза это отсылка к контексту Это же ты оспаривал формулировку "ООП — оно целиком про поведение" и в твоих словах "процедурный подход более ООПшен, чем ОО" это следствие. Потому я привел тебе пример, что бы продемонстрировать твою ошибку.
Раз уж ты любишь притворяться что непонял, то вот полная цитата:
"если выпячивать только эту сторону, то выходит, что процедурный подход более ООПшен, чем ОО, ибо в процедурах кроме поведения нет вообще ничего. "
"если выпячивать только эту сторону" — на примере стека — "то выходит" — а выходит то фигня какая то, которая и близко не ООП а у тебя каким то чудом вышло "процедурный подход более ООПшен, чем ОО"
Как ты вывел такое следствие — совершенно не ясно. Не подходит пример стека — возьми любой другой. В любом примере, где поведение зависит от предыстории сообщений придется забыть собственно про сообщения и явно приседать вокруг состояния.
Здравствуйте, samius, Вы писали:
I>>>>Это будет не ООП, а эмуляция ООП или ООП-стиль. Во всех букварях подробно объясняется, почему такой подход будет не ООП S>>>Мне лень перечитывать все буквари, попробую угадать. Потому что метод вызывается не через точку/стрелочку?
I>>Сообщения, идентити, инкапсуляция... Где это всё ? S>Почем я знаю? Спроси себя. Я написал "определенное взаимодействие", ты что-то там выдумал и стал это выдуманное оспаривать.
Ты написал, что в примере "возьмем 10 процедур. 3 структуры." можно реализовать не просто взаимодействие, а "можно будет квалифицировать как ООП". А как дошло до классификации, у тебя случилось "Почем я знаю?"
Из трёх структур и 10 процедур никакого взаимодействия которое "квалифицировать как ООП" не получится, максимум " эмуляция ООП или ООП-стиль". Это как например с подростками, которые любят одежду military style. такой стиль не делает их военными и даже не делает их одежду военной формой.
Здравствуйте, Ikemefula, Вы писали:
I>>>Ты сказал "процедурный подход более ООПшен, чем ОО"
L>>Нет, Павел, я этого не говорил. Еще раз, Павел, повторюсь, не стоит вырывать слова из контекста, а уж из предложения и подавно не стоит.
I>Процитированая фраза это отсылка к контексту
Фраза не была процитирована, она была вырвана из контекста и тем самым получила смысл, далекий от изначального.
I>Это же ты оспаривал формулировку "ООП — оно целиком про поведение" и в твоих словах "процедурный подход более ООПшен, чем ОО" это следствие.
Вы опять переврали, Павел. Я не оспарвал, что "ООП — про поведение", учитесь читать.
I>Потому я привел тебе пример, что бы продемонстрировать твою ошибку.
Ты читать сначала научись, потом будешь ошибки искать.
I>Раз уж ты любишь притворяться что непонял, то вот полная цитата: I>"если выпячивать только эту сторону, то выходит, что процедурный подход более ООПшен, чем ОО, ибо в процедурах кроме поведения нет вообще ничего. "
I>"если выпячивать только эту сторону" — на примере стека — "то выходит" — а выходит то фигня какая то, которая и близко не ООП
Эта "фигня" вполне соответствует приведенному определению ("ООП — оно целиком про поведение"). Если ты считаешь, что это фигня, то фигня — исключительно в определении, что и подтверждает дополнение этого определния, сделанное Sinclair-ом (идентичность).
I>а у тебя каким то чудом вышло "процедурный подход более ООПшен, чем ОО"
Нет, у меня вышло, что приведенное определение приодит к абсурдным выводам.
I>Как ты вывел такое следствие — совершенно не ясно.
Павел, если непонятно, откройте учебник логики для гуманитариев, обязательно полегчает.
I>Не подходит пример стека — возьми любой другой. В любом примере, где поведение зависит от предыстории сообщений придется забыть собственно про сообщения и явно приседать вокруг состояния.
Павел, вы сейчас с кем спорите, со мной или Sinclair-ом?
В проедложеной мною реалтзации стека есть как состояние, так и "сообщения". Я присел вокруг него настольно сильно, что аж выделил в отдельную сущность.
Хотя извини, постоянно забываю, что ты читать не умеешь.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>>>Это будет не ООП, а эмуляция ООП или ООП-стиль. Во всех букварях подробно объясняется, почему такой подход будет не ООП S>>>>Мне лень перечитывать все буквари, попробую угадать. Потому что метод вызывается не через точку/стрелочку?
I>>>Сообщения, идентити, инкапсуляция... Где это всё ? S>>Почем я знаю? Спроси себя. Я написал "определенное взаимодействие", ты что-то там выдумал и стал это выдуманное оспаривать.
I>Ты написал, что в примере "возьмем 10 процедур. 3 структуры." можно реализовать не просто взаимодействие, а "можно будет квалифицировать как ООП". А как дошло до классификации, у тебя случилось "Почем я знаю?"
У меня случилось "почем я знаю" по поводу того, что ты обсуждаешь. Лично я не вижу никаких ограничений с тем что бы в 3х структурах и 10 процедурах организовать сообщения, идентити, инкапсуляцию, полиморфизм и не только это, и назвать это определенным взаимодействием.
I>Из трёх структур и 10 процедур никакого взаимодействия которое "квалифицировать как ООП" не получится, максимум " эмуляция ООП или ООП-стиль".
Я так не считаю I>Это как например с подростками, которые любят одежду military style. такой стиль не делает их военными и даже не делает их одежду военной формой.
Отличный съезд с темы
E>>я считаю что стоимость заказа — это свойство самого заказа, и логично если оно будет находится в нем. S>Это достаточно неожиданное предположение, которое, вообще говоря, нужно аргументировать. S>Не всё, что можно рассчитать о заказе, стоит считать его свойством. Вот, скажем, среднеквадратичное отклонение количеств товарных позиций — это тоже "свойство самого заказа". Логично ли, если оно будет находиться в нём?
отклонение чего от чего?
какое это отношение имеет к текущему пользовательскому заказу?
E>>расчет же этой стоимости происходит, грубо говоря, суммированием всех продуктов в заказе. S>Хм. Это очень интересный момент, вот это "грубо говоря". Сразу возникает вопрос — а когда это может быть не так? S>Стоимость, о которой мы говорим, это уже с учётом скидок или нет? Если с учётом, то мы потенциально имеем циклическую зависимость — стоимость зависит от скидки, которая зависит от стоимости.
не говорите глупости.
если скидка нужна от общей суммы, то мы можем её считать в методе GetTotal. если скидки высчитываются по какому-то хитрому алгоритму в зависимости от общей суммы, то используем стратегию.
S>>>2. Необходим ли для подсчёта стоимости заказа доступ к непубличной части его состояния? E>>исходя из вышесказанного, ему не требуется доступ за пределы себя самого, все необходимое он имеет. S>Вы отвечаете не на тот вопрос. Я спрашивал ровно обратное — требуется ли ему доступ "вовнутрь", к чему-то такому, что не видно снаружи.
он имеет доступ к внутренним коллекциям, а вот должны они быть видны из вне, или нет, зависит от задачи.
в любом случаи не он сам их создает.
E>>нет, ордер есть и будет оставаться всегда одним. он не содержит хитрых алгоритмов, он лишь суммирует кол-во записей внутри себя. а вот какую цифру вернут эти записи, зависит исключительно от них. и это уже зависит от внутренней реализации. S>Отлично. То есть производительность у нас тут гарантированно хреновая. Поясню на примере: если мы влезаем в один из OrderLine и меняем его quantity, то при сохранении нам нужно пересчитать OrderTotal. А для этого, в свою очередь, нужно материализовать все OrderLine, а не только ту, которая изменялась, и повызывать у каждой из них GetTotal(), который, в свою очередь, потребует материализовать Product(), чтобы позвать у него GetPrice(). То есть мы имеем как бы O(N) обращений к DAO на ровном месте. S>Что характерно, никакой "логики" (то есть нетривиального поведения) ни у каких объектов здесь нет. Вся их работа сводится к тому, чтобы запретить программисту получать тот же результат через S>
S>select sum(quanity * p.price) from orderLine ol inner join product p on ol.productId = p.Id where orderLine.orderId = @orderID
S>
Объект Order со всеми вложенностями может быть матириализован один раз, при изменении quantity у OrderLine, мы получим новую сумму заказа при вызове Order.GetTotal(), при этом мы не полезем в базу.
далее, материализация вложенного объекта выполняется 1м запросом, в данном случаи с 2мя джойнами, и лишь один раз.
тоесть, мы имеем производительность ни чем не хуже.
при этом, реализация БЛ производится на нормальном языке, а не в базе. что имеет массу своих преимуществ, о которых в интернете полно статей.
E>>но в данном случае для изменения расчета скидки на продукт, нам нужно будет изменить только класс конкретного продукта, а не перелопачивать весь метод сервиса, который в итоге обрастет кучей if/case. E>>а класс Order останется неизменным. E>>SRP как бы S>Отлично. Вы не только неправильно понимаете ООП, SRP вы тоже понимаете неверно. S>Поясню: S>1. Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе (покупателя, оформляюшего менеджера, и т.д). Вы засовываете в него ещё одну обязанность — подсчитывать сумму позиций. S>Очевидно, что логика "подсчитать сумму позиций" будет применима не только к Order, но ещё много к чему. К накладной, счёт-фактуре, возвратной накладной, акту пересортицы, и прочему. Из-за того, что вы всунули эту логику внутрь заказа, вы будете вынуждены заниматься унылым Copy-Paste. Ну или мучительно думать, кого из этих классов от кого отнаследовать — в целом это изоморфно знаменитой проблеме "эллипс vs круг".
это кто вам сказал что "Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе"?
вы, как и часть здешних, пихаете всё в базу, я правильно понял? тогда позиция определённо ясна.
кто же тогда должен считать сумму заказа? и почему это должен делать кто-то, а не сам заказ, при том что у него для этого есть все необходимые данные?
второй абзац ересь какая-то. вы бы хоть схему нарисовали, или класс накидали. а то выдумали что-то.
S>2. Продукт у вас, помимо обязанности "предоставлять информацию о продукте", стал внезапно обязан рассчитывать собственную стоимость. S>Такой продукт крайне сложно реализовать. S>Ваше предложение "вернуть свою цену со скидкой, если его взяли более 2х штук" просто прекрасно — тем, что непонятно как его реализовать. В продукте нет информации о том, сколько его взяли. Банальная схема "взявшему два третий бесплатно" в принципе нереализуема при такой иерархии объектов.
когда ордер будет считать стоимость, он спросит все свои OrderLine о их сумме, каждый OrderLine спросит о стоимости товара и помножит её на кол-во.
при этом, он спокойно передает это кол-во в товар, который вернет в зависимости от этого новую цену, уже со скидкой. все ж просто.
а вы усложняете.
S>Уже пункта 1 достаточно для того, чтобы даже оставаясь в рамках заведомо тормозной и плохомасштабируемой Rich-ORM модели захотелось сделать что-то вроде
S>
skipped
S>
S>То есть тут даже OrderService не нужен — это, вообще говоря, настолько банальная арифметика, что вставлять её в модель вообще пахнет оверархитектингом.
модель выполняет только свои обязанности.
вышенаписанное ни чем ни лучше. но это только вершина. а как будет расчитываться все остальное в иерархии?
S>В пункте 2 мы понимаем, что задача "ввести в систему новую скидку" эквивалентна задаче "внести новый класс продукта". Вы думаете, что это гораздо легче, чем поменять класс типа OrderService.
у вас есть 5 товаров. у каждого своя стратегия расчета скидок.
в моём случае, каждый товар сам знает свою стратегию. и мне придется изменить или 1 продукт, или добавить новый.
в вашем. все 5 стратегий в 1м методе. на сколько-то десятков строк. добавление/изменение всегда заставит менять этот метод. а это может повлиять на другие его части.
то есть один метод знает как считать скидки для совершенно разных объектов.
а это очень плохой подход.
S>А у вас уже продумана схема смены класса для существуюшего объекта? Буквари ООП стыдливо обходят этот вопрос молчанием. И правильно делают — в общем случае ничего хорошего ООП не предлагает.
существующего где?
S>OrderService имеет замечательную особенность — он Stateless. То есть мы можем его в любой момент заменить. Мы можем позволить старому и новому OrderService работать одновременно, до окончания всех транзакций, обрабатываемых OrderService. Поэтому любые изменения туда стоят значительно меньше, чем изменения в классе Product.
когда условий станет очень много, изменения сервиса будут сложнее. гораздо сложнее. но опять же, не видя код сервиса, сложно предположить с трудностях, с которыми придется столкнутся. но их будет не меньше, чем в моем случае.
S>При этом вы почему-то думаете, что OrderService обрастёт каким-то набором "if-else" для расчёта скидки, как будто там запрещено использовать наследование, полиморфизм, и агрегацию.
тоесть вы будете порождать тонные объектов и наделять их не свойственной для них логикой? ради бога.
S>На мой взгляд, всё как раз наоборот — в DiscountService у нас доступно всё. И история заказов конкретного кастомера, на основе которой мы можем перевести его в класс "ВИП клиентов" со своим набором скидок. И данные о количестве товаров каждого вида в данном заказе, чтобы реализовать "взявшему два по 0.5 Старого Мельника третья кружка бесплатно". S>И данные о том, в какое время заказ был сделан и оплачен, чтобы реализовать happy hour. S>А использовать эти данные при помощи if-else совершенно необязательно. Ведь есть же ООП. Десятки паттернов — визитор, стратегия, и прочее. Можно строить произвольные цепочки из бизнес-правил при помощи совсем небольшого набора правил по композиции их друг с другом. Это значительно удобее, чем писать всё в топорном стиле хранимых процедур.
конечно можно. так и делайте.
только я считаю что нет необходимости порождать ненужные сущности, если у нас уже имеются конкретные объекты, которые мы можем наделить свойственными только им обязанностями.
а если вы считаете что сумма заказа — это не обязанность заказа, ваше дело
хотите предметную дискуссию, можно описать задачу, и сделать 2 реализации, на основании которых и сравнивать.
Здравствуйте, Enomay, Вы писали:
E>>>там рядом есть мой ответ на этот счет. я не говорил что ордер содержит алгоритм расчета. но он знает как получить общую стоимость. I>>"возьми два ведра джек дениэлс и получи третье бесплатно" как продукт сможет узнать, что он в заказе у конкретного кастомера, который заказал его дважды ?
E>OrderLine знает кол-во этого продукта. он и передаст.
А откуда он узнает, какую скидку применять ? А если например "возьми два ведра джек дениэлс и получи __вёдра__ бесплатно", то как OrderLine узнает про вёдра ?
I>>"для изменения расчета скидки на продукт, нам нужно будет изменить только класс конкретного продукта" I>>А кто будет знать, где какие скидки ? Вот например скидка "возьми разных товаров на сумму > 100$" => "получи доставку бесплатно". Как это сделать в продукте ?
E>это уже будет в ордере.
Т.е. выходит что ордер должен знать обо всём в программе, начиная от скидок, конверсии валют до ролей юзеров, так что ли ?
А каким образом менять скидки ? Находить все ордеры, орделайны и тд и модифицировать их до тех пор пока ордер не будет оплачен и закрыт ?
E>>>а как это будет выглядеть в случаи с внешними сервисами? I>>В случае с сервисами логика скидок может меняться как угодно независимо от сущностей в модели. Параметры для сервиса скидок можно хранить в базе, но только параметры. Объекты-сущености ничего не будут знать ни про скидки, ни про то, кто и как вычисляет скидку.
E>ну, давайте на примере кода тогда, как все вышеперечисленное ляжет в него.
Можно даже без кода. В Order оставляем только OrderLine, никаких методов вроде вычисления суммы заказа там быть не должно.
var rates = new CurrencyRates();
var discountSvc = new DiscountService();
var orderSvc = new OrderService(discountSvc,rates);
var price = orderSvc.TotalPrice(order);
Теперь смотри. Внезапно оказывается, что фирме нужно включать в заказ еще и доставку, а её рассчет зависит от целой пачки факторов — дата-время доставки, адрес и тд и тд. Т.е. всунуть это в ордер не представляется возможным
var rates = new CurrencyRates();
var discountSvc = new DiscountService();
var deliverySvc = new DeliveryService();
var orderSvc = new OrderService(discountSvc,rates, deliverySvc);
var price = orderSvc.TotalPrice(order);
Т.е. логику вычисления стоимости заказа ожно модифицировать как угодно. Как быть, если вся она в классе Ордер ? Получается так, что класс Ордер будет жостко завязан на всех участников операции — скидки, доставка, валюта и тд и тд.
Как быть если фирма делегирует доставку другой фирме ? Опаньки, надо переписывать всё подряд. А вот в случае с сервисами нужно переписать только один сервис.
Здравствуйте, 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>Каким правилом руководствоваться что бы выяснить, что свойственно а что не свойственно для Ордер ? Ну кроме "я так считаю" и "очевидно"
правил нет. каждый волен делать так, как считает нужным. тут нет единственно верного решения. у всех свои предпочтения.
Здравствуйте, 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>правил нет. каждый волен делать так, как считает нужным. тут нет единственно верного решения. у всех свои предпочтения.
Предпочтения разные, зато разные варианты дизайна имеют совершенно разную стоимость разработки, сопровождения и внедрения, при чем это всё измеряемо. Потому правила есть, хотя они и не полностью формализуемы.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>Покажи его. S>>А то что? А то ты останешься при своем мнении? Да чихать.
I>Ты что, пишешь в форум что бы поменять чьё то мнение ?
Проблемы в личной жизни?
I>>>Вероятно, твой пример это "я так щитаю" S>>Вероятно, мне пофигу. Если ты сам не можешь написать такой пример и/или обнаружить в нем перечисленные явления — то это не мои проблемы.
I>Очевдино, это уже обсуждавшаясь ранее тема "эталонов"
Без понятия, о чем ты.
E>>какое это отношение имеет к текущему пользовательскому заказу? S>Ну, точно такое же, как "сумма стоимостей всех позиций". Её тоже можно посчитать на основе только лишь данных заказа.
одного заказа? конкретного?
а для чего?
E>>не говорите глупости. E>>если скидка нужна от общей суммы, то мы можем её считать в методе GetTotal. если скидки высчитываются по какому-то хитрому алгоритму в зависимости от общей суммы, то используем стратегию. S>Отлично. А в какой именно класс мы будем инжектировать стратегию?
в Order? возможно. а возможно и не туда. зависит от типа скидки.
E>>он имеет доступ к внутренним коллекциям, а вот должны они быть видны из вне, или нет, зависит от задачи. S>Вот это интересно. Если у ордера нет public ... Items { get;} — то, конечно же, единственный способ подчитать Total будет реализовать его в ордере.
они видны, но мало ли какую информацию может в себе таить ордер? возможно, мы не хотим раскрывать некоторые детали реализации?
E>>это кто вам сказал что "Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе"? S>Попробуйте отъять у ордера эту обязанность. Что у вас останется?
акцент наверное был на "только".
E>>вы, как и часть здешних, пихаете всё в базу, я правильно понял? тогда позиция определённо ясна. S>Что именно вы называете "всё"? Да, я рассчитываю хранить заказы в RDBMS.
я имею ввиду логику.
E>>кто же тогда должен считать сумму заказа? S>Я же уже сказал — что-то вроде OrderUtils.
почему он, а не ордер?
E>>и почему это должен делать кто-то, а не сам заказ, при том что у него для этого есть все необходимые данные? E>>второй абзац ересь какая-то. вы бы хоть схему нарисовали, или класс накидали. а то выдумали что-то. S>Спокойнее. Вы же не думаете, что в жизни будет ровно один класс данных с "позициями", и вы назовёте его "Order". Какую схему вы ожидаете? Схему наследования всех этих документов друг от друга? Ну так я вам и объясняю, что внятную схему наследования построить не получится.
E>>когда ордер будет считать стоимость, он спросит все свои OrderLine о их сумме, каждый OrderLine спросит о стоимости товара и помножит её на кол-во. E>>при этом, он спокойно передает это кол-во в товар, который вернет в зависимости от этого новую цену, уже со скидкой. все ж просто. E>>а вы усложняете. S>Этот момент я уже понял. Получается очень хрупкая система, с большим количеством нарушений SRP, и круговыми зависимостями.
только в вашем воображении)
по вашему существуют только ДТО и утилиты. вот и пользуйтесь функциональным подходом. я то тут причем?
E>>модель выполняет только свои обязанности. E>>вышенаписанное ни чем ни лучше. но это только вершина. а как будет расчитываться все остальное в иерархии? S>Что такое "всё остальное"?
цены, скидки.
S>Вот например — мы только что договорились с производителем DVD-плееров, что будем давать плееры бесплатно при покупке телевизора.
как это относится к логике расчета стоимости заказа?
S>Вас не затруднит привести реализацию метода Product.GetDiscountedPrice(int quantity) для этого случая? S>И поясните мне ещё раз — я правильно понимаю, что у вас на каждый товар свой класс? То есть для моего случая нужно написать 12000 разных классов? Если нет, то сколько всего наследников мне нужно иметь в иерархии Product?
столько, сколько необходимо. это же просто)
E>>в вашем. все 5 стратегий в 1м методе. на сколько-то десятков строк. добавление/изменение всегда заставит менять этот метод. а это может повлиять на другие его части. S>С чего вы взяли, что в 1м методе?
значит в 10 переплетенных по каким-то условиям. от этого не легче.
S>В базе. Конечно же в базе. Мы этими DVD-плеерами уже четыре года торгуем, потому на них такая программа и пошла. Вы вообще хоть раз в жизни в магазине были? Вот у меня задача — провести распродажу обуви осенней коллекции. Как это сделать в вашей архитектуре? Все товары были и до этого.
добавить скидку на обувь определенного класса?
E>>когда условий станет очень много, изменения сервиса будут сложнее. гораздо сложнее. но опять же, не видя код сервиса, сложно предположить с трудностях, с которыми придется столкнутся. но их будет не меньше, чем в моем случае. S>Вы зачем-то нафантазировали себе какую-то монолитную реализацию этого сервиса. Зачем?
за тем же, зачем вы фантазируете монолитную реализацию ордера
более того, на ордер у вас рапспространяется даже то, чего там быть не должно. а ведь это всего лишь заказ.
S>В реальной жизни сервис был бы устроен примерно так:
все это отлично кладётся в ордер, где имхо ему и место. но вы в праве думать иначе.
S>Как видите — ООП в полный рост. Просто объекты не там, где вы привыкли их искать.
вот вот. просто я храню реализацию не там, где вы. она от этого несколько меняется, но хуже не становится.
E>>тоесть вы будете порождать тонные объектов и наделять их не свойственной для них логикой? ради бога. S>Забавно, но на мой взгляд всё ровно наоборот — это вы порождаете тонны объектов там, где вообще никаких объектов нет (а есть просто данные), и наделяете их совершенно несвойственной им логикой. Но это всё субъективно, так продолжим же объективные рассуждения.
у вас данные, у меня объекты. разница в подходах.
я не буду спорить, что применимо к интернет магазину, ООП подход как таковой, в частности ДДД, который тут неоднократно упоминали, лучше, нежели анемик. но в то же время я уверен что и рич модель будет эффективной.
E>>только я считаю что нет необходимости порождать ненужные сущности, если у нас уже имеются конкретные объекты, которые мы можем наделить свойственными только им обязанностями. E>>а если вы считаете что сумма заказа — это не обязанность заказа, ваше дело S>Рано или поздно вы тоже поймёте, что сумма заказа — не обязанность заказа. Вот вы сходу бросились решать задачу со скидками и угодили в стандартную ловушку. Потому, что вам показалось, что это товар "ведёт себя так" в заказе. Нет! Это не пылесос решает "продайте меня за полцены". Это менеджер принимает решение: "пылесос мы продадим со скидкой 50%, потому что он входит в программу утилизации".
это не изменит реализации. мы установим на товар скидку, а Order.GetTotal() в данном случаи не изменится но вернет правильную сумму.
у нас проблема в том, что мы оперируем разными понятиями и не можем понять друг друга.
S>Далее видно, что менеджер принимает решение не с потолка, а на основе системы правил. В итоге, вместо того, чтобы выполнять анализ в ненужную сторону — "поведения товаров", мы продолжим копать в сторону системы правил. Постараемся выписать все действовавшие когда-либо правила, действующие сейчас, и какие правила планируется применять. Поищем между ними общее, разное. Посмотрим, какие данные нужны правилам, чтобы действовать. И применим всю мощь ООП для моделирования "менеджера", который превратится в DiscountService, и правил. А товары, ордера, строки и прочее так и останутся данными, которыми они и были всю жизнь с 16 примерно века, пока не пришёл Фаулер и не сбил всех с толку.
если это работает, и работает так, как нужно, это здорово, и нет необходимости что-то менять.
я бы пошел по другому пути. лучше, хуже, не знаю.
но раз появился Фаулер со своей идеологией, и её подхватили, значит есть и для них свои задачи
I>То есть, в обязанности продукта входит знание о всех возможных скидках ?
опять занимаешься ерундой. я такого не говорил.
I>>>А каким образом менять скидки ? Находить все ордеры, орделайны и тд и модифицировать их до тех пор пока ордер не будет оплачен и закрыт ? E>>опять нет. но зависит от типа скидок. а сами скидки вполне могут где-то хранится в виде набора правил. в базе, в хмл, в коде. I>Они так и хранятся и как правила логика этой части меняется очень часто. Каким образом ордер или продукт будет знать, какая стратегия может к ним применяться ?
таким же, как и при реализации с сервисами.
E>>доставка — это услуга, имеющая цену, и вполне отлично ложится в ордер, как и продукт. так же, как к проданному ПО может добавится услуга по его установке, настройке. I>Рассчет цены каким образом делать ? Ордеру придется завязываться на особенности реализации доставок, услуг и тд.
ордеру ничего на себе завязывать не придется. абстрактный пример может выглядеть так:
var total = order.GetTotal();
IProduct delivery = DeliveryService.GetDelivery(total, ..., ...);
order.Add(delivery);
соответственно сервис вернет стоимость доставки 0, если сумма заказов >1000, или 35 грн, если ниже 1000.
при том в заказах мы увидим эту стоимость, а так же увидим изменение общей стоимости заказа, с учетом добавившихся 35 грн.
E>>всё это вытекает из придуманных лишних сложностей. доставка ложится в заказ, с её стоимостью, в зависимости от типа доставки. I>Сложности не лишние, это требования бизнеса. Стоимость доставки может зависеть от качественного и количественного состава заказа, а стоимость заказа в свою очередь зависит от стоимости доставки Опаньки !
сложности в реализации имелись в виду конечно же но их нет.
и не забывай, мы обсуждаем абстрактный пример, а для него может быть великое множество решений.
Здравствуйте, Sinclair, Вы писали:
I>>То ли ты чего то не видишь, то ли у тебя есть пример который покажет что этих ограничений нет. Желательно про сообщения, идентити и инкапсуляцию. Ну и про структуры и процедуры не забывай.
S>А чего далеко ходить. WinAPI — в значительной мере ООП. CloseHandle, к примеру, даже полиморфный. В чём вопрос-то?
Я собственно и ждал похожего примера. Хочется узнать что такое "в значительной мере ООП", т.к. этой фразой подразумевается, что ООП не совсем полноценный.
В данном случае квази-OOP достигается не за счет языковых средств, а за счет возможностей/особенностей операционной системы. А хотелось бы примерно так как было обещано на Object Pascal.
E>>ты передёргиваешь. I>Ты объясни, откуда Ордер будет знать про таблицы валют, скидки, доставки, услуги и тд и тд. Как узнать при оплате заказа, что на момент составления действовала определенная система скидок ?
оттуда же, откуда и сервис. ордеру все равно в какой валюте считать. всё равно изначально вся цена в одной валюте.
стоимость же всего остального известна, и все эти пункты являются пунктами ордера, на равне с товарами.
E>>ему предоставили необходимую информацию. как и сервису. E>>ты слишком утрируешь, доводя до крайности. I>Где и как эта информация будет храниться, в каокм виде ? Ну, таблица курсов та же или система скидок которая действовала на момент оформления заказа ?
так же, как и в сервисе.
>>все эти правила расчета могут быть получены 1 раз при создании объекта Order. а могут быть вообще закешированы на уровне приложения, и доступ к ним будет быстрым при необходимости. для каждой конкретной задачи, своё конкретное решение. I>Как это будет храниться в базе ? Позиции могут добавляться, удаляться, изменять цену и тд и тд. Как это оформить один раз при создании объекта ордер ?
ORM отлично справляется с этой задачей.
I>Ты же не даёшь внятного ответа.
ты пытаешься приписать ордеру лишние возможности. конечно я не дам решения этих проблем. ибо их нет.
E>>мы говорим о расчете стоимости заказа конкретного пользователя, или о возвратах, поставках, трансферах? к чему они тут? I>Мы вообще то говорим об ООП, в данном случае про такую вещь как дублирование функционала из за неправильного применения принципов ООП. А стоимость заказа это просто хороший пример.
я не вижу дублирования. или во всех случаях расчет один и тот же? но это ведь не проблема.
I>>>Поподробнее, как товар/ордер/позиция узнает, что скидка даётся в зависимости от I>>>1. даты — на НГ каждый второй бесплатный E>>стратегия? I>Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
параметры могут быть как в ордере, так и как в сервисе. код в ордере.
I>>>2. времени — за полчаса за закрытие -1% E>>стратегия? I>Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
см. выше.
I>>>3. кастомера — постоянным скидка E>>стратегия? I>Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
см. выше.
I>>>4. менеджера — менеджер даёт скидку что бы "купить" кастомера E>>ApplyDiscount? стратегия? I>Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
см. выше.
I>>>5. полномочий менеджера — "новые менеджеры" не имеют некоторых скидок E>>так он ничего и не сможет сделать. но это контролируется другим уровнем. I>То есть, за подсчет цены отвечает какой то другой уровень что ли ?
за то, может ли он добавить скидку или нет. а если может, то мы её посчитаем.
причем тут полномочия менеджера к расчету стоимости заказа?
I>>>6. товара — возьми два xxx получи третий бесплатно (например когда в упаковке по три) E>>в товаре? I>Я не представляю реализации этой скидки в товаре.
а я представляю. вот и вся разница.
E>>это вообще отдельное полиси. мы будем считать в ордере сумму yyy только когда пользователь их добавит туда. а пока, нас это не волнует и мы это в ордере не делаем. это не его ответственность. I>Где будет код этой полиси и где будут храниться параметры ?
определенно это будет контролироваться где-то на уровне добавления товаров в корзину, что бы в дальнейшем дать возможность добавить другие 2 ведра с 0й стоимостью. расчет цены товара тут совершенно не при чем.
I>>>7. суммарной цены всех товаров (набери товаров на 1000$ ) E>>стратегия? I>Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
см. выше.
I>>>8. массы заказа (закажи полную корзину и получи доставку бесплатно) E>>стратегия? I>Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
см. выше.
I>>>9. адрес доставки (доставка по району zzz бесплатна) E>>стратегия? I>Где хранятся параметры для этой стратегии и где хранится код который обсчитывает её ?
см. выше.
I>>>... — продолжать можно до бесконечности. Ты все это хочешь хранить в ордере что ли ? E>>ты сам придумал что я этого хочу. а я ведь такого не говорил. I>Я привел тебе реальный пример. Это не я придумал, а требования бизнеса.
ты сам придумал что я все это хочу хранить в ордере. если тебе так понятнее.
I>И совсем не ясно,как ты предлагаешь реализовывать эти самые скидки. Итого, у тебя места для реализации кода и хранения данных варьируются
I>Для того, что бы хотя бы разобраться с тем как работают скидки и внести изменения, придется мотаться по совершенно разным частям приложеня I>Между тем код этих скидок меняется очень часто, потому логично хранить его в одном месте, скажем DiscountService или наборе таких сервисов, а параметры подтягивать из базы.
все то же самое как и сервисами. и из базы параметры подтягиваются. и мотаться по коду так же как с кучей сервисов.
E>>мы ему об этом сообщим. а возможно он и сам знает. ведь есть полиси скидок для каждого продукта? вот продукт эти полиси, логично, может видеть. I>То есть, GetTotal у Order будет видеть все классы участников и все полиси всех классов участников ?
ну что за глупости опять? мы спросим у продукта его цену с учетом необходимых условий, и продукт нам её вернет.
а вот если нам нужно будет наложить на всю стоимость какую-то скидку, мы сделаем это другим образом.
I>>>Все стратегии будут в разных методах Выбор делается в зависимости от состава участников. E>>то же самое и тут. I>А что делать при изменении детализации, например в случае изменений той части базы про товары, доставки придется перепахивать код ордеров
при глобальных изменениях в любом случае придется что-то перепахать но в данном случае ничего перепахивать не нужно.
I>Я говорю о том, скидки могут быть применены гораздо шире, чем только с заказами. С возвратами что, придется выписывать специальную логику которая аналогично заказам ? Или наследовать возврат от заказа ?
какое отношение имеет возврат к заказу? это отдельное действие. и наверняка оно подчиняется другим правилам. мы считаем сумму заказа. зачем ты отказ прилепил сюда?
Здравствуйте, Lloyd, Вы писали:
I>>Вообще говоря идентичность уже включено в понятие messaging
L>Ошибаешься.
Ваш пост был очень глубок и убедтелен, он в корне перевернул представления всей индустрии о то, что такое ооп. Аргумент "Ошибаешься" мне показался особенно блистательным.
Пишите исчо.
Несомненно, RSDN.Lloyd туфты не напишет
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>Ты что, пишешь в форум что бы поменять чьё то мнение ? S>>Проблемы в личной жизни?
I>Тебе должно быть виднее. Обычно люди обмениваются мнениями, опытом, но вот есть люди которым дай поменять чьё то мнение
Меня поражает, как можно прийти к такому выводу из утверждения о том что мне чихать на твое мнение? И, кстати, обмен мнениями и опытом — это не про тебя. Чужие мнения и опыт интересуют тебя только как предмет для дискредитации любыми средствами, вплоть до подтасовки цитат. О чем тебе только в этом топике неоднократно уже писали.
Здравствуйте, мыщъх, Вы писали:
М>Здравствуйте, Tilir, Вы писали:
T>>Здравствуйте, licedey, Вы писали:
T>>Но не вздумайте сделать проще чем надо. М>+100500
М>по моему глубокому убеждению проблемы нужно решать по мере их возникновения. писать программы на вырост нужно лишь хорошо подумав, ...
Периодически сталкиваюсь с програмками и програмулинами, которые когда-то делались на скорую руку (за день или два) чтобы решить какую-то сиюминутную задачу. Однако потом обросли фичами.
Никто их никогда не редизайнил, не рефакторил... В общем внутри ужас.
Ужас вобщем. Добавить фичу или поправить баг стоит титанических усилий. Однако на "переписывание" никто никогда добро не даст.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Enomay, Вы писали:
E>в Order? возможно. а возможно и не туда. зависит от типа скидки.
То есть вы предлагаете размазать обязанности расчёта скидок по нескольким различным классам модели. Простите, но мне это не кажется хорошей идеей.
E>они видны, но мало ли какую информацию может в себе таить ордер? возможно, мы не хотим раскрывать некоторые детали реализации?
Ну я же вас сразу спросил — есть ли какая-то непубличная информация, нужная для расчёта стоимости. Если стоимость не зависит от деталей реализации, то ничего раскрывать и не нужно.
E>>>это кто вам сказал что "Неотъемлемой обязанностью Order является только хранить список позиций и прочую информацию о заказе"? S>>Попробуйте отъять у ордера эту обязанность. Что у вас останется? E>акцент наверное был на "только".
SRP предполагает, что обязанность ровно одна. Если мы нашли одну неотъемлемую, значит остальные — отъемлемые.
E>я имею ввиду логику.
Я практик. Видите ли, крайне сложно порвать SQL на операциях вида update orderLine set quantity = quantity + 1 при помощи операций в middle-tier. Поэтому для меня хороша та архитектура, которая хотя бы в теории позволяет построить запрос в middle tier, а потом спустить его в SQL и забыть.
E>почему он, а не ордер?
Потому что это улучшает архитектуру. Ордер выполняет меньше обязанностей (SRP), его проще написать и протестировать, код расчёта суммы проще написать и протестировать, он надёжнее, его можно повторно использовать для любых Order-like структур.
E>только в вашем воображении) E>по вашему существуют только ДТО и утилиты. вот и пользуйтесь функциональным подходом. я то тут причем?
S>>Вот например — мы только что договорились с производителем DVD-плееров, что будем давать плееры бесплатно при покупке телевизора. E>как это относится к логике расчета стоимости заказа?
Это и есть "расчёт стоимости заказа". В заказе две позиции — телевизор за 17000 и плеер за 2100. Сумма заказа — 17000, потому что плеер должен идти бесплатно. Если я купил только плеер — 2100. Два плеера — 4200.
E>столько, сколько необходимо. это же просто)
Очевидно, что необходимо ровно 0, т.к. задачу можно решить вообще без наследников класса продукт. И без класса как такового, т.к. его обязанности прекрасно выполнит struct.
E>значит в 10 переплетенных по каким-то условиям. от этого не легче.
Почему в 10 переплетённых? Почему вы не читаете то, что я вам пишу?
E>добавить скидку на обувь определенного класса?
Конкретнее можно? Какие классы у нас были в модели до того, как появилась такая скидка? Какие классы изменились? Какие классы появились?
E>за тем же, зачем вы фантазируете монолитную реализацию ордера
Я не фантазирую монолитной реализации.
E>более того, на ордер у вас рапспространяется даже то, чего там быть не должно. а ведь это всего лишь заказ.
Например чего в ордере быть не должно?
E>все это отлично кладётся в ордер, где имхо ему и место. но вы в праве думать иначе.
Что именно "всё"? Логика по расчёту скидок? А почему в Order, а не в, скажем, Customer?
Ничего отличного в этом нету. Поясняю: логика расчёта скидок сегодня одна, а завтра другая.
Это я параноидально написал тут пять классов правил, и последовательность применения. А в жизни — одна кофейня даёт 50% скидку при заказе "на вынос", а другая только накапливает бонусы на карту. Им нафиг не упёрлись все эти иерархии, рабочее место конфигуратора системы и редактор календаря действия скидок.
В системе, написанной в моём подходе, достаточно заменить реализацию IDiscountService — а всё остальное останется работать. Гарантированно.
Потому что сами заказы в обеих кофейнях устроены совершенно одинаково.
В вашем подходе логика расчёта запихана в сам класс Order. Любое изменение там — это перетестирование класса, и всех зависимых от него классов.
E>вот вот. просто я храню реализацию не там, где вы. она от этого несколько меняется, но хуже не становится.
Ну почему же "не становится". Ещё как становится. Производительность — ниже, стоимость внесения изменений — выше.
E>я не буду спорить, что применимо к интернет магазину, ООП подход как таковой, в частности ДДД, который тут неоднократно упоминали, лучше, нежели анемик. но в то же время я уверен что и рич модель будет эффективной.
Ещё раз поясню, что подход, который я описываю — это ООП. Все черты ООП в нём в полный рост. Для микромагазинов на 5 товаров действительно можно оперировать рич моделью.
Как только вы попробуете построить настоящую систему уровня хотя бы сети магазинов "аскания", ваша rich упрётся в чудовищные проблемы.
Вам просто почему-то кажется, что ООП — это значит запихать методы в данные. Даже если у моделируемых объектов в доменной области не было никакого поведения, которым вы их наделяете. А я вижу, что в решении задач "активных" сущностей, достойных быть объектами, значительно меньше, чем "пассивных" сущностей, от которых нужны только данные.
В учётных задачах ООП вообще порой страшно вредит.
E>это не изменит реализации. мы установим на товар скидку, а Order.GetTotal() в данном случаи не изменится но вернет правильную сумму. E>у нас проблема в том, что мы оперируем разными понятиями и не можем понять друг друга.
Каким образом вы "установите на товар скидку"? Может быть, вы наконец попытаетесь написать пример кода?
Вы упоминали пять классов продуктов с уникальными скидочными стратегиями. Приведите хотя бы два.
E>если это работает, и работает так, как нужно, это здорово, и нет необходимости что-то менять. E>я бы пошел по другому пути. лучше, хуже, не знаю. E>но раз появился Фаулер со своей идеологией, и её подхватили, значит есть и для них свои задачи
Это интересный вывод. Я вот вижу, что вы подхватили идеологию Фаулера, но при этом искренне пытаетесь её применять в неподходящих задачах. И таких людей, как показывает практика, большинство. Вы всё же постарайтесь критически относиться к Фаулеру, и задумываться, зачем вы принимаете то или иное решение.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Enomay, Вы писали:
E>ну что за глупости опять? мы спросим у продукта его цену с учетом необходимых условий, и продукт нам её вернет.
Код вот этого вот "спросим у продукта" — в студию. Без этого все аргументы, простите, ничего не стоят.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
I>>Тебе должно быть виднее. Обычно люди обмениваются мнениями, опытом, но вот есть люди которым дай поменять чьё то мнение
S>Меня поражает, как можно прийти к такому выводу из утверждения о том что мне чихать на твое мнение?
Я пришел к таком выводу исходя вот из твоих ассоциаций "А то что? А то ты останешься при своем мнении?"
>И, кстати, обмен мнениями и опытом — это не про тебя. Чужие мнения и опыт интересуют тебя только как предмет для дискредитации любыми средствами,
Чужие мнения меня интересуют как ещё одна точка зрения. Предмет для дискредитации это отказ от прояснения своей точки зрения. Не совсем ясно, чего ты делаешь на профильном форуме, если отказываешься прояснить свою точку зрения
>вплоть до подтасовки цитат. О чем тебе только в этом топике неоднократно уже писали.
Только не мне, а тебе. Могу с цитатами, где некто(не я), указывает на передёргивания с твоей стороны
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Enomay, Вы писали:
E>>ордеру ничего на себе завязывать не придется. абстрактный пример может выглядеть так:
E>>
I>А как быть если какая то позиция была удалена, отредактирована, добавлена, надо повторить такие действия ?
ничего сложного.
order.SetDelivery(new DeliveryStrategy());
а order.GetTotal будет содержать приблизительно следующий код
var total = Sum(this.orderLines.GetCost());
return total + this.Delivery.GetCost(total);
соответственно GetTotal всегда вернет актуальную цену.
I>Ты похоже показал, что order.GetTotal будет зависеть от стоимости доставки, а стоимост доставки будет зависеть от стоимости заказа
Ну вот и отлично. Видим, что за доставку отвечает DeliveryService. За скидки — DiscountService.
Осталось понять, зачем вписывать GetTotal внутрь класса Order, когда с точки зрения удобства поддержки гораздо проще сделать его extension-методом.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
S>>Меня поражает, как можно прийти к такому выводу из утверждения о том что мне чихать на твое мнение?
I>Я пришел к таком выводу исходя вот из твоих ассоциаций "А то что? А то ты останешься при своем мнении?"
Точно, я в пылу высказал свои самые серьезные опасения...
>>И, кстати, обмен мнениями и опытом — это не про тебя. Чужие мнения и опыт интересуют тебя только как предмет для дискредитации любыми средствами,
I>Чужие мнения меня интересуют как ещё одна точка зрения. Предмет для дискредитации это отказ от прояснения своей точки зрения. Не совсем ясно, чего ты делаешь на профильном форуме, если отказываешься прояснить свою точку зрения
Я не желаю потратить на это месяц. А в твоем случае, меньшим, похоже не обойтись.
>>вплоть до подтасовки цитат. О чем тебе только в этом топике неоднократно уже писали.
I>Только не мне, а тебе. Могу с цитатами, где некто(не я), указывает на передёргивания с твоей стороны
Это писали мне? Я как-то не подумал об этом, т.к. это были ответы на твои сообщения.
Здравствуйте, Enomay, Вы писали:
E>ничего сложного.
E>order.SetDelivery(new DeliveryStrategy());
E>а order.GetTotal будет содержать приблизительно следующий код
E>var total = Sum(this.orderLines.GetCost()); E>return total + this.Delivery.GetCost(total);
E>соответственно GetTotal всегда вернет актуальную цену.
А как со скидками быть ? Хочется в эту схему вписать и скидки, но я не понимаю, как это сделать используя твой дизайн.
I>>Ты похоже показал, что order.GetTotal будет зависеть от стоимости доставки, а стоимост доставки будет зависеть от стоимости заказа
E>оно ведь так в жизни и есть. правда?
Здравствуйте, Sinclair, Вы писали:
L>>Ошибаешься S>Вообще-то нет. Кей напрямую идентичность не упоминает, но его messaging подразумевает возможность послать сообщение конкретному объекту, вне зависимости от его состояния. Так что без identity messaging не работает.
Здравствуйте, Sinclair, Вы писали:
I>>В данном случае квази-OOP достигается не за счет языковых средств, а за счет возможностей/особенностей операционной системы. А хотелось бы примерно так как было обещано на Object Pascal. S>А какая разница, на Object Pascal или нет? Залудить CreateFile/FileRead/FileWrite/CloseHandle можно хоть на Visual Basic, хоть на виртовском паскале. S>Дело же не в языке, а в том, как устроено решение.
E>>в Order? возможно. а возможно и не туда. зависит от типа скидки. S>То есть вы предлагаете размазать обязанности расчёта скидок по нескольким различным классам модели. Простите, но мне это не кажется хорошей идеей.
очень странно, так как идея размазывания по разным классам сервисов вам кажется хорошей идеей.
E>>они видны, но мало ли какую информацию может в себе таить ордер? возможно, мы не хотим раскрывать некоторые детали реализации? S>Ну я же вас сразу спросил — есть ли какая-то непубличная информация, нужная для расчёта стоимости. Если стоимость не зависит от деталей реализации, то ничего раскрывать и не нужно.
я могу предположить, но сказать точно, не имея всех требований, увы.
E>>акцент наверное был на "только". S>SRP предполагает, что обязанность ровно одна. Если мы нашли одну неотъемлемую, значит остальные — отъемлемые.
по-вашему у ордера задача только одна — хранить данные? интересное понимание ответственности. но пусть будет так.
E>>я имею ввиду логику. S>Я практик. Видите ли, крайне сложно порвать SQL на операциях вида update orderLine set quantity = quantity + 1 при помощи операций в middle-tier. Поэтому для меня хороша та архитектура, которая хотя бы в теории позволяет построить запрос в middle tier, а потом спустить его в SQL и забыть.
это ваше дело. тут спорить смысла нет. в интернете все давно разжевано.
E>>почему он, а не ордер? S>Потому что это улучшает архитектуру. Ордер выполняет меньше обязанностей (SRP), его проще написать и протестировать, код расчёта суммы проще написать и протестировать, он надёжнее, его можно повторно использовать для любых Order-like структур.
от того, что метод находится не в ордере, а в сервисе, ни метод, ни ордер, проще не становится.
в вашем случаи все методы работают только с внешними данными, у меня с внутренними. это решит проблему "закрытости", при необходимости.
S>>>Вот например — мы только что договорились с производителем DVD-плееров, что будем давать плееры бесплатно при покупке телевизора. E>>как это относится к логике расчета стоимости заказа? S>Это и есть "расчёт стоимости заказа". В заказе две позиции — телевизор за 17000 и плеер за 2100. Сумма заказа — 17000, потому что плеер должен идти бесплатно. Если я купил только плеер — 2100. Два плеера — 4200.
ну и отлично. если купили телевизор, то плеер добавляется к ордеру с ценой 0. ордер вернет стоимость 17000. иначе цена будет другой.
E>>значит в 10 переплетенных по каким-то условиям. от этого не легче. S>Почему в 10 переплетённых? Почему вы не читаете то, что я вам пишу?
потому что вы не читаете то, что я пишу.
E>>добавить скидку на обувь определенного класса? S>Конкретнее можно? Какие классы у нас были в модели до того, как появилась такая скидка? Какие классы изменились? Какие классы появились?
в объектной модели у нас ничего не изменилось. добавили товару в базе скидку и забыли. Ордер вернет правильную сумму заказа.
E>>более того, на ордер у вас рапспространяется даже то, чего там быть не должно. а ведь это всего лишь заказ. S>Например чего в ордере быть не должно?
все то, что вы ему приписали, кроме расчета общей стоимости заказа
E>>все это отлично кладётся в ордер, где имхо ему и место. но вы в праве думать иначе. S>Что именно "всё"? Логика по расчёту скидок? А почему в Order, а не в, скажем, Customer?
наверное потому, что общая сумма заказа есть информация о самом заказе и относящаяся к нему?
S>Ничего отличного в этом нету. Поясняю: логика расчёта скидок сегодня одна, а завтра другая. S>Это я параноидально написал тут пять классов правил, и последовательность применения. А в жизни — одна кофейня даёт 50% скидку при заказе "на вынос", а другая только накапливает бонусы на карту. Им нафиг не упёрлись все эти иерархии, рабочее место конфигуратора системы и редактор календаря действия скидок.
разве я против? делайте как вам удобнее
S>В системе, написанной в моём подходе, достаточно заменить реализацию IDiscountService — а всё остальное останется работать. Гарантированно. S>Потому что сами заказы в обеих кофейнях устроены совершенно одинаково. S>В вашем подходе логика расчёта запихана в сам класс Order. Любое изменение там — это перетестирование класса, и всех зависимых от него классов.
глупости. а говорите что я не читаю ваши сообщения. а я ведь писал, что ордер кроме суммирования, фактически ничего не делает.
E>>вот вот. просто я храню реализацию не там, где вы. она от этого несколько меняется, но хуже не становится. S>Ну почему же "не становится". Ещё как становится. Производительность — ниже, стоимость внесения изменений — выше.
очень спорное и беспредметное утверждение.
E>>я не буду спорить, что применимо к интернет магазину, ООП подход как таковой, в частности ДДД, который тут неоднократно упоминали, лучше, нежели анемик. но в то же время я уверен что и рич модель будет эффективной. S>Ещё раз поясню, что подход, который я описываю — это ООП. Все черты ООП в нём в полный рост. Для микромагазинов на 5 товаров действительно можно оперировать рич моделью.
в ООП так же входит то, что объект оперирует внутренним состоянием. у вас состояние и действия разнесены в разные места.
S>Как только вы попробуете построить настоящую систему уровня хотя бы сети магазинов "аскания", ваша rich упрётся в чудовищные проблемы.
я думаю это проблема не в рич подходе.
S>Вам просто почему-то кажется, что ООП — это значит запихать методы в данные. Даже если у моделируемых объектов в доменной области не было никакого поведения, которым вы их наделяете. А я вижу, что в решении задач "активных" сущностей, достойных быть объектами, значительно меньше, чем "пассивных" сущностей, от которых нужны только данные. S>В учётных задачах ООП вообще порой страшно вредит.
мне кажется что для каждой задачи существует своё решение. а выбирать нужно из того, что лучше умеешь. я не сталкивался с конкретно вашими проблемами, но сталкивался с проблемами которые возникают от подобного подхода к реализации.
особенно — логика в базе. но это все лирика.
E>>это не изменит реализации. мы установим на товар скидку, а Order.GetTotal() в данном случаи не изменится но вернет правильную сумму. E>>у нас проблема в том, что мы оперируем разными понятиями и не можем понять друг друга. S>Каким образом вы "установите на товар скидку"? Может быть, вы наконец попытаетесь написать пример кода?
в базе установлю. так же как и вы.
E>>если это работает, и работает так, как нужно, это здорово, и нет необходимости что-то менять. E>>я бы пошел по другому пути. лучше, хуже, не знаю. E>>но раз появился Фаулер со своей идеологией, и её подхватили, значит есть и для них свои задачи S>Это интересный вывод. Я вот вижу, что вы подхватили идеологию Фаулера, но при этом искренне пытаетесь её применять в неподходящих задачах. И таких людей, как показывает практика, большинство. Вы всё же постарайтесь критически относиться к Фаулеру, и задумываться, зачем вы принимаете то или иное решение.
я не вижу ничего плохого в решении задач вашим способом. если он вам ближе, то не стоит заморачиваться.
на сегодняшний день я не вижу ничего плохого в рич модели. она хорошо справляется с моими задачами. а это увы, не интернет магазины.
и в моем случае код получается достаточно логичный и структурированный.
это касается реализации БЛ. где нужно будет анемик модель, будет анемик (в основном отображение данных).
E>>ну что за глупости опять? мы спросим у продукта его цену с учетом необходимых условий, и продукт нам её вернет. S>Код вот этого вот "спросим у продукта" — в студию. Без этого все аргументы, простите, ничего не стоят.
product.GetPrice() ?
при необходимости в этот метод можно передать еще что-то. например кол-во этих продуктов в заказе. от этого изменится возвращемое значение.
S>Ну вот и отлично. Видим, что за доставку отвечает DeliveryService. За скидки — DiscountService. S>Осталось понять, зачем вписывать GetTotal внутрь класса Order, когда с точки зрения удобства поддержки гораздо проще сделать его extension-методом.
вам проще? удобнее? делайте
а я его засуну в Ордер, что бы не плодить лишний класс с единственным методом.
и с точки зрения удобства я не вижу недостатков.
E>>var total = Sum(this.orderLines.GetCost()); E>>return total + this.Delivery.GetCost(total);
E>>соответственно GetTotal всегда вернет актуальную цену. I>А как со скидками быть ? Хочется в эту схему вписать и скидки, но я не понимаю, как это сделать используя твой дизайн.
зависит от типа скидки. если она на конкретный товар, то изменим его полиси скидки в базе на этот товар. если вообще, от внешних значений, применим стратегию к total в этом методе.
I>>>Ты похоже показал, что order.GetTotal будет зависеть от стоимости доставки, а стоимост доставки будет зависеть от стоимости заказа E>>оно ведь так в жизни и есть. правда? I>Я говорил про депенденсы, а не про результат.
модель отражает жизненную ситуацию. это правильно.
Здравствуйте, samius, Вы писали:
I>>Чужие мнения меня интересуют как ещё одна точка зрения. Предмет для дискредитации это отказ от прояснения своей точки зрения. Не совсем ясно, чего ты делаешь на профильном форуме, если отказываешься прояснить свою точку зрения S>Я не желаю потратить на это месяц. А в твоем случае, меньшим, похоже не обойтись.
Можешь не тратить месяц — Синклер сделал то о чем я тебя просил всего за одно сообщение. Тренируйся.
Здравствуйте, Enomay, Вы писали:
E>зависит от типа скидки. если она на конкретный товар, то изменим его полиси скидки в базе на этот товар. если вообще, от внешних значений, применим стратегию к total в этом методе.
А если GetTotal считать во внешнем, по отношению к Order, сервисе, то у нас только одно место безо всяких если, при чем эта часть какправило меняется очень часто и не надо будет приседать в будущем.
I>>>>Ты похоже показал, что order.GetTotal будет зависеть от стоимости доставки, а стоимост доставки будет зависеть от стоимости заказа E>>>оно ведь так в жизни и есть. правда? I>>Я говорил про депенденсы, а не про результат.
E>модель отражает жизненную ситуацию. это правильно.
Качественная модель отражать способ которым резолвится циклическая зависимость, а не само наличие этой зависимости.
E>>зависит от типа скидки. если она на конкретный товар, то изменим его полиси скидки в базе на этот товар. если вообще, от внешних значений, применим стратегию к total в этом методе. I>А если GetTotal считать во внешнем, по отношению к Order, сервисе, то у нас только одно место безо всяких если, при чем эта часть какправило меняется очень часто и не надо будет приседать в будущем.
совершенно не обязательно. иногда может оказать наоборот.
проще говоря, где бы GetTotal не находился, сложность его модификации от этого слабо меняется.
Здравствуйте, Enomay, Вы писали:
E>совершенно не обязательно. иногда может оказать наоборот. E>проще говоря, где бы GetTotal не находился, сложность его модификации от этого слабо меняется.
Наоборот В большинстве случаев его вообще не нужно будет модифицировать, а если поместить код в Ордер, придется обкладывать все случаи if/else
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Sinclair, Вы писали:
L>>>Ошибаешься S>>Вообще-то нет. Кей напрямую идентичность не упоминает, но его messaging подразумевает возможность послать сообщение конкретному объекту, вне зависимости от его состояния. Так что без identity messaging не работает.
L>т.е. SOA — это ООП? Или SOA — это не messaging?
Как в SOA же нет состояния.
Нет состояния — нет ООП.
Нет ножек — нет мультиков.
Здравствуйте, Lloyd, Вы писали:
S>>>>Вообще-то нет. Кей напрямую идентичность не упоминает, но его messaging подразумевает возможность послать сообщение конкретному объекту, вне зависимости от его состояния. Так что без identity messaging не работает.
F>>Как в SOA же нет состояния. F>>Нет состояния — нет ООП.
L>О том и речь, что утверждение "идентичность уже включено в понятие messaging", мягко говоря, сомнительно.
Здравствуйте, Flem1234, Вы писали:
L>>О том и речь, что утверждение "идентичность уже включено в понятие messaging", мягко говоря, сомнительно.
F>А как возможно отослать сообщение без адресата?
Здравствуйте, Ikemefula, Вы писали:
L>>Вызов процедуры, например.
I>Где же здесь messaging т.е. взаимодействие объектов через посылку-приём сообщений ?
Посылка сообщения — это абстракция любого вызова, не только вызова методов объектов. Для примера, можешь поинтересоваться SOA и очередями сообщений.
Здравствуйте, Enomay, Вы писали:
E>очень странно, так как идея размазывания по разным классам сервисов вам кажется хорошей идеей.
Ничего подобного. Вся необходимая логика компактно расположена внутри DiscountService и связанных с ним классов.
Если вы нарисуете диаграмму зависимости.
E>по-вашему у ордера задача только одна — хранить данные? интересное понимание ответственности. но пусть будет так.
Я вас тогда так спрошу: вы слово Single в аббревиатуре SRP как понимаете?
E>от того, что метод находится не в ордере, а в сервисе, ни метод, ни ордер, проще не становится.
Конечно же становится. Банальная математика. Уменьшая площадь поверхности класса Order, мы гарантированно упрощаем его разработку и тестирование.
E>в вашем случаи все методы работают только с внешними данными, у меня с внутренними. это решит проблему "закрытости", при необходимости.
Нет. В моём методе все методы, которые могут работать с внешними данными, остаются снаружи. Их не нужно перетестировать всякий раз, как мы меняем внутреннюю подробность реализации Order — достаточно протестировать внешний контракт Order.
S>>>>Вот например — мы только что договорились с производителем DVD-плееров, что будем давать плееры бесплатно при покупке телевизора. E>>>как это относится к логике расчета стоимости заказа? S>>Это и есть "расчёт стоимости заказа". В заказе две позиции — телевизор за 17000 и плеер за 2100. Сумма заказа — 17000, потому что плеер должен идти бесплатно. Если я купил только плеер — 2100. Два плеера — 4200.
E>ну и отлично. если купили телевизор, то плеер добавляется к ордеру с ценой 0. ордер вернет стоимость 17000. иначе цена будет другой.
Подождите, что значит "с ценой 0"? Вы мне только что рассказывали, что цену OrderLine берёт из Product.
Product у нас в двух заказах один и тот же.
Вопрос повышенной сложности: а что, если мы добавили в ордер сначала плеер, а потом телевизор? E>потому что вы не читаете то, что я пишу.
Я очень внимательно читаю то, как вы уклоняетесь от моих вопросов.
E>в объектной модели у нас ничего не изменилось. добавили товару в базе скидку и забыли. Ордер вернет правильную сумму заказа.
Код в студию можно?
E>все то, что вы ему приписали, кроме расчета общей стоимости заказа
Конкретнее.
E>>>все это отлично кладётся в ордер, где имхо ему и место. но вы в праве думать иначе. S>>Что именно "всё"? Логика по расчёту скидок? А почему в Order, а не в, скажем, Customer? E>наверное потому, что общая сумма заказа есть информация о самом заказе и относящаяся к нему? Хорошая попытка. Ок, предположим, что обязанность рассчитывать стоимость с учётом скидок вменена ордеру (пусть и в нарушение SRP).
Давайте посмотрим, куда это нас приведёт.
E>разве я против? делайте как вам удобнее
S>>В системе, написанной в моём подходе, достаточно заменить реализацию IDiscountService — а всё остальное останется работать. Гарантированно. S>>Потому что сами заказы в обеих кофейнях устроены совершенно одинаково. S>>В вашем подходе логика расчёта запихана в сам класс Order. Любое изменение там — это перетестирование класса, и всех зависимых от него классов.
E>глупости. а говорите что я не читаю ваши сообщения. а я ведь писал, что ордер кроме суммирования, фактически ничего не делает.
Подождите, ведь только что в ордере фигурировали скидки.
Давайте вы всё же приведёте пример кода, а то вы в одном месте пишете одно, и тут же рядом пишете нечто другое.
E>>>вот вот. просто я храню реализацию не там, где вы. она от этого несколько меняется, но хуже не становится. S>>Ну почему же "не становится". Ещё как становится. Производительность — ниже, стоимость внесения изменений — выше.
E>очень спорное и беспредметное утверждение.
Ну давайте оспорьте его.
S>>Ещё раз поясню, что подход, который я описываю — это ООП. Все черты ООП в нём в полный рост. Для микромагазинов на 5 товаров действительно можно оперировать рич моделью. E>в ООП так же входит то, что объект оперирует внутренним состоянием. у вас состояние и действия разнесены в разные места.
Нет, в ООП это не входит. Вас обманули. ООП вовсе не запрещает объекту общаться с окружающим миром.
E>я думаю это проблема не в рич подходе.
А в чём же?
E>мне кажется что для каждой задачи существует своё решение. а выбирать нужно из того, что лучше умеешь. я не сталкивался с конкретно вашими проблемами, но сталкивался с проблемами которые возникают от подобного подхода к реализации.
Ну расскажите про проблемы. Я вам набросал скетч решения для задачи "рассчитать сумму заказа с учётом скидок". E>особенно — логика в базе. но это все лирика.
Я пока ничего не говорил про логику в базе. Я вам даже привёл пример кода на C#.
E>в базе установлю. так же как и вы.
В какой базе? Ну напишите же уже пример кода. Вы так этому сопротивляетесь, что я начинаю думать, что вы просто не понимаете, как реально будет выглядеть ваш код.
E>я не вижу ничего плохого в решении задач вашим способом. если он вам ближе, то не стоит заморачиваться. E>на сегодняшний день я не вижу ничего плохого в рич модели. она хорошо справляется с моими задачами. а это увы, не интернет магазины. E>и в моем случае код получается достаточно логичный и структурированный. E>это касается реализации БЛ. где нужно будет анемик модель, будет анемик (в основном отображение данных).
Это очень хорошо. Осталось только отбросить заблуждения вроде того, что анемик != ООП. или что анемик = функциональный подход.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Enomay, Вы писали:
E>product.GetPrice() ?
E>при необходимости в этот метод можно передать еще что-то. например кол-во этих продуктов в заказе. от этого изменится возвращемое значение.
Экий вы ловкий. Ок, вот вы реализовали product.GetPrice. Теперь вас попросили внести в вашу систему скидку "купив два, третий — бесплатно". Естественно, для некоторых товаров.
И есть намёк на то, что завтра потребуются другие скидки, но пока точно непонятно какие (сделаем вид, что мы с Ikemefula не рассказали вам только что про десять других видов скидок).
Расскажите мне, как вы поменяете интерфейс класса Product, и как будет устроен его GetPrice().
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
L>С фига-ли?
Как с фига? Идентичность есть, поведение есть, состояние есть. Чего ещё? L>Может еще и очереди сообщений в ОО запишешь?
Нет, зачем? L>Да ладно уж, чего там мелочиться, давай и свободные процедуры/функции туда же до кучи.
Нет идентичности и возможности иметь поведение с предысторией (т.е. состояние).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
L>>С фига-ли? S>Как с фига? Идентичность есть, поведение есть, состояние есть. Чего ещё?
Идентичность чего с чем?
L>>Может еще и очереди сообщений в ОО запишешь? S>Нет, зачем?
Почему нет? В чем собственно отличие сервиса от очереди сообщений, если не принимать во внимание асинхронности,
L>>Да ладно уж, чего там мелочиться, давай и свободные процедуры/функции туда же до кучи. S>Нет идентичности и возможности иметь поведение с предысторией (т.е. состояние).
Здравствуйте, Flem1234, Вы писали:
F>Здравствуйте, Lloyd, Вы писали:
L>>Здравствуйте, Sinclair, Вы писали:
L>>>>Ошибаешься S>>>Вообще-то нет. Кей напрямую идентичность не упоминает, но его messaging подразумевает возможность послать сообщение конкретному объекту, вне зависимости от его состояния. Так что без identity messaging не работает.
L>>т.е. SOA — это ООП? Или SOA — это не messaging?
F>Как в SOA же нет состояния.
Это неверно.
F>Нет состояния — нет ООП.
Это тоже неверно.
F>Нет ножек — нет мультиков.
???
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали: L>>Идентичность чего с чем? S>Более точным переводом identity является "идентифицируемость", но обычно переводят "идентичность". S>У вас есть какие-то сомнения в том, что в SOA каждое обращение идёт к какому-то конкретному сервису?
Снаружи нет возможности идентифицировать конкретный сервис, вернее экземпляр сервиса. Это и есть отсутствие идентичности.
Снаружи мы можем говорить только об эквивалентности. И с точки зрения SOA все сервисы с одинаковым контрактом эквивалентны.
Здравствуйте, Lloyd, Вы писали:
L>Посылка сообщения — это абстракция любого вызова, не только вызова методов объектов. Для примера, можешь поинтересоваться SOA и очередями сообщений.
В вики в статьях про MQ и message фигурируют отправитель и получатель
Например:
Message passing is a form of communication used in concurrent and parallel computing, object-oriented programming, and interprocess communication, where communication is made by sending messages to recipients. In a related use of this sense of a message, in object-oriented programming languages such as Smalltalk or Java, a message is sent to an object, specifying a request for action.
или
Message queues provide an asynchronous communications protocol, meaning that the sender and receiver of the message do not need to interact with the message queue at the same time. Messages placed onto the queue are stored until the recipient retrieves them.
Но даже если есть случаи, когда у сообщения нет получателя, то Алан Кей как раз имел в виду, что получатель есть.
Не могу понять, что ты хочешь доказать? Что ООП это не "идентифицируемые объекты общающиеся через сообщения друг к другу, и реагирующие на сообщения по разному в зависимости от внутреннего состояния"?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>Чужие мнения меня интересуют как ещё одна точка зрения. Предмет для дискредитации это отказ от прояснения своей точки зрения. Не совсем ясно, чего ты делаешь на профильном форуме, если отказываешься прояснить свою точку зрения S>>Я не желаю потратить на это месяц. А в твоем случае, меньшим, похоже не обойтись.
I>Можешь не тратить месяц — Синклер сделал то о чем я тебя просил всего за одно сообщение.
Вот и славно, спасибо Синклеру.
Так это была просьба? Я принял ее за предварительный диагноз.
I>Тренируйся.
Только меня не покидает ощущение того, что если бы ты о примере услышал от меня, то повел бы себя иначе.
Здравствуйте, Flem1234, Вы писали:
F>В вики в статьях про MQ и message фигурируют отправитель и получатель F>Например: F>
F>Message passing is a form of communication used in concurrent and parallel computing, object-oriented programming, and interprocess communication, where communication is made by sending messages to recipients. In a related use of this sense of a message, in object-oriented programming languages such as Smalltalk or Java, a message is sent to an object, specifying a request for action.
Ну продемонстрируйте, как из этого определения следует идентичность получателя.
Например, посылаю я широковещательный сетевой пакет, ну и кому я его посылаю? Или пишу сообщение в MQ, из кторой сосут десяток читателей, кто освоборится, тот и подхватить очередную порцию, кому тогда слался message, какова identity получателя?
F>Но даже если есть случаи, когда у сообщения нет получателя, то Алан Кей как раз имел в виду, что получатель есть. F>Не могу понять, что ты хочешь доказать?
А вы поднимитесь по ветке на пяток сообщений, там все есть.
F>Что ООП это не "идентифицируемые объекты общающиеся через сообщения друг к другу, и реагирующие на сообщения по разному в зависимости от внутреннего состояния"?
На основе чего вы сделали вывод, что я хочу доказать именно это?
F>
Ты под Павла со своими смайликами косишь что-ли? Право, не самый лучший образец для подражания.
Здравствуйте, Sinclair, Вы писали:
L>>В ветке, где обсуждается процедурность vs объектная-ориентированность более логично подчеркивать тот аспект которые отличает эти две парадигмы, а не тот, что их сближает. L>>В этом отношении определение ООП из википедии вполне корректно, а цитаты Алана Кея — совсем неуместны. S>В ветке происходит странная борьба между неправильным пониманием ООП и неправильным пониманием процедурного подхода.
S>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься. S>Постулат номер 1: ООП — оно не про моделирование задачи. Оно про моделирование решения.
S>Постулат номер 2: ООП не про данные, ООП про поведение.
Это какой-то новый совершенно выбивающий из колеи прием — я отвечаю на ваш пост, а вы в ответ приводите набор банальностей, на который и возразить вроде нечего.
Видимо если я вас спрошу, где связь, вы мне посоветуете опять перейти к чтению классиков?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Enomay, Вы писали:
E>>product.GetPrice() ?
E>>при необходимости в этот метод можно передать еще что-то. например кол-во этих продуктов в заказе. от этого изменится возвращемое значение. S>Экий вы ловкий. Ок, вот вы реализовали product.GetPrice. Теперь вас попросили внести в вашу систему скидку "купив два, третий — бесплатно". Естественно, для некоторых товаров. S>И есть намёк на то, что завтра потребуются другие скидки, но пока точно непонятно какие (сделаем вид, что мы с Ikemefula не рассказали вам только что про десять других видов скидок). S>Расскажите мне, как вы поменяете интерфейс класса Product, и как будет устроен его GetPrice().
как-то так.
это, конечно, тупая реализация, с опущенными вариантами получения разных типов скидок.
а скидки по конкретному продукту могут описываться хоть в XML.
само собой добавление товаров свыше 2х, которые бессплатные, не является обязанностью класса Order.
ведь это как в жизни. купил 2, но от 3го бессплатного отказался. не отказался? ок. расчет стоимости корзины все равно останется верным, в данном случае.
вся проблема в том, что мы смотрим на вещи по разному. в моем случае Order это грубо говоря корзина с продуктами, если быть точнее — чек.
а по этому мой класс Order работает как чек. и лишние товары со скидками, или бесплатные, он сам не добавляет. он считает то, что есть. а вот кто это добавит, не его проблема.
это и есть, на мой взгляд, SRP. каждый занимается тем, что лучше умеет.
кстати говоря, "купи 3 бутылки пива и 4ю бессплатно" можно рассматривать как 1 еденица товара. обычно они именно в таком виде и продаются. так что делать хитрые условия по скидке 4го товара, после предыдущих 3х, обычно нет необходимости.
ну а для уникальных случаев, конечно же, есть соответствующие решения.
E>>очень странно, так как идея размазывания по разным классам сервисов вам кажется хорошей идеей. S>Ничего подобного. Вся необходимая логика компактно расположена внутри DiscountService и связанных с ним классов. S>Если вы нарисуете диаграмму зависимости.
это отличается лишь местоположением, от моего подхода. и еще тем, что я работаю с теми данными, которые имею, а вы работаете с внешними.
E>>по-вашему у ордера задача только одна — хранить данные? интересное понимание ответственности. но пусть будет так. S>Я вас тогда так спрошу: вы слово Single в аббревиатуре SRP как понимаете?
я понимаю к чему вы клоните. но хранение данных для любого объекта, мне так всегда казалось, не является ответстветнностью. мой класс Order считает сумму позиций в, грубо говоря, ценнике. но ни в коем случае не печатает на принтере. учет скидок так же входит в расчет стоимости.
я считаю, что класс придерживается SRP.
если у вас другое мнение, вы в праве делать иначе
E>>от того, что метод находится не в ордере, а в сервисе, ни метод, ни ордер, проще не становится. S>Конечно же становится. Банальная математика. Уменьшая площадь поверхности класса Order, мы гарантированно упрощаем его разработку и тестирование.
но увеличиваем сложность и площадь сервиса. закон сохранения энергии, да. если что-то где-то пропало, то что-то появится в другом месте )
у меня логика лежит ближе к данным, на которые она распространяется. у вас наоборот, как я писал, данные отдельно, логика отдельно.
я не против такого решения, и там, где оно уместно, применяю. но если можно вырисовать красивую и функциональную рич модель, я это сделаю.
ну и про тестирование совершенно не аргумент. и тут и там метод. тестируются одинаково. как минимум. более того, у меня еще и разделено все на запчасти, каждая из частей может быть протестирована отдельно от общей инфраструктуры. сервисы обычно все же жощще завязаны.
E>>в вашем случаи все методы работают только с внешними данными, у меня с внутренними. это решит проблему "закрытости", при необходимости. S>Нет. В моём методе все методы, которые могут работать с внешними данными, остаются снаружи. Их не нужно перетестировать всякий раз, как мы меняем внутреннюю подробность реализации Order — достаточно протестировать внешний контракт Order.
масло масленое какое-то. методы которые работают с данными остаются снаружи, а что же тогда считает сумму заказа, если все данные с другой стороны.
E>>ну и отлично. если купили телевизор, то плеер добавляется к ордеру с ценой 0. ордер вернет стоимость 17000. иначе цена будет другой. S>Подождите, что значит "с ценой 0"? Вы мне только что рассказывали, что цену OrderLine берёт из Product.
а это уже зависит от того, как вы реализуете.
а если плеер добавили до телевизора, какая будет цена и как она будет считаться?
S>Product у нас в двух заказах один и тот же.
не всегда это так. это скорее некая копия продукта. ведь мы хотим хранить историю заказов? если будем хранить ссылку на оригинал, то при изменении его цены, у нас изменятся все заказы. а этого быть не должно.
S>Вопрос повышенной сложности: а что, если мы добавили в ордер сначала плеер, а потом телевизор?
да, это правда очень хороший вопрос. и я с ходу не готов дать на него ответ.
могу предположить, что при возрастающей сложности системы расчета заказа, всё это будет обрастать неимоверным кол-вом вспомогательных сервисов.
подозреваю что в некоторых случая, как этот, будет использоваться что-то вроде "итератор + посетитель", для некоторых правок.
опять же, это лишь вариант.
и он очень близко к вашему решению на основе сервисов.
E>>потому что вы не читаете то, что я пишу. S>Я очень внимательно читаю то, как вы уклоняетесь от моих вопросов.
некоторые вопросы на столько абстрактны и каверзны, что несколько отдаляются от действительности, а посему, и ответ на них найти не просто, а часто, и бессмысленно. мы рисуем схему к совершенно абстрактному магазину, требования к которому меняются ежесекундно. у вас есть готовое решение, я за вас рад.
E>>в объектной модели у нас ничего не изменилось. добавили товару в базе скидку и забыли. Ордер вернет правильную сумму заказа. S>Код в студию можно?
ну вот, еще один человек требует код.
но кода не будет. приведи я его вам, вы скажете "ага! а вот эта фишка в нем работать не будет", и будете совершенно правы, так как я не учел её, но лишь потому, что вы заранее её не упомянули.
именно по этой причине сие бессмысленно.
но, как я уже было предлогал, мы можем поставить задачу и представить 2 разных решения, а дальше вести обсуждении на основе их.
E>>все то, что вы ему приписали, кроме расчета общей стоимости заказа S>Конкретнее.
если вы вернетесь на пару постов назад, увидите, какие-то остатки, возвраты и прочую ерунду.
E>>глупости. а говорите что я не читаю ваши сообщения. а я ведь писал, что ордер кроме суммирования, фактически ничего не делает. S>Подождите, ведь только что в ордере фигурировали скидки.
а скидки не участвуют в подсчете суммы товаров заказа?
S>Давайте вы всё же приведёте пример кода, а то вы в одном месте пишете одно, и тут же рядом пишете нечто другое.
я где-то приводил небольшой абстрактный пример. возможно другому оппоненту.
пока не будет четкой задачи — не будет четкой реализации. вы то это должны понимать.
E>>очень спорное и беспредметное утверждение. S>Ну давайте оспорьте его.
не стану. потому что мне, на самом деле, это совершенно безразлично. пока такая проблема не стала, я не стану искать её решение. да и проблемы я не вижу.
E>>в ООП так же входит то, что объект оперирует внутренним состоянием. у вас состояние и действия разнесены в разные места. S>Нет, в ООП это не входит. Вас обманули. ООП вовсе не запрещает объекту общаться с окружающим миром.
конечно он может общаться с окружающим миром. разве я это запрещал? или говорил что кто-то другой запрещает?
но основная логика класса сконцентрирована на внутренних объектах.
возьмите объект Window в .NET. он ведь отрисовывает только свои контролы, а не чужие, правда?
E>>я думаю это проблема не в рич подходе. S>А в чём же?
в восприятии окружающего мира? )
E>>мне кажется что для каждой задачи существует своё решение. а выбирать нужно из того, что лучше умеешь. я не сталкивался с конкретно вашими проблемами, но сталкивался с проблемами которые возникают от подобного подхода к реализации. S>Ну расскажите про проблемы. Я вам набросал скетч решения для задачи "рассчитать сумму заказа с учётом скидок".
там другая задача, это далеко не интернет магазин, это тонны разнородных данных, которые нужно было агреггировать) но к делу это мало относится.
E>>я не вижу ничего плохого в решении задач вашим способом. если он вам ближе, то не стоит заморачиваться. E>>на сегодняшний день я не вижу ничего плохого в рич модели. она хорошо справляется с моими задачами. а это увы, не интернет магазины. E>>и в моем случае код получается достаточно логичный и структурированный. E>>это касается реализации БЛ. где нужно будет анемик модель, будет анемик (в основном отображение данных). S>Это очень хорошо. Осталось только отбросить заблуждения вроде того, что анемик != ООП. или что анемик = функциональный подход.
хотите отбросить — отбрасывайте. тот подход к реализации, что пропагандирует большинство, при работе с анемик моделью, лично я не считаю true OOP. но это ведь мое мнение, и я его никому не собираюсь навязывать.
я стараюсь использовать другой подход, по возможности, там где это уместно, либо третий, если не работают предыдущие два.
но зачем меня в чем-то убеждать, ума не приложу.
это больше похоже на то, что вы сами не уверенны, но если удастся убедить меня, то вы одержите победу над собой, и ваши сомнения развеятся. но увы, я останусь при своём
Здравствуйте, gandjustas, Вы писали: G>Снаружи нет возможности идентифицировать конкретный сервис, вернее экземпляр сервиса. Это и есть отсутствие идентичности. G>Снаружи мы можем говорить только об эквивалентности. И с точки зрения SOA все сервисы с одинаковым контрактом эквивалентны.
Ок, может быть. Я не столь силён в SOA. Неужели там все сервисы предполагаются stateless?
Я как-то плохо себе представляю вот эту "эквивалентность". Вот есть у меня, допустим, контракт на OrderTracking.
Он типа весь стандартный. И что, мне должно быть пофигу, вызывать его для Fedex, UPS, или DHL?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
L>У меня есть сомнение, что можно говорить об идентичности в случае когда речь идет об одном экземпляре.
Судя по википедии, предполагается некая стандартизация сервисов. Т.е. один и тот же контракт исполняют многие сервисы. L>А какое это имеет значение?
Да, верно.
L>Нет, не помню, как впрочем и вы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
E>как-то так. E>это, конечно, тупая реализация, с опущенными вариантами получения разных типов скидок.
Прекрасно, что вы это понимаете.
Плохо, что вы на полном серьёзе предлагаете такую реализацию:
1. У вас появились в задаче скидки. Вы моментально меняете контракт класса Product.
2. Предлагаемые вами изменения никак не помогут вам описать следующую скидку, которую попросят. Вам снова придётся менять контракт — а, значит, переделывать и перетестировать все зависимые классы.
Вам самому не очевидно, что в приличной архитектуре такие задачи должны решаться в худшем случае дописыванием нового класса, а в нормальном случае — конфигурацией определённых объектов?
До ошибки в реализации докапываться не буду — будем считать, что вы не поняли, что означает скидка "купившему два третий бесплатно".
E>а скидки по конкретному продукту могут описываться хоть в XML.
Описываться-то они, конечно, могут. Вот только интересно было бы посмотреть на код, который пользуется этим описанием.
E>само собой добавление товаров свыше 2х, которые бессплатные, не является обязанностью класса Order. E>ведь это как в жизни. купил 2, но от 3го бессплатного отказался. не отказался? ок. расчет стоимости корзины все равно останется верным, в данном случае.
Конечно, про это никто и не говорит. Речь идёт исключительно о расчёте цены ордера. Заставить покупать третий экземпляр мы не можем.
E>вся проблема в том, что мы смотрим на вещи по разному. в моем случае Order это грубо говоря корзина с продуктами, если быть точнее — чек. E>а по этому мой класс Order работает как чек. и лишние товары со скидками, или бесплатные, он сам не добавляет. он считает то, что есть. а вот кто это добавит, не его проблема.
Ваш класс Order пока ещё ничего не считает. Пока что вы вшили в систему ровно один вид скидок, и тот работает неправильно.
Давайте всё же добавим в систему ещё одно реалистичное требование. Давайте сделаем так, чтобы на большинство товаров распространялась накопительная скидка, привязанная к покупателю (скажем, 10%), но для некоторых особо популярных товаров этой скидки не было.
Как это отразится в вашей красивой архитектуре?
E>это и есть, на мой взгляд, SRP. каждый занимается тем, что лучше умеет.
У вас товар занимается определением скидок. Он это умеет плохо.
E>кстати говоря, "купи 3 бутылки пива и 4ю бессплатно" можно рассматривать как 1 еденица товара. обычно они именно в таком виде и продаются. так что делать хитрые условия по скидке 4го товара, после предыдущих 3х, обычно нет необходимости.
Неплохое решение. Требует, правда, от оператора определённой работы (типа как правильно пробить 10 бутылок пива?), но жизнеспособно.
К сожалению, для остальных десятков видов скидок оно не помогает.
E>ну а для уникальных случаев, конечно же, есть соответствующие решения.
Да, я привёл соответствующее решение в этом топике. Вам оно чем-то не нравится.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
E>>как-то так. E>>это, конечно, тупая реализация, с опущенными вариантами получения разных типов скидок. S>Прекрасно, что вы это понимаете. S>Плохо, что вы на полном серьёзе предлагаете такую реализацию: S>1. У вас появились в задаче скидки. Вы моментально меняете контракт класса Product. S>2. Предлагаемые вами изменения никак не помогут вам описать следующую скидку, которую попросят. Вам снова придётся менять контракт — а, значит, переделывать и перетестировать все зависимые классы. S>Вам самому не очевидно, что в приличной архитектуре такие задачи должны решаться в худшем случае дописыванием нового класса, а в нормальном случае — конфигурацией определённых объектов? S>До ошибки в реализации докапываться не буду — будем считать, что вы не поняли, что означает скидка "купившему два третий бесплатно".
вся проблема в том, что вы видите только то, что написано, но не видите дальше.
какие были требования, такая была и реализация. но вы почему-то пытаетесь докопаться до нее и подставить под всевозможные условия, которые тут даже не реализовывались.
E>>вся проблема в том, что мы смотрим на вещи по разному. в моем случае Order это грубо говоря корзина с продуктами, если быть точнее — чек. E>>а по этому мой класс Order работает как чек. и лишние товары со скидками, или бесплатные, он сам не добавляет. он считает то, что есть. а вот кто это добавит, не его проблема. S>Ваш класс Order пока ещё ничего не считает. Пока что вы вшили в систему ровно один вид скидок, и тот работает неправильно.
опять же, про 2 + 1 бесплатно я писал. этот вариант рассматривается в том же виде, в котором продаётся, и как правило, это 3 вместе скрученых бутылки. вместе 1й строкой мы их и считаем. как и продукт, а не как 3. что вполне разумно.
но да, та реализация не правильная.
S>Давайте всё же добавим в систему ещё одно реалистичное требование. Давайте сделаем так, чтобы на большинство товаров распространялась накопительная скидка, привязанная к покупателю (скажем, 10%), но для некоторых особо популярных товаров этой скидки не было. S>Как это отразится в вашей красивой архитектуре?
товар вернет цену с учетом накопительной скидки?
E>>это и есть, на мой взгляд, SRP. каждый занимается тем, что лучше умеет. S>У вас товар занимается определением скидок. Он это умеет плохо.
товар занимается определением собственной цены, с учетом вероятной скидки. для этого у него есть всё необходимое.
E>>кстати говоря, "купи 3 бутылки пива и 4ю бессплатно" можно рассматривать как 1 еденица товара. обычно они именно в таком виде и продаются. так что делать хитрые условия по скидке 4го товара, после предыдущих 3х, обычно нет необходимости. S>Неплохое решение. Требует, правда, от оператора определённой работы (типа как правильно пробить 10 бутылок пива?), но жизнеспособно. S>К сожалению, для остальных десятков видов скидок оно не помогает.
это может быть реализовано как связка товаров, так и другим образом.
а вы все время почему-то пытаетесь использовать одну и ту же реализацию для разных случаев скидок. и это плохо получается. что не удивительно.
E>>ну а для уникальных случаев, конечно же, есть соответствующие решения. S>Да, я привёл соответствующее решение в этом топике. Вам оно чем-то не нравится.
какое имеет значение, нравится оно мне или нет? я ведь не пытаюсь тут кому-то доказать или навязать какое-то решение, в отличии от вас.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, gandjustas, Вы писали: G>>Снаружи нет возможности идентифицировать конкретный сервис, вернее экземпляр сервиса. Это и есть отсутствие идентичности. G>>Снаружи мы можем говорить только об эквивалентности. И с точки зрения SOA все сервисы с одинаковым контрактом эквивалентны. S>Ок, может быть. Я не столь силён в SOA. Неужели там все сервисы предполагаются stateless? S>Я как-то плохо себе представляю вот эту "эквивалентность". Вот есть у меня, допустим, контракт на OrderTracking. S>Он типа весь стандартный. И что, мне должно быть пофигу, вызывать его для Fedex, UPS, или DHL?
Судя по тому что UDDI не пошел в массы скорее всего так и предполагалось. Но не получилось.
Здравствуйте, gandjustas, Вы писали:
G>Адрес не есть Identity. За одним адресом может быть много identity, как в одной квартире могут проживать много человек.
Хороший поинт. Это означает, что граница водораздела проходит по наличию состояния адресата, на которое мы полагаемся. "Принесите деньги в полночь в то место, что я указал в предыдущем письме" — упс, здесь полагаемся на то, что за одним адресом не кроется неопределённое количество identities. Мы полагаемся на то, что получатель письма — ровно тот же, что и в прошлый раз.
Если такое есть — то мы построили ООП поверх очередей сообщений. Если такого нету — то нет и ООП.
Скажем, широковещательная рассылка UDP пакета, упомянутая по соседству, не является ООП.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
S>>Я как-то плохо себе представляю вот эту "эквивалентность". Вот есть у меня, допустим, контракт на OrderTracking. S>>Он типа весь стандартный. И что, мне должно быть пофигу, вызывать его для Fedex, UPS, или DHL?
G>Судя по тому что UDDI не пошел в массы скорее всего так и предполагалось. Но не получилось.
Не, я не про UDDI. Я про то, что если моя посылка отправлена федексом, то ДХЛ можно хоть заспрашиваться о ней.
То есть — имеем state. Клиентский код для общения с сервисами может быть одним и тем же, но вызов мы отправляем конкретному сервису. Что, очевидно, изоморфно ООПу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
E>>какое имеет значение, нравится оно мне или нет? я ведь не пытаюсь тут кому-то доказать или навязать какое-то решение, в отличии от вас. S>Я не навязываю решение. Я показываю, что ваш подход заводит вас в тупик на каждом шаге. А мой приводит к корректным решениям.
у вас есть комплексное решение, у меня его нет. у меня нет готовой реализации модели магазина.
я лишь могу строить предположения и мелкие решения на основании конкретного требования, но не их комплекса, и естественно это не будет работать для всех случаев.
более того, я даже не пытаюсь решить поставленную задачу, так как в этом нет смысла.
к тому же, кроме интернет магазинов, существует еще масса задач.
вы меня пытаетесь разубедить в эффективности рич модели, которая, в общем-то, достаточно эффективно используется в текущих проектах, там, где это необходимо, и используются другие подходы, если они лучше подходят для решения конкретной задачи.
если вы не можете реализовать эффективную модель для своего случая, это исключительно ваши проблемы. но зачем же меня убеждать в том, что рич это плохо?
Здравствуйте, gandjustas, Вы писали:
G>Вообще свойство identity в программе выражается в том что для пары объектов можно проверить идентичны они или нет.
Мы должны проверять идентичность поведения, а тут уже пахнет проблемой останова. Т.е. доказать что объекты идентичны по их поведению невозможно. Можно это лишь опровергнуть. Но при этом объект(ы) возможно изменят свои состояния, так что эта операция небезопасная.
S>Вы останетесь при своем, даже если вас удастся убедить?
для того, что бы меня в чем-то разубедить, я должен быть в чем-то убежден)
но я не настаивал на каком-то одном конкретном решении, являющимся голубой таблеткой. я неоднократно говорил что нужно руководствоваться здравым смыслом.
но меня по прежнему пытаются в чем-то убедить. но зачем?
Здравствуйте, Enomay, Вы писали:
S>>Вы останетесь при своем, даже если вас удастся убедить?
E>для того, что бы меня в чем-то разубедить, я должен быть в чем-то убежден) E>но я не настаивал на каком-то одном конкретном решении, являющимся голубой таблеткой. я неоднократно говорил что нужно руководствоваться здравым смыслом. E>но меня по прежнему пытаются в чем-то убедить. но зачем?
Что бы не платить взносы в братстве Истинного ООП, нужно привести последователей
Здравствуйте, samius, Вы писали:
I>>Можешь не тратить месяц — Синклер сделал то о чем я тебя просил всего за одно сообщение. S>Вот и славно, спасибо Синклеру. S>Так это была просьба? Я принял ее за предварительный диагноз. I>>Тренируйся. S>Только меня не покидает ощущение того, что если бы ты о примере услышал от меня, то повел бы себя иначе.
Я то здесь при чем ? Это ж ты просьбу показать код трактуешь как диагноз
Здравствуйте, Lloyd, Вы писали:
L>>>Вызов процедуры, например.
I>>Где же здесь messaging т.е. взаимодействие объектов через посылку-приём сообщений ?
L>Посылка сообщения — это абстракция любого вызова, не только вызова методов объектов. Для примера, можешь поинтересоваться SOA и очередями сообщений.
Посылка сообщения есть, а где в вызове процедуры "взаимодействие объектов через посылку-приём сообщений" ? Кто в вызове процедуры принимает сообщение ? Одной процедуры получается недостаточно.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали: L>>Идентичность чего с чем? S>Более точным переводом identity является "идентифицируемость", но обычно переводят "идентичность". S>У вас есть какие-то сомнения в том, что в SOA каждое обращение идёт к какому-то конкретному сервису?
L>>Почему нет? В чем собственно отличие сервиса от очереди сообщений, если не принимать во внимание асинхронности, S>Очередь — всего лишь механизм доставки. Кто разгребает очередь?
L>>Поведение с предысторий — можно. S>Можно, но получится собственно эмуляция ООП при помощи процедурного программирования (CFront помните?)
Здравствуйте, Enomay, Вы писали: E>у вас есть комплексное решение, у меня его нет. у меня нет готовой реализации модели магазина.
Ещё раз: у меня нет комплексного решения. У меня есть подход. Я код в этот топик пишу из головы, а не из SVN.
E>я лишь могу строить предположения и мелкие решения на основании конкретного требования, но не их комплекса, и естественно это не будет работать для всех случаев. E>более того, я даже не пытаюсь решить поставленную задачу, так как в этом нет смысла. E>к тому же, кроме интернет магазинов, существует еще масса задач.
Это правда. E>вы меня пытаетесь разубедить в эффективности рич модели, которая, в общем-то, достаточно эффективно используется в текущих проектах, там, где это необходимо, и используются другие подходы, если они лучше подходят для решения конкретной задачи.
Ок. Ну расскажите же нам, для решения какой задачи рич подходит лучше анемика, и мы посмотрим, так это или нет.
E>если вы не можете реализовать эффективную модель для своего случая, это исключительно ваши проблемы.
Почему же не могу? Могу. Просто это будет не рич модель. E>но зачем же меня убеждать в том, что рич это плохо?
Да, это мы уже ушли от темы "почему анемик — это ООП".
На самом деле, я спорю со сложным тезисом "ООП — хорошо; анемик — более ООП чем рич, поэтому рич — лучше, чем анемик".
В нём неправильно сразу всё:
— ООП само по себе не плохое и не хорошее. Оно подходит для очень многих задач, а для некоторых — не очень.
— анемик не обязательно менее ООП чем рич. Да, в рамках анемик модели можно обойтись без ООП, но ограничения на применение ООП в анемике нету.
— рич не лучше чем анемик. В большинстве случаев, рассмотренных в рамках этого форума, рич безнадёжно сливает анемику по нефункциональным характеристикам.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
было — "купив два, третий — бесплатно". Функцию вроде той что ты привел нужно снабдить комментарием
// вызывать только из Order.GetTotal
или же снабдить параметром Order.
Что будет если бизнес (бизнес == иди туда не знаю куда принеси то не знаю что) скажет вдруг "а добавь скидку 'принеси упаковку от xxx, возьми два и получи третий бесплатно' "
получится
GetPrice(bool oldBag, int count)
И так на каждое новое требование придется изменять сигнатуру и даже раскладывать одну единственную схему скидок по классам Order-OrderLIne-Product-Delivery.
Здравствуйте, Sinclair, Вы писали:
S>- рич не лучше чем анемик. В большинстве случаев, рассмотренных в рамках этого форума, рич безнадёжно сливает анемику по нефункциональным характеристикам.
Не хочу защищать рич, но в том что GetTotalPrice() оказался в Order, виноват не рич. Рич не запрещает создать некий PriceFormation и положить GetTotalPrice(OrderLineCollection) в него вместе с активным набором скидок.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>Я то здесь при чем ? Это ж ты просьбу показать код трактуешь как диагноз
Как это при чем? Это же была твоя "просьба".
Здравствуйте, Ikemefula, Вы писали:
L>>Посылка сообщения — это абстракция любого вызова, не только вызова методов объектов. Для примера, можешь поинтересоваться SOA и очередями сообщений.
I>Посылка сообщения есть, а где в вызове процедуры "взаимодействие объектов через посылку-приём сообщений" ?
А где во фразе "Вообще говоря идентичность уже включено в понятие messaging" процитированный кусок?
Здравствуйте, samius, Вы писали:
I>>Здравствуйте, samius, Вы писали:
I>>Я то здесь при чем ? Это ж ты просьбу показать код трактуешь как диагноз S>Как это при чем? Это же была твоя "просьба".
Одну и ту же просьбу читают несколько человек, но баттхёрт почему то у одного. Может у этого одного что то не так, раз ему мерещится диагноз ?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
L>>>Посылка сообщения — это абстракция любого вызова, не только вызова методов объектов. Для примера, можешь поинтересоваться SOA и очередями сообщений.
I>>Посылка сообщения есть, а где в вызове процедуры "взаимодействие объектов через посылку-приём сообщений" ?
L>А где во фразе "Вообще говоря идентичность уже включено в понятие messaging" процитированный кусок?
messaging == взаимодействие объектов через посылку-приём сообщений, это у Алана Кея так, к слову. Потому когда я использую определенный термин, то предполагаю, что ты будешь смотреть его значение в первоисточнике, а не придумывать своё.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
S>>Как это при чем? Это же была твоя "просьба".
I>Одну и ту же просьбу читают несколько человек, но баттхёрт почему то у одного. Может у этого одного что то не так, раз ему мерещится диагноз ?
В этот раз тоже мерещится? Или ты мне его все-таки поставил?
Здравствуйте, samius, Вы писали:
S>>>Как это при чем? Это же была твоя "просьба".
I>>Одну и ту же просьбу читают несколько человек, но баттхёрт почему то у одного. Может у этого одного что то не так, раз ему мерещится диагноз ? S>В этот раз тоже мерещится? Или ты мне его все-таки поставил?
Процитируй место, где ты увидел постановку диагноза, а то я перебрал свои сообщения в ветке и шота не нашел никаких диагнозов. Зато я нашел место где именно ты пробуешь поставить диагноз и получает справедливый отлуп
Здравствуйте, Ikemefula, Вы писали:
I>>>Посылка сообщения есть, а где в вызове процедуры "взаимодействие объектов через посылку-приём сообщений" ?
L>>А где во фразе "Вообще говоря идентичность уже включено в понятие messaging" процитированный кусок?
I>messaging == взаимодействие объектов через посылку-приём сообщений,.
messaging — гораздо более широкое понятие, и я сильно сомневаюсь, что Кей писал именно о messaging как таковом.
I>Потому когда я использую определенный термин, то предполагаю, что ты будешь смотреть его значение в первоисточнике, а не придумывать своё.
Алан Кей не является первоисточником этого термина.
Здравствуйте, Ikemefula, Вы писали:
L>>А где во фразе "Вообще говоря идентичность уже включено в понятие messaging" процитированный кусок?
I>messaging == взаимодействие объектов через посылку-приём сообщений, это у Алана Кея так, к слову. Потому когда я использую определенный термин, то предполагаю, что ты будешь смотреть его значение в первоисточнике, а не придумывать своё.
кроме того, кей в процитированной в соседней ветке цитате определяется ооп через понятие messaging-а, что вас как бы должно было навести на мысль, что messaging — более базовае понятие.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>Одну и ту же просьбу читают несколько человек, но баттхёрт почему то у одного. Может у этого одного что то не так, раз ему мерещится диагноз ? S>>В этот раз тоже мерещится? Или ты мне его все-таки поставил?
I>Процитируй место, где ты увидел постановку диагноза, а то я перебрал свои сообщения в ветке и шота не нашел никаких диагнозов. Зато я нашел место где именно ты пробуешь поставить диагноз и получает справедливый отлуп
Пожалуйста, см. выделенное. Свои сообщения ты тоже читать не умеешь. Это не диагноз, это факт.
Здравствуйте, samius, Вы писали:
I>>>>Одну и ту же просьбу читают несколько человек, но баттхёрт почему то у одного. Может у этого одного что то не так, раз ему мерещится диагноз ? S>>>В этот раз тоже мерещится? Или ты мне его все-таки поставил?
I>>Процитируй место, где ты увидел постановку диагноза, а то я перебрал свои сообщения в ветке и шота не нашел никаких диагнозов. Зато я нашел место где именно ты пробуешь поставить диагноз и получает справедливый отлуп S>Пожалуйста, см. выделенное. Свои сообщения ты тоже читать не умеешь. Это не диагноз, это факт.
То есть, когда ты вчера углядел диагноз, ты был уверен, что сегодня я тебе его поставлю ? Похоже, ты слишком хорошо себя знаешь
Здравствуйте, Lloyd, Вы писали:
I>>messaging == взаимодействие объектов через посылку-приём сообщений, это у Алана Кея так, к слову. Потому когда я использую определенный термин, то предполагаю, что ты будешь смотреть его значение в первоисточнике, а не придумывать своё.
L>кроме того, кей в процитированной в соседней ветке цитате определяется ооп через понятие messaging-а, что вас как бы должно было навести на мысль, что messaging — более базовае понятие.
В той же ветке, если ты заметил, нет ничего про идентити И это должно тебя навести на мысль, что всё таки идентити определяется хотя и не фигурирует явно.
Здравствуйте, Lloyd, Вы писали:
L>messaging — гораздо более широкое понятие, и я сильно сомневаюсь, что Кей писал именно о messaging как таковом.
I>>Потому когда я использую определенный термин, то предполагаю, что ты будешь смотреть его значение в первоисточнике, а не придумывать своё.
L>Алан Кей не является первоисточником этого термина.
Если совсем буквально ты прав. Алан Кей даёт определённую метафору и использует глагол communicate. И да, одним словом спокойно может быть названо несколько понятий.
Здравствуйте, gandjustas, Вы писали:
S>>Более точным переводом identity является "идентифицируемость", но обычно переводят "идентичность". S>>У вас есть какие-то сомнения в том, что в SOA каждое обращение идёт к какому-то конкретному сервису? G>Снаружи нет возможности идентифицировать конкретный сервис, вернее экземпляр сервиса. Это и есть отсутствие идентичности.
Разве идентити означает возможность снаружи идентифицировать конкретный объект ?
Здравствуйте, Ikemefula, Вы писали:
I>>>messaging == взаимодействие объектов через посылку-приём сообщений, это у Алана Кея так, к слову. Потому когда я использую определенный термин, то предполагаю, что ты будешь смотреть его значение в первоисточнике, а не придумывать своё.
L>>кроме того, кей в процитированной в соседней ветке цитате определяется ооп через понятие messaging-а, что вас как бы должно было навести на мысль, что messaging — более базовае понятие.
I>В той же ветке, если ты заметил, нет ничего про идентити
Давай сначала разберемся с фразой "messaging == взаимодействие объектов через посылку-приём сообщений".
Эта фраза не может являться определением messaging-а, т.к. Кей, на которого ты так любишь ссылаться, использует понятие messaging при определении взаимодействия объектов, следовательно messaging — более базовое понятие.
I>И это должно тебя навести на мысль, что всё таки идентити определяется хотя и не фигурирует явно.
Да ясогласен, что ООП подразумевает identity. Но ты же утверждаешь не это, а что-то другое, а именно, что "идентичность уже включено в понятие messaging", а это утверждение уже неверно.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
S>>Пожалуйста, см. выделенное. Свои сообщения ты тоже читать не умеешь. Это не диагноз, это факт.
I>То есть, когда ты вчера углядел диагноз, ты был уверен, что сегодня я тебе его поставлю ? Похоже, ты слишком хорошо себя знаешь
Ты предсказуем как понос после кефира с селедкой. В одном я промахнулся, в том что ты мне диагноз бы поставил в любом случае, с примером или без.
Здравствуйте, samius, Вы писали:
S>>>Пожалуйста, см. выделенное. Свои сообщения ты тоже читать не умеешь. Это не диагноз, это факт.
I>>То есть, когда ты вчера углядел диагноз, ты был уверен, что сегодня я тебе его поставлю ? Похоже, ты слишком хорошо себя знаешь S>Ты предсказуем как понос после кефира с селедкой. В одном я промахнулся, в том что ты мне диагноз бы поставил в любом случае, с примером или без.
Я ж говорю, ты хорошо себя знаешь А я не люблю людей которые делают заявления и отказываются пояснять. Очень сильно не люблю. Ты собственно мог бы это заметить, начиная где то с обсуждения визиторов пару лет назад.
Здравствуйте, Lloyd, Вы писали:
L>Давай сначала разберемся с фразой "messaging == взаимодействие объектов через посылку-приём сообщений". L>Эта фраза не может являться определением messaging-а, т.к. Кей, на которого ты так любишь ссылаться, использует понятие messaging при определении
взаимодействия объектов, следовательно messaging — более базовое понятие.
"I thought of objects being like biological cells and/or individual
computers on a network, only able to communicate with messages "
Где здесь "более базовое понятие ?"
I>>И это должно тебя навести на мысль, что всё таки идентити определяется хотя и не фигурирует явно.
L>Да ясогласен, что ООП подразумевает identity. Но ты же утверждаешь не это, а что-то другое, а именно, что "идентичность уже включено в понятие messaging", а это утверждение уже неверно.
Идентити оно в messaging, потому как у сообщения есть минимум получатель и отправитель. Если терминальный получатель заранее не известен, в этом нет ничего страшного, так как есть другие, транзитные.
Здравствуйте, Ikemefula, Вы писали:
L>>Давай сначала разберемся с фразой "messaging == взаимодействие объектов через посылку-приём сообщений". L>>Эта фраза не может являться определением messaging-а, т.к. Кей, на которого ты так любишь ссылаться, использует понятие messaging при определении I>взаимодействия объектов, следовательно messaging — более базовое понятие.
I>"I thought of objects being like biological cells and/or individual I>computers on a network, only able to communicate with messages "
I>Где здесь "более базовое понятие ?"
Ты не понимаешь что означает "более базовое"?
"А — более базовое по отношению к Б" в данном случае означает, что Б определяется в терминах А. В обсуждаемом примере A — messaging, Б — объекты в ООП (сокласно Кеевском определению).
Так вот, если А — более базовое к Б, то определение А через Б — невалидно (см. свое определение messaging).
I>>>И это должно тебя навести на мысль, что всё таки идентити определяется хотя и не фигурирует явно.
L>>Да ясогласен, что ООП подразумевает identity. Но ты же утверждаешь не это, а что-то другое, а именно, что "идентичность уже включено в понятие messaging", а это утверждение уже неверно.
I>Идентити оно в messaging, потому как у сообщения есть минимум получатель и отправитель.
Вообще-то, это не так, получателя может и не быть.
Например, кто явлется получателем широковещательного сетевого сообщения, когда к сети подключен только отправитель? Или кто является получателем в случае отправки сообщения в MQ, из которой никто не читает?
Здравствуйте, samius, Вы писали:
G>>Вообще свойство identity в программе выражается в том что для пары объектов можно проверить идентичны они или нет. S>Мы должны проверять идентичность поведения, а тут уже пахнет проблемой останова. Т.е. доказать что объекты идентичны по их поведению невозможно. Можно это лишь опровергнуть. Но при этом объект(ы) возможно изменят свои состояния, так что эта операция небезопасная.
Совершенно верно. Именно поэтому в ООП встраивают идентифицируемость с самого начала, чтобы не надо было проверять идентичность поведения.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали: L>Вообще-то, это не так, получателя может и не быть. L>Например, кто явлется получателем широковещательного сетевого сообщения, когда к сети подключен только отправитель? Или кто является получателем в случае отправки сообщения в MQ, из которой никто не читает?
Это всё верно, но Кей имел в виду не messaging вообще, а совершенно определённый messaging — в коммуникации между объектами.
Вот в такой messaging идентити таки встроено. Отправка бродкаст пакета не имеет отношения к кеевскому ООП.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
L>>Например, кто явлется получателем широковещательного сетевого сообщения, когда к сети подключен только отправитель? Или кто является получателем в случае отправки сообщения в MQ, из которой никто не читает? S>Это всё верно, но Кей имел в виду не messaging вообще,
А теперь смотрим, с чего это началось:
Вообще говоря идентичность уже включено в понятие messaging
S>а совершенно определённый messaging — в коммуникации между объектами. Вот в такой messaging идентити таки встроено.
Нет, не так. В коммуникацию между объектами "встроено" messaging и идентити: чтобы коммуницировать нужен адресат (для этого нужен способ на него сослаться) и содержимое коммуникации (message).
Но в messaging идентити таки не встроено.
Здравствуйте, Lloyd, Вы писали:
I>>"I thought of objects being like biological cells and/or individual I>>computers on a network, only able to communicate with messages "
I>>Где здесь "более базовое понятие ?"
L>Ты не понимаешь что означает "более базовое"?
Я тебя спрашиваю, где ты углядел определение через родовые, т.е. базовые понятия во фразе "я думал об объектах как о..."
Просто выдели нужные слова и этого будет достаточно.
I>>Идентити оно в messaging, потому как у сообщения есть минимум получатель и отправитель.
L>Вообще-то, это не так, получателя может и не быть. L>Например, кто явлется получателем широковещательного сетевого сообщения, когда к сети подключен только отправитель?
Сеть как транзитный получатель.
>Или кто является получателем в случае отправки сообщения в MQ, из которой никто не читает?
Очередь как транзитный получатель.
"Если терминальный получатель заранее не известен, в этом нет ничего страшного, так как есть другие, транзитные."
Вот если нет ни транзитного, ни терминального, то это да, проблема. И похоже твои два примера сюда не относятся
Здравствуйте, Sinclair, Вы писали:
S>Это всё верно, но Кей имел в виду не messaging вообще, а совершенно определённый messaging — в коммуникации между объектами. S>Вот в такой messaging идентити таки встроено. Отправка бродкаст пакета не имеет отношения к кеевскому ООП.
бродкаст посылается всей сети. вот послать сообщение без сети и даже без среды — вот это было бы новостью
Здравствуйте, Ikemefula, Вы писали:
I>>>Где здесь "более базовое понятие ?"
L>>Ты не понимаешь что означает "более базовое"?
I>Я тебя спрашиваю, где ты углядел определение через родовые, т.е. базовые понятия
С чего бы "родовые" — вдруг стали "базовые понятия" ?
I>во фразе "я думал об объектах как о..."
Ты откуда это вообще выкопал? Ты еще Пушкина бы еще процитировал.
I>Просто выдели нужные слова и этого будет достаточно.
OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.
I>>>Идентити оно в messaging, потому как у сообщения есть минимум получатель и отправитель.
L>>Вообще-то, это не так, получателя может и не быть. L>>Например, кто явлется получателем широковещательного сетевого сообщения, когда к сети подключен только отправитель?
I>Сеть как транзитный получатель.
Нет, сеть — не получатель, а среда передачи.
>>Или кто является получателем в случае отправки сообщения в MQ, из которой никто не читает?
I>Очередь как транзитный получатель.
Опять нет.
I>"Если терминальный получатель заранее не известен, в этом нет ничего страшного, так как есть другие, транзитные."
I>Вот если нет ни транзитного, ни терминального, то это да, проблема. И похоже твои два примера сюда не относятся
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
S>>Ты предсказуем как понос после кефира с селедкой. В одном я промахнулся, в том что ты мне диагноз бы поставил в любом случае, с примером или без.
I>Я ж говорю, ты хорошо себя знаешь А я не люблю людей которые делают заявления и отказываются пояснять. Очень сильно не люблю. Ты собственно мог бы это заметить, начиная где то с обсуждения визиторов пару лет назад.
Так это все было прелюдией перед тем, как поведать мне о своей нелюбви? Придется тебя разочаровать. Я не рассчитываю на твою любовь и не пытаюсь анализировать твои чувства к окружающим и помнить о них годы.
Но я помню что там где ты, вместо обмена опыта обмен "любезностями".
Потому, если хочешь обмена опытом и мнениями — прояви уважение к опыту и мнениям. Нет — иди лесом и нелюби кого влезет. Меня лично, в одностороннем порядке, твой опыт и его пополнение не интересуют. Помни об этом, когда будешь приставать со своей нелюбовью.
Здравствуйте, Lloyd, Вы писали:
I>>во фразе "я думал об объектах как о..."
L>Ты откуда это вообще выкопал? Ты еще Пушкина бы еще процитировал.
У Алана Кея, в той части где он поясняет, что же такое messaging.
I>>Просто выдели нужные слова и этого будет достаточно.
L>OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.
Это ж определение ООП, а не messaging и то не совсем уж определение, скорее просто мнение
I>>Сеть как транзитный получатель.
L>Нет, сеть — не получатель, а среда передачи.
Да как хочешь назови, ничего не изменится. Это самой среде отправляется сообщение "вот то сообщение доставь получателям" Т.е. среда выступает как объект, ибо у Кея "всё есть объект" и "объекты взаимодействуют посредством отправки-приём сообщений".
Здравствуйте, samius, Вы писали:
I>>Я ж говорю, ты хорошо себя знаешь А я не люблю людей которые делают заявления и отказываются пояснять. Очень сильно не люблю. Ты собственно мог бы это заметить, начиная где то с обсуждения визиторов пару лет назад. S>Так это все было прелюдией перед тем, как поведать мне о своей нелюбви?
Если совсем точно, то это была отрицательная стимуляция твоих действий.
>Придется тебя разочаровать. Я не рассчитываю на твою любовь и не пытаюсь анализировать твои чувства к окружающим и помнить о них годы.
У меня память так устроена, что безо всякого напряга я помню многие вещи
S>Потому, если хочешь обмена опытом и мнениями — прояви уважение к опыту и мнениям.
Начни с себя. Например в следующий раз когда решишь написать нечто вроде ""Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь."" — просто сделай паузу в десяток-другой ответов мне — заметь, я предлагаю тебе это уже в который раз.
Здравствуйте, Flem1234, Вы писали:
F>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, Flem1234, Вы писали:
F>>>Как в SOA же нет состояния. G>>Это неверно. F>Это потому что на одинаковые сообщения сервис в праве реагировать по разному?
Нет, просто потому что SOA не отрицает состояние.
F>>>Нет состояния — нет ООП. G>>Это тоже неверно. F>Я думал, что если нет состояния, то ООП тоже нет.
Неправильно думал ООП — про поведение, а не про состояние.
Здравствуйте, Ikemefula, Вы писали:
L>>Ты откуда это вообще выкопал? Ты еще Пушкина бы еще процитировал.
I>У Алана Кея, в той части где он поясняет, что же такое messaging.
Прочтите эту часть внимательнее: он поясняет, не что такое messaging, а как взаимодействуют объекты.
I>>>Просто выдели нужные слова и этого будет достаточно.
L>>OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.
I>Это ж определение ООП, а не messaging и то не совсем уж определение, скорее просто мнение
Это определение через базовые понятия.
L>>Нет, сеть — не получатель, а среда передачи.
I>Да как хочешь назови, ничего не изменится.
Конечно не изменится ибо мое сообщение до получателя никак не доходит.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
S>>Так это все было прелюдией перед тем, как поведать мне о своей нелюбви?
I>Если совсем точно, то это была отрицательная стимуляция твоих действий.
И ты в ответ хотел конструктив? Жениться тебе надо, барин!
S>>Потому, если хочешь обмена опытом и мнениями — прояви уважение к опыту и мнениям.
I>Начни с себя. Например в следующий раз когда решишь написать нечто вроде ""Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь."" — просто сделай паузу в десяток-другой ответов мне — заметь, я предлагаю тебе это уже в который раз.
А я предлагаю тебе пойти лесом, уже в который раз.
Здравствуйте, samius, Вы писали:
I>>Если совсем точно, то это была отрицательная стимуляция твоих действий. S>И ты в ответ хотел конструктив? Жениться тебе надо, барин!
После фразы "Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь." я уже не ждал никакого конструктива от тебя.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
S>>>Более точным переводом identity является "идентифицируемость", но обычно переводят "идентичность". S>>>У вас есть какие-то сомнения в том, что в SOA каждое обращение идёт к какому-то конкретному сервису? G>>Снаружи нет возможности идентифицировать конкретный сервис, вернее экземпляр сервиса. Это и есть отсутствие идентичности.
I>Разве идентити означает возможность снаружи идентифицировать конкретный объект ?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>После фразы "Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь." я уже не ждал никакого конструктива от тебя.
Персонально у тебя не было повода ждать конструктива от меня и до этой фразы. Можешь рассчитывать на подобное и впредь, пока у меня нет ни повода, ни желания отвечать тебе конструктивом.
Здравствуйте, Lloyd, Вы писали:
I>>У Алана Кея, в той части где он поясняет, что же такое messaging. L>Прочтите эту часть внимательнее: он поясняет, не что такое messaging, а как взаимодействуют объекты.
Какую эту ? Я тебя только что попросил выделить и ты вместо "этой части" про взаимодействие привел высказывание, что же ООП значит для Алана Кея лично Потому мне совсем не ясно, какое именно высказываение Кея ты иммешь ввиду.
I>>Это ж определение ООП, а не messaging и то не совсем уж определение, скорее просто мнение
L>Это определение через базовые понятия.
Это не определение, т.к. "to me" — стало быть, всего лишь мнение.
I>>Да как хочешь назови, ничего не изменится.
L>Конечно не изменится
Здравствуйте, Ikemefula, Вы писали:
I>>>У Алана Кея, в той части где он поясняет, что же такое messaging. L>>Прочтите эту часть внимательнее: он поясняет, не что такое messaging, а как взаимодействуют объекты.
I>Какую эту ? Я тебя только что попросил выделить и ты вместо "этой части" про взаимодействие привел высказывание, что же ООП значит для Алана Кея лично Потому мне совсем не ясно, какое именно высказываение Кея ты иммешь ввиду.
Я имею в виду то высказывание, кусок разговора о котором я оставил отквоченым в своем посте. Да, повторю совет про читать внимательнее.
I>>>Это ж определение ООП, а не messaging и то не совсем уж определение, скорее просто мнение
L>>Это определение через базовые понятия.
I>Это не определение, т.к. "to me" — стало быть, всего лишь мнение.
Нет, это определение OOP мо мнению Кея.
I>>>Да как хочешь назови, ничего не изменится.
L>>Конечно не изменится
I>Ну раз ты согласен, на том можно и закончить.
Ты опять недостаточно вчитался в ответ:
Конечно не изменится ибо мое сообщение до получателя никак не доходит.
Здравствуйте, samius, Вы писали:
I>>После фразы "Легко, но ради того что бы тебе что-то вталдычить я его накидывать не собираюсь." я уже не ждал никакого конструктива от тебя. S>Персонально у тебя не было повода ждать конструктива от меня и до этой фразы.
Не льсти себе, персонально для тебя у меня нет никаких приёмов Потому я жду ровно столько же как и от любого другого. Более того, скажу страшное, я даже не всегда замечаю кому именно пишу ответ В данном топике я например не сразу заметил что разговариваю с Lloyd
>Можешь рассчитывать на подобное и впредь, пока у меня нет ни повода, ни желания отвечать тебе конструктивом.
Я ж говорю — ты слишком хорошо себя знаешь и я тут точно ни при чем
Здравствуйте, Lloyd, Вы писали:
I>>Какую эту ? Я тебя только что попросил выделить и ты вместо "этой части" про взаимодействие привел высказывание, что же ООП значит для Алана Кея лично Потому мне совсем не ясно, какое именно высказываение Кея ты иммешь ввиду.
L>Я имею в виду то высказывание, кусок разговора о котором я оставил отквоченым в своем посте. Да, повторю совет про читать внимательнее.
Смотри сам, что было:
I>>"I thought of objects being like biological cells and/or individual
I>>computers on a network, only able to communicate with messages "
I>>Где здесь "более базовое понятие ?"
L>Ты не понимаешь что означает "более базовое"?
Я тебя спрашиваю, где ты углядел определение через родовые, т.е. базовые понятия во фразе "я думал об объектах как о..."
Просто выдели нужные слова и этого будет достаточно.
И совершенно не ясно, как ты перепрыгнул на высказывание про ООП, когда речь явно про то, что же такое messaging
L>Ты опять недостаточно вчитался в ответ: L>
L>Конечно не изменится ибо мое сообщение до получателя никак не доходит.
L>Суть я выделил, раз вы с первого раза не уловили.
Ты мог бы и не стараться, я скипнул все лишнее, ровно так же, как и ты перед этим — просто что бы показать тебе твой же собственный подход. Ты, по моему, слишком часто злоупотребляешь тем, что удаляешь лишний текст да еще стараешься обвинять меня в том, что я чего то искажаю.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
I>>Не льсти себе, персонально для тебя у меня нет никаких приёмов Потому я жду ровно столько же как и от любого другого. Более того, скажу страшное, я даже не всегда замечаю кому именно пишу ответ В данном топике я например не сразу заметил что разговариваю с Lloyd
L>Что, Павел, в лишний раз подтверждает факт, что вы не читаете не только пост, на который отвечаете, но и даже то, что вы сами пишете. L>Иначе как понять, что вы не заметили "Здравствуйте, Lloyd, Вы писали:" в каждом своем ответе?
Очень просто.
Во первых я вообще не смотрю на первые строчки как раз потому что там "Здравствуйте, xxx, Вы писали" и бывает таких строчек не одна а штук пять. И по моему эта как раз та ненужная фича которая только загромождает экран.
Во вторых меня интересует точка зрения, а не её автор.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
F>>>Я думал, что если нет состояния, то ООП тоже нет. G>>Неправильно думал ООП — про поведение, а не про состояние.
I>А как без состояния реализовать поведение которое зависит от предыстории сообщений ?
А почему без состояния?
Ты видимо не так понял фразу
ООП — про поведение, а не про состояние
как то что в ООП нет состояния, но это неверно.
Принципы которыми руководствуется ООП (инкапсуляция, полиморфизм) надо применять для поведения, а не для состояния.
Например наследование — не средство добавления полей в класс, а средство специализации поведения класса.
Здравствуйте, Ikemefula, Вы писали:
I>>>Какую эту ? Я тебя только что попросил выделить и ты вместо "этой части" про взаимодействие привел высказывание, что же ООП значит для Алана Кея лично Потому мне совсем не ясно, какое именно высказываение Кея ты иммешь ввиду.
L>>Я имею в виду то высказывание, кусок разговора о котором я оставил отквоченым в своем посте. Да, повторю совет про читать внимательнее.
I>Смотри сам, что было: I>
I>>>"I thought of objects being like biological cells and/or individual
I>>>computers on a network, only able to communicate with messages "
I>>>Где здесь "более базовое понятие ?"
L>>Ты не понимаешь что означает "более базовое"?
I>Я тебя спрашиваю, где ты углядел определение через родовые, т.е. базовые понятия во фразе "я думал об объектах как о..."
I>Просто выдели нужные слова и этого будет достаточно.
I>И совершенно не ясно, как ты перепрыгнул на высказывание про ООП, когда речь явно про то, что же такое messaging
Нет, Павел, вы опять не читаете. В процитрованном вами тексте речь не о messaging, а о способе взаимодействия объектов.
Ровно та же самая ошибка.
L>>Ты опять недостаточно вчитался в ответ: L>>
L>>Конечно не изменится ибо мое сообщение до получателя никак не доходит.
L>>Суть я выделил, раз вы с первого раза не уловили.
I>Ты мог бы и не стараться, я скипнул все лишнее, ровно так же, как и ты перед этим — просто что бы показать тебе твой же собственный подход. I>Ты, по моему, слишком часто злоупотребляешь тем, что удаляешь лишний текст да еще стараешься обвинять меня в том, что я чего то искажаю.
Павел, ну это, право, смешно слышать от вас про "удаляешь лишний текст".
Вас уже такое кол-во раз посадили в лужу, но вы упорно в своих ответах просто скипаете этот факт и переходите к другой более удобной теме. За примером ходить далеко не надо: смотрите 52-й пост, когда вы в обсуждение о том, что такое messaging элегантно вплели обсуждение identity.
Здравствуйте, gandjustas, Вы писали:
F>>>>Я думал, что если нет состояния, то ООП тоже нет. G>>>Неправильно думал ООП — про поведение, а не про состояние.
I>>А как без состояния реализовать поведение которое зависит от предыстории сообщений ?
G>А почему без состояния?
Так ведь исходная посылка у Flem1234 — "если нет состояния, то ООП тоже нет"
G>Ты видимо не так понял фразу
G>
G>ООП — про поведение, а не про состояние
G>как то что в ООП нет состояния, но это неверно.
Ну это Синклер утрировал. Идея в том, что поведение это основная цель и об этом же говорит и Алан Кей. А состояние это уже дело десятое.
А сейчас мы говорим о том, что сказал Flem1234 — "если нет состояния, то ООП тоже нет"
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
F>>>>>Я думал, что если нет состояния, то ООП тоже нет. G>>>>Неправильно думал ООП — про поведение, а не про состояние.
I>>>А как без состояния реализовать поведение которое зависит от предыстории сообщений ?
G>>А почему без состояния?
I>Так ведь исходная посылка у Flem1234 — "если нет состояния, то ООП тоже нет"
Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
Здравствуйте, gandjustas, Вы писали:
I>>Так ведь исходная посылка у Flem1234 — "если нет состояния, то ООП тоже нет"
G>Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
Здравствуйте, Lloyd, Вы писали:
I>>Смотри сам, что было: I>>
I>>>>"I thought of objects being like biological cells and/or individual
I>>>>computers on a network, only able to communicate with messages "
I>>>>Где здесь "более базовое понятие ?"
L>>>Ты не понимаешь что означает "более базовое"?
I>>Я тебя спрашиваю, где ты углядел определение через родовые, т.е. базовые понятия во фразе "я думал об объектах как о..."
I>>Просто выдели нужные слова и этого будет достаточно.
I>>И совершенно не ясно, как ты перепрыгнул на высказывание про ООП, когда речь явно про то, что же такое messaging
L>Нет, Павел, вы опять не читаете.
Я нахожу такие аргументы крайне скучными и абсолютно бесполезными "у вас ошибка", "вы не так прочитали" и тд. Ты можешь не стараться, такое мнение очень легко симулировать
L>Ровно та же самая ошибка.
Это и есть messaging Еще раз — у Алана Кея messaging это не совсем тот messaging, что в сетях передачи данных. Слово Messaging он использует для обращения к одному из принципов ООП, их несколько, messaging во всех источниках это второй принцип, например вот такая формулировка:
"Communication is performed by objects communicating with each other, requesting that objects perform actions. Objects communicate by sending and receiving messages. A message is a request for action, bundled with whatever objects may be necessary to complete the task. "
I>>Ты мог бы и не стараться, я скипнул все лишнее, ровно так же, как и ты перед этим — просто что бы показать тебе твой же собственный подход. I>>Ты, по моему, слишком часто злоупотребляешь тем, что удаляешь лишний текст да еще стараешься обвинять меня в том, что я чего то искажаю.
L>Павел, ну это, право, смешно слышать от вас про "удаляешь лишний текст". L>Вас уже такое кол-во раз посадили в лужу, но вы упорно в своих ответах просто скипаете этот факт и переходите к другой более удобной теме.
Я то продолжаю ровно ту же тему — messaging.
>За примером ходить далеко не надо: смотрите 52-й пост, когда вы в обсуждение о том, что такое messaging элегантно вплели обсуждение identity.
смотрим 52й пост, опаньки, в этой ветке их два и оба принадлежат некому Lloyd. Что ты там говорил про умение читать ?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
I>>>Так ведь исходная посылка у Flem1234 — "если нет состояния, то ООП тоже нет"
G>>Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
L>А identity совсем без состояния реализуема?
Здравствуйте, Ikemefula, Вы писали:
L>>Нет, Павел, вы опять не читаете.
I>Я нахожу такие аргументы крайне скучными и абсолютно бесполезными "у вас ошибка", "вы не так прочитали" и тд. Ты можешь не стараться, такое мнение очень легко симулировать
Зечем мне симулировать мое же мнение?
L>>Ровно та же самая ошибка.
I>Это и есть messaging
Что означет эта фраза?
I>Еще раз — у Алана Кея messaging это не совсем тот messaging, что в сетях передачи данных. Слово Messaging он использует для обращения к одному из принципов ООП, их несколько, messaging во всех источниках это второй принцип, например вот такая формулировка: I>"Communication is performed by objects communicating with each other, requesting that objects perform actions. Objects communicate by sending and receiving messages. A message is a request for action, bundled with whatever objects may be necessary to complete the task. "
Вы зачем это пишите-то?
Да, он использует понятие messaging при описании способа взаимодействия объектов, но это не делает messaging применимым только к этой задаче.
Понятия messaging шире и потому ваша фраза про то, что messaging вклюяает identity — не корректна, взимодействие объектов — включает identity (нужен адресат), но не messaging-же [включает identity].
I>>>Ты мог бы и не стараться, я скипнул все лишнее, ровно так же, как и ты перед этим — просто что бы показать тебе твой же собственный подход. I>>>Ты, по моему, слишком часто злоупотребляешь тем, что удаляешь лишний текст да еще стараешься обвинять меня в том, что я чего то искажаю.
L>>Павел, ну это, право, смешно слышать от вас про "удаляешь лишний текст". L>Вас уже такое кол-во раз посадили в лужу, но вы упорно в своих ответах просто скипаете этот факт и переходите к другой более удобной теме.
I>Я то продолжаю ровно ту же тему — messaging.
Нет, Павел, вы уходите в лес да по дрова, т.к. messaging не имеет никакого отношения к identity, вам даже примеры привели с широковещательным сообщением и mq.
>>За примером ходить далеко не надо: смотрите 52-й пост, когда вы в обсуждение о том, что такое messaging элегантно вплели обсуждение identity.
I>смотрим 52й пост, опаньки, в этой ветке их два и оба принадлежат некому Lloyd. Что ты там говорил про умение читать ?
Спасибо, что поправили, действительно 51-й пост. Иногда вы-таки читаете, признаю.
Здравствуйте, gandjustas, Вы писали:
G>>>Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
L>>А identity совсем без состояния реализуема?
G>Да, а почему нет?
Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить?
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>>>Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
L>>>А identity совсем без состояния реализуема?
G>>Да, а почему нет?
L>Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить?
Легко:
class A
{
}
//...var a = new A();
var b = new A();
var c = a;
a==b //false
a==c //true
В этом и заключается свойство identity. При этом если a == b, то a.Equals(b) == true.
Если взять SOA и принять что identity обеспечивается адресом endpoint, а эквивалентность — поведением в зависимости от состояния, то легко сделать так чтобы a == b, но при этом a.Equals(b) = false
Здравствуйте, gandjustas, Вы писали:
G>>>>>Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
L>>>>А identity совсем без состояния реализуема?
G>>>Да, а почему нет?
L>>Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить?
G>В этом и заключается свойство identity. При этом если a == b, то a.Equals(b) == true.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>>>>>Она неверна. ООП может быть как с состоянием, так и без оного. Посмотри паттерны проектирования, добрая половина вообще никак с состоянием не связаны.
L>>>>>А identity совсем без состояния реализуема?
G>>>>Да, а почему нет?
L>>>Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить?
G>>В этом и заключается свойство identity. При этом если a == b, то a.Equals(b) == true.
L>Это не объекты без состояния, у них адрес есть.
Это не относится к их состоянию и типично не влияет на поведение с его историей, кроме тех случаев, когда поведение объекта завязано на физический адрес.
Вообще нам identity нужно не для того, что бы отличать объекты, а для того, что бы не путать их. Т.е. если я начал работу с одним объектом и его поведение зависит от истории ранее посланных сообщений, я должен быть уверен в том, что именно этот объект обработает мое сообщение, а не какой-то другой, находящийся в неожиданном для меня состоянии. Если же поведение объектов неотличимо, то какая разница?
new Foo().Bar() сделает то же самое что и cachedFoo.Bar()
Конечно, до тех пор, пока мы не строим логику на сравнении ссылок.
Здравствуйте, Lloyd, Вы писали:
I>>Я нахожу такие аргументы крайне скучными и абсолютно бесполезными "у вас ошибка", "вы не так прочитали" и тд. Ты можешь не стараться, такое мнение очень легко симулировать L>Зечем мне симулировать мое же мнение?
Я разве говорю что тебе надо симулировать ? Представь, я сам могу представить твои ответы, смотри:
"Ошибка", "Опять нет", "Ровно та же самая ошибка."
Информативность таких ответов примерно одинаковая и стремится к нулю слева.
L>>>Ровно та же самая ошибка. I>>Это и есть messaging L>Что означет эта фраза?
Это я случайно скипнул предложение. Вот цепочка
I>И совершенно не ясно, как ты перепрыгнул на высказывание про ООП, когда речь явно про то, что же такое messaging
Нет, Павел, вы опять не читаете. В процитрованном вами тексте речь не о messaging, а о способе взаимодействия объектов.
Ровно та же самая ошибка.
"Это и есть messaging "
Имеется ввиду выделеный текст, т.е. способ взаимодействия объектов == messaging. Если читать Кея, то он говорит что "messaging" это центральная часть Smalltalk, а messages в Smalltalk как то не допускают вольной трактовки.
I>>"Communication is performed by objects communicating with each other, requesting that objects perform actions. Objects communicate by sending and receiving messages. A message is a request for action, bundled with whatever objects may be necessary to complete the task. "
L>Да, он использует понятие messaging при описании способа взаимодействия объектов, но это не делает messaging применимым только к этой задаче.
Разумеется не делает. Он ведь указывает: "The big idea is "messaging" — that is what the kernal of Smalltalk/Squeak
is all about". Т.е. messaging в его трактовке это чуток не тот messaging что в сетях передачи данных и я уже говорил и повторяю снова.
L>Понятия messaging шире и потому ваша фраза про то, что messaging вклюяает identity — не корректна, взимодействие объектов — включает identity (нужен адресат), но не messaging-же [включает identity].
Я говорю про то, что Алан Кей называет messaging, а не про messaging вообще. Т.е. имеет место обычная практика — в зависимости от контекста термины часто меняют значение и это нормально.
I>>Я то продолжаю ровно ту же тему — messaging.
L>Нет, Павел, вы уходите в лес да по дрова, т.к. messaging не имеет никакого отношения к identity, вам даже примеры привели с широковещательным сообщением и mq.
Скажи пожалуйста, а где MQ и широковещательные сообщения в ядре Смаллтолка ?
"The big idea is "messaging" — that is what the kernal of Smalltalk/Squeak is all about ..."
При этом MQ и широковещательные сообщения можно свести к кеевскому "messaging", если под получателем понимать не конечного, а любого, в т.ч. промежуточно, т.е. транзитного, а сеть как объект. То есть, сеть получает сообщение А "передать сообщение Б всем подключенным участникам"
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, Lloyd, Вы писали:
L>>Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить?
G>Легко:
G>
G>class A
G>{
G>}
G>//...
G>var a = new A();
G>var b = new A();
G>var c = a;
G>a==b //false
G>a==c //true
G>
G>В этом и заключается свойство identity. При этом если a == b, то a.Equals(b) == true.
Тут мы получили равенство ссылок, а не отличие в поведении объектов.
Отличие в поведении мы получим так:
Здравствуйте, samius, Вы писали:
G>>В этом и заключается свойство identity. При этом если a == b, то a.Equals(b) == true. S>Тут мы получили равенство ссылок, а не отличие в поведении объектов.
Это и есть идентичность в отличие от эквивалентности.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>В этом и заключается свойство identity. При этом если a == b, то a.Equals(b) == true. S>>Тут мы получили равенство ссылок, а не отличие в поведении объектов. G>Это и есть идентичность в отличие от эквивалентности.
Не согласен.
Сравнение ссылок (при отсутствии оператора сравнения) дает нам ссылочную эквивалентность; вызов Equals дает нам эквивалентность по умолчанию; Comparison<T> дает нам любую другую эквивалентность. В то время как идентичность обусловлена идентичным поведением.
Объекты a и b не идентичны, т.к. по разному реагируют на x.Equals(b). Но их можно сделать таковыми, переопределив Equals соответствующим образом.
L>>Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить?
два объекта с одинаковым поведением и без состояния отличить невозможно. Но можно отличить ссылки на них. Это не одно и то же, т.к. адрес объекта или ссылка на объект — это не внутренний атрибут объекта и он не имеет отношения к поведению объекта в общем случае.
Верно то, что получив положительный результат сравнения ссылок на равенство, можно делать вывод об идентичности объектов. Обратное не верно (из идентичности поведения равенство ссылок не вытекает).
Наоборот, получив отрицательный результат сравнения ссылок на равенство, можно делать вывод лишь о том что мы имеем разные экземпляры. Но идентичность этим самым не опровергнута.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Сравнение ссылок (при отсутствии оператора сравнения) дает нам ссылочную эквивалентность; вызов Equals дает нам эквивалентность по умолчанию; Comparison<T> дает нам любую другую эквивалентность. В то время как идентичность обусловлена идентичным поведением. S>>Объекты a и b не идентичны, т.к. по разному реагируют на x.Equals(b). Но их можно сделать таковыми, переопределив Equals соответствующим образом. G>Ссылочная эквивалентность — реализация идентифицируемости (не идентичности, в данном случае слово наталкивает тебя наневерные размышления) в большинстве языков.
Я не делаю различий между этими словами. Говоря об идентичности я подразумеваю identity. Пусть это будет идентифицируемость.
G>Вот идентифицируемость в БД осуществляется по ключу, из за этого и возникают проблемы объектно-реляционного отображения.
Верно, а в ООП объекты идентифицируются по поведению.
S>>два объекта с одинаковым поведением и без состояния отличить невозможно. Но можно отличить ссылки на них. G>Что значит отличить?
В случае объектов — обнаружить отличное поведение. В случае ссылок — обнаружить равенство или неравенство их.
S>>Это не одно и то же, т.к. адрес объекта или ссылка на объект — это не внутренний атрибут объекта и он не имеет отношения к поведению объекта в общем случае. G>Да ну? Покажи как в C# получить ссылку отдельно от самого объекта?
Не получить, но это не делает ссылку атрибутом объекта. Тем более, что объект без ссылки в дотнете существовать может (недетерминированное время).
S>>Наоборот, получив отрицательный результат сравнения ссылок на равенство, можно делать вывод лишь о том что мы имеем разные экземпляры. Но идентичность этим самым не опровергнута. G>Еще раз, не идентичность, а идентифицируемость. В C# для объектов reference-типов идентифицируемость по ссылке.
Identity allows comparison of references. Two references can be compared whether they are equal or not. Due to the identity property, this comparison has special properties. If the comparison of references indicates that the references are equal, then it's clear that the two objects pointed by the references are the same object. If the references do not compare equal, then it's not necessarily guaranteed that the identity of the objects behind those references is different.The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
(http://en.wikipedia.org/wiki/Identity_%28object-oriented_programming%29)
т.е. согласно выделенному — из отсутствия равенства ссылок не следует различная идентифицируемость. В том числе в C#.
G>Метафора identity — паспорт. Если два человека выглядят и ведут себя одинаково, но у них разные паспорта, то это разные люди. Если один паспорт — то это один человек.
Если identity принимается за паспорт, то при разных паспортах мы получим разное identity. Из этого следует что экземпляры разные. Верно. Но из того что паспорта одинаковы не будет следовать что экземпляр один.
Это как если в дотнете взять две строки с одинаковым содержимым (пусть будут получены разным способом, что бы избежать скидки на интернирование). Поведение одинаково. о них говорят same identity, даже если ссылки будут отличаться.
G>В "мире" SOA вместо "паспорта", используется "адрес проживания". Что скрывается за этим адресом и кто получает сообщения снаружи не видно.
Это не имеет значения, пока сервис не начнет вести себя в зависимости от накопленной в своем внутреннем состоянии истории. А пока поведение конкретных получателей за этим адресом неотличимо, какая разница, кто из них получит сообщение?
Даже если история копится в БД, но различные экземпляры сервиса реагируют на нее одинаковым образом (шарят это состояние), это позволяет говорить об их same identity (см выделенное курсивом в цитате с википедии).
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Верно, а в ООП объекты идентифицируются по поведению. G>Нет, идентифицируемость объекта ортогонально поведению. Фактически возможность узнать являются ли два объекта идентичными (не путать с эквивалентностью). Свойство идентичности нельзя нарушить, в отличие от эквивалентности, которое может зависеть от состояния.
Если ты под идентичностью подразумеваешь возможность сказать что a1 и a2 это в точности тот же самый объект, занимающий ту же самую память, то identity с википедии точно не про это.
S>>Не получить, но это не делает ссылку атрибутом объекта. Тем более, что объект без ссылки в дотнете существовать может (недетерминированное время). G>Нет, может существовать память объекта, но не сам объект, потому что объект — identity+поведение. Если на объект нет ссылок, то фактически у него нет ни identity и нету способов получить поведение. G>Не стоит путать концептуальные вещи с деталями реализации. Ведь в .NET value-типы наследуются от Object, но это не значит что для каждого value-типа есть указатель на VMT.
Надо сперва разобраться с тем, что подразумевать под identity, способ идентифицировать объект с точностью до экземпляра, либо с точностью до поведения. Вики говорит об поведении, допуская множество объектов с same identity. Есть более компетентные источники с противоположным мнением?
S>>
S>>т.е. согласно выделенному — из отсутствия равенства ссылок не следует различная идентифицируемость. G>Да, потому что это деталь реализации.
Это общая концепция.
S>>В том числе в C#. G>Нет, ты не можешь в C# получить пару объектов reference типа для которых object.ReferenceEquals(a,b) == true, но a.Equals(b) == false, если нормально реализован Equals. Более того гайдлайн требует чтобы реализация equals была такова что идентичные объекты будут эквивалентны. На это и опирается ООП.
ООП опирается на понятие identity. А Equals — это особенности реализации эквивалентности в дотнете.
Качество реализации Equals влияет на работу с этим объектом средствами фреймворка, но не влияет на концептуальные качества объекта, не относящиеся к платформе.
S>>Если identity принимается за паспорт, то при разных паспортах мы получим разное identity. Из этого следует что экземпляры разные. Верно. Но из того что паспорта одинаковы не будет следовать что экземпляр один. G>Ну возьми SSN\СНИЛС, он не меняется.
Не имеет смысла обсуждать без согласования термина identity.
S>>Это как если в дотнете взять две строки с одинаковым содержимым (пусть будут получены разным способом, что бы избежать скидки на интернирование). Поведение одинаково. о них говорят same identity, даже если ссылки будут отличаться. G>Где говорят? Ссылку дай что ли. То что на equal string говорят same identity не делает чести тому кто говорит.
Не знаю, где говорят, но я сделал такой вывод на основании статьи в вики. G>И уж точно никак не влияет на соотношение identity и equal в ООП.
не влияет, т.к. между ними мало общего, учитывая то, что эквивалентность — понятие навесное. Никто не может мне запретить считать эквивалентными людей с одной фамилией при различном их поведении.
S>>Это не имеет значения, пока сервис не начнет вести себя в зависимости от накопленной в своем внутреннем состоянии истории. А пока поведение конкретных получателей за этим адресом неотличимо, какая разница, кто из них получит сообщение? S>>Даже если история копится в БД, но различные экземпляры сервиса реагируют на нее одинаковым образом (шарят это состояние), это позволяет говорить об их same identity (см выделенное курсивом в цитате с википедии). G>Нет, ты опять подменяешь понятия. Ты говоришь об эквивалентности (взаимозаменяемости) сервисов, а не об идентичности. Хотя тут ты даже доказать ничего не сможешь, потому что нарываешь на проблему тотальности.
Я говорю об identity из OOP. Или как минимум о том, что написано в википедии.
Здравствуйте, samius, Вы писали:
S>Но вместо того, что бы отделять тру-ООП от не тру-ООП, предлагаю сфокусировать внимание на том, что на самом деле мы тут обсуждаем лишь один аспект ООП, который даже напрямую нельзя отнести к ООП, т.к. непонятно откуда он взялся вообще. Это способ определения местонахождения метода по данным, которыми он пользуется.
Это один из GRASP-паттернов — Information Expert. Упоминается в книжке Лармана.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, samius, Вы писали:
S>>Но вместо того, что бы отделять тру-ООП от не тру-ООП, предлагаю сфокусировать внимание на том, что на самом деле мы тут обсуждаем лишь один аспект ООП, который даже напрямую нельзя отнести к ООП, т.к. непонятно откуда он взялся вообще. Это способ определения местонахождения метода по данным, которыми он пользуется.
L>Это один из GRASP-паттернов — Information Expert. Упоминается в книжке Лармана.
Order как набор OrderLine-ов в качестве Information Expert ничем не лучше чем набор действующих скидок.
Здравствуйте, samius, Вы писали:
S>>>Но вместо того, что бы отделять тру-ООП от не тру-ООП, предлагаю сфокусировать внимание на том, что на самом деле мы тут обсуждаем лишь один аспект ООП, который даже напрямую нельзя отнести к ООП, т.к. непонятно откуда он взялся вообще. Это способ определения местонахождения метода по данным, которыми он пользуется.
L>>Это один из GRASP-паттернов — Information Expert. Упоминается в книжке Лармана. S>Order как набор OrderLine-ов в качестве Information Expert ничем не лучше чем набор действующих скидок.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, samius, Вы писали:
S>>>>Но вместо того, что бы отделять тру-ООП от не тру-ООП, предлагаю сфокусировать внимание на том, что на самом деле мы тут обсуждаем лишь один аспект ООП, который даже напрямую нельзя отнести к ООП, т.к. непонятно откуда он взялся вообще. Это способ определения местонахождения метода по данным, которыми он пользуется.
L>>>Это один из GRASP-паттернов — Information Expert. Упоминается в книжке Лармана. S>>Order как набор OrderLine-ов в качестве Information Expert ничем не лучше чем набор действующих скидок.
L>Сорри, не распарсил.
Я о том что в качестве Information Expert можно было выбрать набор действующих скидок, а не набор продуктов. Т.е. паттерн Information Expert нам опять таки не дает однозначности. Согласно этому паттерну у нас ответственность можно однозначно назначить Order-у только в случае полного отсутствия системы скидок. И то, имхо, такое действие будет неправильным. Пусть ордер предоставит набор позиций, а сложить их можно левой пяткой по месту использования суммы.
Здравствуйте, samius, Вы писали:
L>>Сорри, не распарсил.
S>Я о том что в качестве Information Expert можно было выбрать набор действующих скидок, а не набор продуктов.
Да я как бы и не спорю. Я отвечал исключительно на вопрос "непонятно откуда он взялся вообще".
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, samius, Вы писали:
S>>Я о том что в качестве Information Expert можно было выбрать набор действующих скидок, а не набор продуктов.
L>Да я как бы и не спорю. Я отвечал исключительно на вопрос "непонятно откуда он взялся вообще".
Да, я понял.
Здравствуйте, -VaS-, Вы писали:
VS>Вопрос с подвохом Нормальный OOD — как минимум, соблюдение SOLID.
SOLID, он тоже не без вопросов. В частности, S, по большому счету, уже содержит I, О надо применять очень аккуратно, а D штука довольно специфическая и имеющая нехилые побочные эффекты. Так что я бы от SOLID только S и L оставил в качестве обязательных.
... << RSDN@Home 1.2.0 alpha 5 rev. 1530 on Windows 7 6.1.7601.65536>>
Здравствуйте, Lloyd, Вы писали:
L>Вот я чем дольше работаю, тем меньше вижу ентое ООП. L>Более того, очень многими неглупыми людьми ставится под сомнение его полезность. Все народ от того же насквозь оопшного DDD плюется, а вот вполне из себя процедурный anemic model вызывает массу положительных эмоций.
Чем больше работаю, тем больше вижу ООП. Если раньше в основном использовал процедурный подход, в котором одни функции вызывают другие, что образует между ними жесткую связь, и количество этих связей плодится в геометрической прогрессии, что неминуемо сказывается на поддерживаемости и скорости развития проекта, то теперь все разложено по объектам, каждый из которых:
1. Имеет свой определенный контракт.
2. Делает свою конкретную работу и ни байта больше, все посторонние действия делегируются соотв. объектам.
На выходе имеем комбинацию этих объектов, как комбинация рабочих на конвеере, каждый из которых делает какое-то небольшое дело, а на выходе — готовый продукт. Захотели — уволили кого-то, поставили людей лучшей квалификации, захотели — поменяли схему сборки узлов на более оптимальную, захотели — выпустили рестайлинговую версию, заменив определенные узлы на более совершенные. Процесс гибок и легко поддается изменению, не влияя на другие компоненты. При этом работу любой части можно проверить автономно, т.к. у нее нет никакой зависимости ни от кого.
Тогда как как процедурный подход сродни ручному управлению, что неэффективно и должно быть забыто как страшный сон.
Здравствуйте, michael_isu, Вы писали:
_>Тогда как как процедурный подход сродни ручному управлению, что неэффективно и должно быть забыто как страшный сон.
Для начала прочитайте, о чем идет речь. Что такое анемик и рич, и увидете, что минус поставили совершенно зря.
Здравствуйте, licedey, Вы писали:
L>Вы все правильно написало. Однако хотелось бы несколько пометок сделать. Язык не должен быть таким сложным как плюсы. Не при каком раскладе. Это что называется попал в нужное время в нужное место. ГУИ нужен, Сишного кода море, а вот тебе и абстрактность во всей ее красе. struct window {}; make_window_visible хуже ведь Class Window { void Show(); void Hide(); }; Для человека.
Аналогия: кирпич — это сложный строительный материал? в руках хорошего строителя из него будет создано добротное здание, которое простоит не одну сотню лет, и может быть будет считаться шедевром инженерной мысли. А можно сделать джамшутами тяп-ляп, будет отсыревать, пропускать холод, портить ремонт внутри, который чаще придется делать, портить твое здоровье, чаще ходить к врачу Но виноват ли в этом кирпич?
L>Тут как говорится, смешались люди кони. От меня требуют (ну впрочем я и сам привык), писать движок антивируса в ООП-стиле. Т.е. сканирование файла — класс. Загрузка сигнатур — класс. Настройки класс. Разновидности сканирование (память, реестр, мбр) — наследование абстрактного класса ScanTask. Вопрос Зачем? И почему наряду со знание базовых знаний (структуры данных, алгоритмы), знай шаблоны проектирования.
Затем, чтобы сделать отдельные части приложения независимыми друг от друга. Т.к. при развитии проекта, изменении требований и т.п. велик риск, что затронув одну часть кода, поломаете другую. Поломаете
L>Есть же задачи (большинство их), где ООП замедляет процесс разработки. Иногда ломаешь голову, чтобы подогнать компоненты системы под иерархию наследования. Или вся эта виртуальность. Ну библиотечное это все течение. Я уже отписывал на хабре, что С++ для реализации задач и С++ для библиотек — это разные языки. Можно сказать, что первое — это повседневный язык студента, а второй преподавателя.
Иерархия наследования к ООП никакого отношения не имеет. Она имеет отношение к людям, любящим иерархии наследования, квалификация которых априори низка, иначе бы они не делали иерархии
L>Я негодую....А еще этот ворох старья тянущейся с 70-ых годов...
Нет там старья, там есть все для счастливой жизни. Нужно просто овладеть предметом.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Ikemefula, Вы писали:
L>>>ты сейчас с кем разговаривал? причем тут все это?
I>>"модель данных меняется намного реже модели обработки этих данных" @
I>>Вроде как очевидная фраза а тебя понесло непойми куда
L>Это тебя понесло непойми куда. Прочитай определение уже и пойми, что твое разделение модели данных и кода обработки ее и есть уход от ООП в его классичесом определении ("data structures consisting of data fields and methods together with their interactions").
S>The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design; which is to combine data and process together. The anemic domain model is really just a procedural style design, exactly the kind of thing that object bigots like me (and Eric) have been fighting since our early days in Smalltalk.
У Фаулера каша в голове. Тоже начитался определений из википедии.
Здравствуйте, Lloyd, Вы писали:
L>Это не объекты без состояния, у них адрес есть.
"Адрес" объекта не является частью его состояния.
Предлагаю также отказаться от злоупотребления термином "адрес" в этой ветке, т.к. он неявно подразумевает наличие информации о размещении объекта в памяти, и некоторую специальную алгебру над указателями. Это не является фундаментальной частью ООП.
Лучше рассуждать в терминах ссылок, алгебра которых значительно проще.
С точки зрения ООП, identity включает в себя
— возможность иметь ссылку на объект
— возможность сравнить две ссылки между собой на равенство и установить, таким образом, идентичность объекта.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали: S>Не согласен. S>Сравнение ссылок (при отсутствии оператора сравнения) дает нам ссылочную эквивалентность; вызов Equals дает нам эквивалентность по умолчанию; Comparison<T> дает нам любую другую эквивалентность. В то время как идентичность обусловлена идентичным поведением.
Не имеет смысла не соглашаться с определением. Идентичность специально определена отдельно от эквивалентности, и никакого отношения к идентичности поведения не имеет.
Идентичность обеспечивает нам возможность взаимодействовать с конкретным объектом.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Если ты под идентичностью подразумеваешь возможность сказать что a1 и a2 это в точности тот же самый объект, занимающий ту же самую память, то identity с википедии точно не про это.
Слова про занимание памяти нужно выкинуть, а в остальном identity именно про это. S>Надо сперва разобраться с тем, что подразумевать под identity, способ идентифицировать объект с точностью до экземпляра, либо с точностью до поведения. Вики говорит об поведении, допуская множество объектов с same identity.
Где именно вики говорит о множестве объектов с same identity? Нет такого.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали: S>Если к отсутствию состояния добавить требование детерминированности, то у однотипных объектов поведение будет неотличимо, т.е. их идентичность не может быть опровергнута. А раз так — нет оснований их считать неидентичными. Это абсолютная аналогия объектам, расшаривающим общее состояние. Разница может быть выявлена лишь с помощью сравнения ссылок, что нельзя отнести к поведению объекта.
S>детерминированность достаточное требование, но не необходимое. Объект-обертку(без состояния) над статическим методом Console.ReadLine() можно считать идентичным другому такому же объекту.
Нет. Можно считать его эквивалентным. Идентичным считать его не получится — по определению идентичности. Идентичность позволяет всегда отличить объект от других объектов. Независимо от наличия или отсутствия состояния. И даже поведения.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
L>Разве 2 объекта с одинаковым контрактом и без состояния можно как-то отличить?
Да, благодаря наличию identity.
Пример привели по соседству. На самом деле не нужен даже специальный класс:
var a = new object();
var b = new object();
var c = a;
Debug.Assert(a == c);
Debug.Assert(a != b);
Одинаковость контракта обеспечивается тем, что все объекты — одного класса.
Состояния у объектов нет. Проверить это утверждение можно следующим образом:
1. состояние объекта в ООП определяется по его поведению.
2. т.е. о различиях в состоянии объекта можно судить по различиям его реакции на различные сообщения
3. Какие бы вызовы мы ни выполняли на объектах a и b, их результаты всегда будут оставаться одними и теми же.
Формально тут есть некоторая сложность, связанная с тем, что мы делаем всеобщее утверждение, которое невозможно доказать никаким количеством примеров. Неформально мы поступим наоборот — выполним акт веры, примем утверждение за истинное, и подождём опровержения .
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Если ты под идентичностью подразумеваешь возможность сказать что a1 и a2 это в точности тот же самый объект, занимающий ту же самую память, то identity с википедии точно не про это. S>Слова про занимание памяти нужно выкинуть, а в остальном identity именно про это. S>>Надо сперва разобраться с тем, что подразумевать под identity, способ идентифицировать объект с точностью до экземпляра, либо с точностью до поведения. Вики говорит об поведении, допуская множество объектов с same identity. S>Где именно вики говорит о множестве объектов с same identity? Нет такого.
http://en.wikipedia.org/wiki/Identity_(object-oriented_programming)#Consequences_of_identity
If the references do not compare equal, then it's not necessarily guaranteed that the identity of the objects behind those references is different.
The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
Оба процитированных следствия подразумевают возможность существования различных объектов с same identity.
Здравствуйте, samius, Вы писали:
S>http://en.wikipedia.org/wiki/Identity_(object-oriented_programming)#Consequences_of_identity S>If the references do not compare equal, then it's not necessarily guaranteed that the identity of the objects behind those references is different. S>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>Оба процитированных следствия подразумевают возможность существования различных объектов с same identity.
Нет. Первый фрагмент просто говорит о том, что бывают различные ссылки на один и тот же объект — читайте внимательно.
Классический пример — указатели в сегментированной модели памяти, используемые в качестве ссылок. Там можно иметь два битово различных указателя в одно и то же место.
В большинстве практических случаев ссылки можно использовать в качестве критерия идентичности.
Второй фрагмент говорит о том, что все изменения, применяемые к "одному объекту" также отражаются и на "другом". С точки зрения реализации, это может применяться для, к примеру, работы в распределённой среде. С точки зрения математики, все эти "объекты" — один и тот же объект.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>http://en.wikipedia.org/wiki/Identity_(object-oriented_programming)#Consequences_of_identity S>>If the references do not compare equal, then it's not necessarily guaranteed that the identity of the objects behind those references is different. S>>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>>Оба процитированных следствия подразумевают возможность существования различных объектов с same identity. S>Нет. Первый фрагмент просто говорит о том, что бывают различные ссылки на один и тот же объект — читайте внимательно.
я считаю что там написано не об этом (см. ниже).
S>Классический пример — указатели в сегментированной модели памяти, используемые в качестве ссылок. Там можно иметь два битово различных указателя в одно и то же место. S>В большинстве практических случаев ссылки можно использовать в качестве критерия идентичности.
S>Второй фрагмент говорит о том, что все изменения, применяемые к "одному объекту" также отражаются и на "другом". С точки зрения реализации, это может применяться для, к примеру, работы в распределённой среде. С точки зрения математики, все эти "объекты" — один и тот же объект.
Это различные объекты с same identity. Паттерн monostate работает и без распределенной среды.
There are two varieties of identity. There is internal identity, and there is external identity. Internal identity is logical identity. External identity is physical identity. Internal identity is independent of context. External identity is not.
A data tuple has a logical identity according to its value(s). We can copy it to different places. We can duplicate it as many times as we like. Yet at all times we can identify it, by its value. Since we identify it by its value, we can say that this identity is internal. Furthermore we can say that this identity is logical. It is independent of the physical context or representation. If it is duplicated then it is still the same object.
В вики описана именно логическая идентичность, я уверен в этом. Во всяком случае с точки зрения логической идентичности, описанное в вики не противоречит моему пониманию вики. А с точки зрения физической идентичности приходится в концептуальную модель вводить неравные ссылки на один объект, что бы написанное в вики было похоже на правду.
В отношении классических изменяемых объектов (не расшаривающих состояние) понятия логической и физической идентичности эквивалентны. Т.е. из одной вытекает другая и наоборот. Возможно по этой причине варианты идентичности не разделяют.
С неизменяемыми объектами логическая эквивалентность шире физической. Их невозможно отличить, не сравнивая физическое расположение или ссылки (которые не являются атрибутом объекта). Потому следует рассматривать изменяемые объекты и их идентичность как частный случай идентичности.
Здравствуйте, michael_isu, Вы писали:
L>>Потому что имеем разнесение данных и способов работы с ними. Может "процедурный" и не самое удачное слово, но вот "ООП" уж тут точно ни в какие ворота.
_>ООП — это только поведение. Данные там вообще ортогональны.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Верно, а в ООП объекты идентифицируются по поведению. G>>Нет, идентифицируемость объекта ортогонально поведению. Фактически возможность узнать являются ли два объекта идентичными (не путать с эквивалентностью). Свойство идентичности нельзя нарушить, в отличие от эквивалентности, которое может зависеть от состояния. S>Если ты под идентичностью подразумеваешь возможность сказать что a1 и a2 это в точности тот же самый объект, занимающий ту же самую память, то identity с википедии точно не про это.
Я конкретно про современные языки и реализацию ООП в них.
S>>>Не получить, но это не делает ссылку атрибутом объекта. Тем более, что объект без ссылки в дотнете существовать может (недетерминированное время). G>>Нет, может существовать память объекта, но не сам объект, потому что объект — identity+поведение. Если на объект нет ссылок, то фактически у него нет ни identity и нету способов получить поведение. G>>Не стоит путать концептуальные вещи с деталями реализации. Ведь в .NET value-типы наследуются от Object, но это не значит что для каждого value-типа есть указатель на VMT. S>Надо сперва разобраться с тем, что подразумевать под identity, способ идентифицировать объект с точностью до экземпляра, либо с точностью до поведения. Вики говорит об поведении, допуская множество объектов с same identity. Есть более компетентные источники с противоположным мнением?
Ты опять концепцию с реализацией путаешь. Может быть где-то и есть реализации где для идентичности не обязательно совпадение ссылок, но я таких не видел.
S>>>т.е. согласно выделенному — из отсутствия равенства ссылок не следует различная идентифицируемость. G>>Да, потому что это деталь реализации. S>Это общая концепция.
Я неправильно выразился. Конкретная реализация работает на сравнении ссылок, других я не видел.
S>>>В том числе в C#. G>>Нет, ты не можешь в C# получить пару объектов reference типа для которых object.ReferenceEquals(a,b) == true, но a.Equals(b) == false, если нормально реализован Equals. Более того гайдлайн требует чтобы реализация equals была такова что идентичные объекты будут эквивалентны. На это и опирается ООП. S>ООП опирается на понятие identity. А Equals — это особенности реализации эквивалентности в дотнете. S>Качество реализации Equals влияет на работу с этим объектом средствами фреймворка, но не влияет на концептуальные качества объекта, не относящиеся к платформе.
S>>>Если identity принимается за паспорт, то при разных паспортах мы получим разное identity. Из этого следует что экземпляры разные. Верно. Но из того что паспорта одинаковы не будет следовать что экземпляр один. G>>Ну возьми SSN\СНИЛС, он не меняется. S>Не имеет смысла обсуждать без согласования термина identity.
Indentity — возможность узнать что a1 и a2 — один и тот же объект, и это свойство не изменяется со временем. В отличие от эквивалентности двух разных объектов a1 и a2, когда a1.Equals(a2) зависит от состояния a1 и a2.
S>>>Это как если в дотнете взять две строки с одинаковым содержимым (пусть будут получены разным способом, что бы избежать скидки на интернирование). Поведение одинаково. о них говорят same identity, даже если ссылки будут отличаться. G>>Где говорят? Ссылку дай что ли. То что на equal string говорят same identity не делает чести тому кто говорит. S>Не знаю, где говорят, но я сделал такой вывод на основании статьи в вики.
То есть так только ты говоришь?
G>>И уж точно никак не влияет на соотношение identity и equal в ООП. S>не влияет, т.к. между ними мало общего, учитывая то, что эквивалентность — понятие навесное. Никто не может мне запретить считать эквивалентными людей с одной фамилией при различном их поведении.
Да считай, твое дело. Главное чтобы идентичные объекты всегда были эквивалентны, тогда будет ООП.
Здравствуйте, Lloyd, Вы писали: L>Опа, а откуда еще классы нарисовались?
Оттуда, что пример — на C#. В терминах дотнета контракт объекта определяется классом, которому он принадлежит.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Lloyd, Вы писали: L>>Опа, а откуда еще классы нарисовались? S>Оттуда, что пример — на C#. В терминах дотнета контракт объекта определяется классом, которому он принадлежит.
Хорошо, выкрутился.
А как будет выглядеть identity для COM-а, например? Там QueryInterface вполне может вернуть разные адреса.
Identity тут все еще будет применимо или же COM с ООП не совсем совместим?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Если ты под идентичностью подразумеваешь возможность сказать что a1 и a2 это в точности тот же самый объект, занимающий ту же самую память, то identity с википедии точно не про это.
G>Я конкретно про современные языки и реализацию ООП в них.
А я про концептуальную модель, которой современные языки не противоречат.
S>>Надо сперва разобраться с тем, что подразумевать под identity, способ идентифицировать объект с точностью до экземпляра, либо с точностью до поведения. Вики говорит об поведении, допуская множество объектов с same identity. Есть более компетентные источники с противоположным мнением?
G>Ты опять концепцию с реализацией путаешь. Может быть где-то и есть реализации где для идентичности не обязательно совпадение ссылок, но я таких не видел.
A reference contains the information that is necessary for the identity property to be realized in the programming language, and allows access to the object with the identity. (вики)
ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity).
S>>>>т.е. согласно выделенному — из отсутствия равенства ссылок не следует различная идентифицируемость. G>>>Да, потому что это деталь реализации. S>>Это общая концепция. G>Я неправильно выразился. Конкретная реализация работает на сравнении ссылок, других я не видел.
Из равенства ссылок следует same identity. Т.е. увидеть что объекты идентичны можно по равенству ссылок. Из неравенство ссылок неравенство identity следует лишь в частном случае — в случае изменяемых объектов.
S>>Не имеет смысла обсуждать без согласования термина identity. G>Indentity — возможность узнать что a1 и a2 — один и тот же объект, и это свойство не изменяется со временем. В отличие от эквивалентности двух разных объектов a1 и a2, когда a1.Equals(a2) зависит от состояния a1 и a2.
Верно. Но http://c2.com/cgi/wiki?ObjectIdentity описывает два варианта — логическую и физическую identity. В вики описана логическая. Я о ней. Ты, похоже, о физической.
G>>>Где говорят? Ссылку дай что ли. То что на equal string говорят same identity не делает чести тому кто говорит. S>>Не знаю, где говорят, но я сделал такой вывод на основании статьи в вики. G>То есть так только ты говоришь?
Такая формулировка слишком сильная. Я не слышал, что бы кто-то еще так говорил. Но что так говорят я сделал вывод из написанного в вики. Переформулирую, что бы избежать неоднозначности в трактовке identity:
Разные экземпляры строки (в дотнете) с одинаковым содержимым (по Ordinal типу сравнения) будут обладать same logical identity. Иначе говоря, доказать что они отличны будет невозможно, не сравнивая физические адреса, ссылки, и не портя память.
S>>не влияет, т.к. между ними мало общего, учитывая то, что эквивалентность — понятие навесное. Никто не может мне запретить считать эквивалентными людей с одной фамилией при различном их поведении. G>Да считай, твое дело. Главное чтобы идентичные объекты всегда были эквивалентны, тогда будет ООП.
Можно ссылку?
Вообще это не всегда выполняется. Из логической идентичности ссылочная эквивалентность не следует.
S>ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity).
Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю.
S>>>>>т.е. согласно выделенному — из отсутствия равенства ссылок не следует различная идентифицируемость. G>>>>Да, потому что это деталь реализации. S>>>Это общая концепция. G>>Я неправильно выразился. Конкретная реализация работает на сравнении ссылок, других я не видел. S>Из равенства ссылок следует same identity. Т.е. увидеть что объекты идентичны можно по равенству ссылок. Из неравенство ссылок неравенство identity следует лишь в частном случае — в случае изменяемых объектов.
Ты опять путаешь identity и equals.
Закрой вики и попробуй придумать что такое идентифицируемость и эквивалентность, и чем эти понятия отличаются.
S>>>Не имеет смысла обсуждать без согласования термина identity. G>>Indentity — возможность узнать что a1 и a2 — один и тот же объект, и это свойство не изменяется со временем. В отличие от эквивалентности двух разных объектов a1 и a2, когда a1.Equals(a2) зависит от состояния a1 и a2. S>Верно. Но http://c2.com/cgi/wiki?ObjectIdentity описывает два варианта — логическую и физическую identity. В вики описана логическая. Я о ней. Ты, похоже, о физической.
Физическая identity — это и есть идентичность (не меняется со временем), "логическая" identity — эквивалентность.
Проблема возникла из C++ и подобных языков. Там ссылка не является неотъемлимым атрибутом объекта и identity для объектов на стеке нет. Различное понимание идентичности в с++ и том же smalltalk привело к тому что понятия identity и equals перемешались.
G>>>>Где говорят? Ссылку дай что ли. То что на equal string говорят same identity не делает чести тому кто говорит. S>>>Не знаю, где говорят, но я сделал такой вывод на основании статьи в вики. G>>То есть так только ты говоришь? S>Такая формулировка слишком сильная. Я не слышал, что бы кто-то еще так говорил. Но что так говорят я сделал вывод из написанного в вики. Переформулирую, что бы избежать неоднозначности в трактовке identity: S>Разные экземпляры строки (в дотнете) с одинаковым содержимым (по Ordinal типу сравнения) будут обладать same logical identity. Иначе говоря, доказать что они отличны будет невозможно, не сравнивая физические адреса, ссылки, и не портя память.
Это называется эквивалентностью.
S>>>не влияет, т.к. между ними мало общего, учитывая то, что эквивалентность — понятие навесное. Никто не может мне запретить считать эквивалентными людей с одной фамилией при различном их поведении. G>>Да считай, твое дело. Главное чтобы идентичные объекты всегда были эквивалентны, тогда будет ООП. S>Можно ссылку?
На что?
S>Вообще это не всегда выполняется. Из логической идентичности ссылочная эквивалентность не следует.
Покажи пример.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity). G>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю.
Для C# две строки с одинаковым содержимым.
S>>Из равенства ссылок следует same identity. Т.е. увидеть что объекты идентичны можно по равенству ссылок. Из неравенство ссылок неравенство identity следует лишь в частном случае — в случае изменяемых объектов. G>Ты опять путаешь identity и equals. G>Закрой вики и попробуй придумать что такое идентифицируемость и эквивалентность, и чем эти понятия отличаются.
Придумать я могу все что угодно, что приведет к проблеме при общении со мной. Мне важно знать что я под термином понимаю именно то, что понимают другие. Для этого я открываю вики и шарюсь по книжкам.
S>>>>Не имеет смысла обсуждать без согласования термина identity. G>>>Indentity — возможность узнать что a1 и a2 — один и тот же объект, и это свойство не изменяется со временем. В отличие от эквивалентности двух разных объектов a1 и a2, когда a1.Equals(a2) зависит от состояния a1 и a2. S>>Верно. Но http://c2.com/cgi/wiki?ObjectIdentity описывает два варианта — логическую и физическую identity. В вики описана логическая. Я о ней. Ты, похоже, о физической. G>Физическая identity — это и есть идентичность (не меняется со временем), "логическая" identity — эквивалентность.
логическая идентичность и эквивалентность — это разные термины.
Ссылочная эквивалентность эквивалентна физической идентичности.
Структурная эквивалентность логической идентичности не экивалентна. Пример:
возмьмем объекты
class A { public string Name { get; set; } }
var a = new A { Name = "a"; }
var b = new A { Name = "a"; }
a и b структурно эквивалентны, но логически не идентичны, что можно увидеть, присвоив a.Name другое значение и обнаружив что в b.Name осталось прежнее значение.
G>Проблема возникла из C++ и подобных языков. Там ссылка не является неотъемлимым атрибутом объекта и identity для объектов на стеке нет. Различное понимание идентичности в с++ и том же smalltalk привело к тому что понятия identity и equals перемешались.
Я их отличаю, см. пример выше.
S>>Разные экземпляры строки (в дотнете) с одинаковым содержимым (по Ordinal типу сравнения) будут обладать same logical identity. Иначе говоря, доказать что они отличны будет невозможно, не сравнивая физические адреса, ссылки, и не портя память. G>Это называется эквивалентностью.
см. пример выше.
Для строк доказать их логическую неидентичность невозможно.
G>>>Да считай, твое дело. Главное чтобы идентичные объекты всегда были эквивалентны, тогда будет ООП. S>>Можно ссылку? G>На что?
На то что для существования ООП нужно что бы идентичные объекты всегда были эквивалентны. Откуда это?
S>>Вообще это не всегда выполняется. Из логической идентичности ссылочная эквивалентность не следует. G>Покажи пример.
пример с двумя строками равного содержимого.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity). G>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю. S>Для C# две строки с одинаковым содержимым.
Они эквивалентны, но не идентичны.
S>>>Из равенства ссылок следует same identity. Т.е. увидеть что объекты идентичны можно по равенству ссылок. Из неравенство ссылок неравенство identity следует лишь в частном случае — в случае изменяемых объектов. G>>Ты опять путаешь identity и equals. G>>Закрой вики и попробуй придумать что такое идентифицируемость и эквивалентность, и чем эти понятия отличаются. S>Придумать я могу все что угодно, что приведет к проблеме при общении со мной. Мне важно знать что я под термином понимаю именно то, что понимают другие. Для этого я открываю вики и шарюсь по книжкам.
Тем не менее надо думать головой. Вики и книги пишут люди и им свойственно ошибаться.
Вот есть два понятия: эквивалентность и идентичность. Придумай им формальные определения (разные определения).
S>логическая идентичность и эквивалентность — это разные термины.
Чем разные?
S>Ссылочная эквивалентность эквивалентна физической идентичности. S>Структурная эквивалентность логической идентичности не экивалентна. Пример: S>возмьмем объекты S>
S>class A { public string Name { get; set; } }
S>var a = new A { Name = "a"; }
S>var b = new A { Name = "a"; }
S>
S>a и b структурно эквивалентны, но логически не идентичны, что можно увидеть, присвоив a.Name другое значение и обнаружив что в b.Name осталось прежнее значение.
То что они "структурно эквивалентны" C# не знает, там нет такого понятия.
В данном случае Object.ReferenceEquals(a,b) == false и a.Equals(b) == false. Других формальных утверждений про данный код ты сделать не можешь.
Ты ничего не доказал.
G>>Проблема возникла из C++ и подобных языков. Там ссылка не является неотъемлимым атрибутом объекта и identity для объектов на стеке нет. Различное понимание идентичности в с++ и том же smalltalk привело к тому что понятия identity и equals перемешались. S>Я их отличаю, см. пример выше.
Пример твой ничего не доказывает.
S>>>Разные экземпляры строки (в дотнете) с одинаковым содержимым (по Ordinal типу сравнения) будут обладать same logical identity. Иначе говоря, доказать что они отличны будет невозможно, не сравнивая физические адреса, ссылки, и не портя память. G>>Это называется эквивалентностью. S>см. пример выше. S>Для строк доказать их логическую неидентичность невозможно.
Я не понимаю уже что такое логическая идентичность. Как она в языке выражается? Если никак, то её нет, или ты просто ошибся с понятием.
G>>>>Да считай, твое дело. Главное чтобы идентичные объекты всегда были эквивалентны, тогда будет ООП. S>>>Можно ссылку? G>>На что? S>На то что для существования ООП нужно что бы идентичные объекты всегда были эквивалентны. Откуда это? http://msdn.microsoft.com/en-us/library/system.object.equals.aspx
Для любого другого языка с возможность переопределить equals можно найти подобные правила.
S>>>Вообще это не всегда выполняется. Из логической идентичности ссылочная эквивалентность не следует. G>>Покажи пример. S>пример с двумя строками равного содержимого.
Они эквивалентны, но не идентичны.
S>>The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design; which is to combine data and process together. The anemic domain model is really just a procedural style design, exactly the kind of thing that object bigots like me (and Eric) have been fighting since our early days in Smalltalk.
_>У Фаулера каша в голове. Тоже начитался определений из википедии.
Дело не в Википедии, а в том, что для ООП начисто отсутствует общепринятая терминология и фундаментальная база. Классики ООП как минимум две — Симула и Алана Кея. Каждая из этих классик имеет развитие. По большому счету нет ни одного принципа ООП, который не вызывал бы бурных споров, взять тот же SRP.
Что касается "каши" у Фаулера, то его взгляды разделяет достаточно большая часть людей в этом топике и хотя бы по этому не все так однозначно
Здравствуйте, Lloyd, Вы писали: L>Хорошо, выкрутился. L>А как будет выглядеть identity для COM-а, например? Там QueryInterface вполне может вернуть разные адреса. L>Identity тут все еще будет применимо или же COM с ООП не совсем совместим?
В COM для проверки идентичности надо запрашивать всегда IUnknown.
Remarks
For any one object, a specific query for the IUnknown interface on any of the object's interfaces must always return the same pointer value. This enables a client to determine whether two pointers point to the same component by calling QueryInterface with IID_IUnknown and comparing the results. It is specifically not the case that queries for interfaces other than IUnknown (even the same interface through the same pointer) must return the same pointer value.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Sinclair, Вы писали:
S>>Здравствуйте, Lloyd, Вы писали: L>>>Опа, а откуда еще классы нарисовались? S>>Оттуда, что пример — на C#. В терминах дотнета контракт объекта определяется классом, которому он принадлежит.
L>Хорошо, выкрутился. L>А как будет выглядеть identity для COM-а, например? Там QueryInterface вполне может вернуть разные адреса.
И пусть возвращает разные, но это ссылки на один объект.
Как уже писал Синклер понятие "адреса" тут лишнее и только вводит в заблуждение, лучше оперировать ссылками.
Кстати QueryInterface(IUknown) для одного объекта обязанвсегда возвращать один адрес.
Выделенное — требование к реализации COM.
L>Identity тут все еще будет применимо или же COM с ООП не совсем совместим?
Как видишь очень даже совместим. COM может быть не совместим с реализацией идентичности на конкретном языке. Например C++, где мы можем явно оперировать адресами.
Здравствуйте, gandjustas, Вы писали:
S>>Это не одно и то же, т.к. адрес объекта или ссылка на объект — это не внутренний атрибут объекта и он не имеет отношения к поведению объекта в общем случае. G>Да ну? Покажи как в C# получить ссылку отдельно от самого объекта?
В C# этого нет в языке, но при этом в дотнет есть такой тип — ссылки. Т.е. это вопрос только конкретного языка.
S>>Наоборот, получив отрицательный результат сравнения ссылок на равенство, можно делать вывод лишь о том что мы имеем разные экземпляры. Но идентичность этим самым не опровергнута. G>Еще раз, не идентичность, а идентифицируемость. В C# для объектов reference-типов идентифицируемость по ссылке.
Здесь под идентичностью пониматся не идентичность а идентифицируемость, надо бы уже привыкнуть
G>Метафора identity — паспорт. Если два человека выглядят и ведут себя одинаково, но у них разные паспорта, то это разные люди. Если один паспорт — то это один человек.
А если паспорт заменили, то это уже будет другой человек что ли ?
Здравствуйте, samius, Вы писали: G>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю. S>Для C# две строки с одинаковым содержимым.
Нет, это не так. Опровергнуть идентичность этих строк можно, правда для этого придётся выйти в unsafe. S>Придумать я могу все что угодно, что приведет к проблеме при общении со мной. Мне важно знать что я под термином понимаю именно то, что понимают другие. Для этого я открываю вики и шарюсь по книжкам.
Пока что ты понимаешь под термином идентичность совсем не то, что понимают все остальные. И пытаешься углядеть в вики скрытый смысл, которого там нет.
S>Ссылочная эквивалентность эквивалентна физической идентичности.
Нет. В частном случае COM, который тут по соседству упомянули, ссылочная эквивалентность не эквивалентна физической идентичности (даже если мы введём этот термин строгим образом).
"Физически идентичный" объект может иметь две различные ссылки — It is specifically not the case that queries for interfaces other than IUnknown (even the same interface through the same pointer) must return the same pointer value.
S>На то что для существования ООП нужно что бы идентичные объекты всегда были эквивалентны. Откуда это?
Эм-м, с точки зрения математики эквивалентностью может быть любое симметричное транзитивное рефлексивное отношение. Это понятно?
Из рефлексивности следует, что объект всегда эквивалентен сам себе.
А поскольку объекты с одинаковой идентичностью — это один и тот же объект, то объекты с одинаковой идентичностью эквивалентны.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю. S>>Для C# две строки с одинаковым содержимым.
G>Они эквивалентны, но не идентичны.
Можешь это доказать? Строго, делая верифицируемые выкладки из определения. Только без догадок о том что физический адрес это атрибут объекта.
S>>Придумать я могу все что угодно, что приведет к проблеме при общении со мной. Мне важно знать что я под термином понимаю именно то, что понимают другие. Для этого я открываю вики и шарюсь по книжкам. G>Тем не менее надо думать головой. Вики и книги пишут люди и им свойственно ошибаться.
Придумывать свои определения — это прямая дорога к непониманию. G>Вот есть два понятия: эквивалентность и идентичность. Придумай им формальные определения (разные определения).
Я не придумываю определения, я ими пользуюсь.
S>>логическая идентичность и эквивалентность — это разные термины. G>Чем разные?
Обозначают разные вещи.
S>>a и b структурно эквивалентны, но логически не идентичны, что можно увидеть, присвоив a.Name другое значение и обнаружив что в b.Name осталось прежнее значение. G>То что они "структурно эквивалентны" C# не знает, там нет такого понятия.
Я могу определить отношение экивалентности классов A и реализовать его формально и математически строго. G>В данном случае Object.ReferenceEquals(a,b) == false и a.Equals(b) == false. Других формальных утверждений про данный код ты сделать не можешь. G>Ты ничего не доказал.
Я показал что эквивалентность и идентичность могут обозначать разные вещи.
S>>Для строк доказать их логическую неидентичность невозможно. G>Я не понимаю уже что такое логическая идентичность. Как она в языке выражается?
Никак G>Если никак, то её нет, или ты просто ошибся с понятием.
Это следствие не верифицируемо
S>>На то что для существования ООП нужно что бы идентичные объекты всегда были эквивалентны. Откуда это? G>http://msdn.microsoft.com/en-us/library/system.object.equals.aspx G>Для любого другого языка с возможность переопределить equals можно найти подобные правила.
Эти правила требуют формального соответствия вводимому отношению эквивалентности математическому понятию отношения эквивалентности, т.к. фреймворк в своей работе полагается на свойства отношения эквивалентности (рефлексивность, транзитивности, симметричность + кое-что из floating-point специфики). Рефлексивность требует что бы объект был эквивалентен самому себе. Но ни слова об идентичности.
Твоя ссылка не доказывает твоего утверждения.
S>>>>Вообще это не всегда выполняется. Из логической идентичности ссылочная эквивалентность не следует. G>>>Покажи пример. S>>пример с двумя строками равного содержимого. G>Они эквивалентны, но не идентичны.
Докажи что логически не идентичны.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: G>>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю. S>>Для C# две строки с одинаковым содержимым. S>Нет, это не так. Опровергнуть идентичность этих строк можно, правда для этого придётся выйти в unsafe.
Выйдя в unsafe можно опровергнуть идентичность строки самой себе.
S>>Придумать я могу все что угодно, что приведет к проблеме при общении со мной. Мне важно знать что я под термином понимаю именно то, что понимают другие. Для этого я открываю вики и шарюсь по книжкам. S>Пока что ты понимаешь под термином идентичность совсем не то, что понимают все остальные.
вижу S>И пытаешься углядеть в вики скрытый смысл, которого там нет.
Еще как минимум один источник говорит о наличии логической идентичности. AFAIR, вы на него ссылались весной.
S>>Ссылочная эквивалентность эквивалентна физической идентичности. S>Нет. В частном случае COM, который тут по соседству упомянули, ссылочная эквивалентность не эквивалентна физической идентичности (даже если мы введём этот термин строгим образом). S>"Физически идентичный" объект может иметь две различные ссылки — It is specifically not the case that queries for interfaces other than IUnknown (even the same interface through the same pointer) must return the same pointer value.
ок, COM особый случай.
S>>На то что для существования ООП нужно что бы идентичные объекты всегда были эквивалентны. Откуда это? S>Эм-м, с точки зрения математики эквивалентностью может быть любое симметричное транзитивное рефлексивное отношение. Это понятно? S>Из рефлексивности следует, что объект всегда эквивалентен сам себе.
Верно S>А поскольку объекты с одинаковой идентичностью — это один и тот же объект
Это справедливо для физической эквивалентности но не для логической. S>, то объекты с одинаковой идентичностью эквивалентны.
с физической — да. Логическая эквивалентность двух различных объектов не ведет к ссылочной эквивалентности.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
S>>>Это не одно и то же, т.к. адрес объекта или ссылка на объект — это не внутренний атрибут объекта и он не имеет отношения к поведению объекта в общем случае. G>>Да ну? Покажи как в C# получить ссылку отдельно от самого объекта? I>В C# этого нет в языке, но при этом в дотнет есть такой тип — ссылки. Т.е. это вопрос только конкретного языка.
Нет. Есть более общее, математическое понятие ссылки. Где-то оно может быть адресом или каким-то другим представлением. Но суть в том что эти ссылки можно сравнить и для идентичных (одинаковых, same) объектов они совпадут.
S>>>Наоборот, получив отрицательный результат сравнения ссылок на равенство, можно делать вывод лишь о том что мы имеем разные экземпляры. Но идентичность этим самым не опровергнута. G>>Еще раз, не идентичность, а идентифицируемость. В C# для объектов reference-типов идентифицируемость по ссылке. I>Здесь под идентичностью пониматся не идентичность а идентифицируемость, надо бы уже привыкнуть
Ниче не понял.
G>>Метафора identity — паспорт. Если два человека выглядят и ведут себя одинаково, но у них разные паспорта, то это разные люди. Если один паспорт — то это один человек. I>А если паспорт заменили, то это уже будет другой человек что ли ?
Еще один умник... Ну возьми не паспорт, а SSN.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Sinclair, Вы писали:
S>>Пока что ты понимаешь под термином идентичность совсем не то, что понимают все остальные. S>вижу S>>И пытаешься углядеть в вики скрытый смысл, которого там нет. S>Еще как минимум один источник говорит о наличии логической идентичности. AFAIR, вы на него ссылались весной.
Прошу прощения, это я ссылался
Здравствуйте, samius, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Здравствуйте, Sinclair, Вы писали:
S>>>Пока что ты понимаешь под термином идентичность совсем не то, что понимают все остальные. S>>вижу S>>>И пытаешься углядеть в вики скрытый смысл, которого там нет. S>>Еще как минимум один источник говорит о наличии логической идентичности. AFAIR, вы на него ссылались весной. S>Прошу прощения, это я ссылался
What makes up the identity of an object in an object-oriented system? A common answer is "object identity" is defined by being in the same spot in memory, which is called "reference equality" and matches Java's == operator. A consequence of this situation is if two objects are identical, a change to one will always affect the other. This distinguishes identity from the notion of "being equal," which can change over time. In fact, multiple notions of being equal are possible, such as String.equals() and String.equalsIgnoreCase().
Using reference equality as the only notion of object identity seems a good solution at first, but unfortunately this point of view is a little naive.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю. S>>>Для C# две строки с одинаковым содержимым.
G>>Они эквивалентны, но не идентичны. S>Можешь это доказать? Строго, делая верифицируемые выкладки из определения. Только без догадок о том что физический адрес это атрибут объекта.
Да
var a = "string";
var b = "string"
Debug.Assert((object)a != (object)b); //(1)
Debug.Assert(Object.Equals(a,b)); //(2)
Очевидно что приведение типа не изменяет объект, таким образом a и b разные объекты (1), то есть не идентичны, но они эквивалентны (2)
S>>>Придумать я могу все что угодно, что приведет к проблеме при общении со мной. Мне важно знать что я под термином понимаю именно то, что понимают другие. Для этого я открываю вики и шарюсь по книжкам. G>>Тем не менее надо думать головой. Вики и книги пишут люди и им свойственно ошибаться. S>Придумывать свои определения — это прямая дорога к непониманию. G>>Вот есть два понятия: эквивалентность и идентичность. Придумай им формальные определения (разные определения). S>Я не придумываю определения, я ими пользуюсь.
В википедии определение откровенно слабое, неформальное.
S>>>логическая идентичность и эквивалентность — это разные термины. G>>Чем разные? S>Обозначают разные вещи.
Ну так приведи определения. Я не понимаю что ты имеешь ввиду под этими разными вещами.
S>>>a и b структурно эквивалентны, но логически не идентичны, что можно увидеть, присвоив a.Name другое значение и обнаружив что в b.Name осталось прежнее значение. G>>То что они "структурно эквивалентны" C# не знает, там нет такого понятия. S>Я могу определить отношение экивалентности классов A и реализовать его формально и математически строго. G>>В данном случае Object.ReferenceEquals(a,b) == false и a.Equals(b) == false. Других формальных утверждений про данный код ты сделать не можешь. G>>Ты ничего не доказал. S>Я показал что эквивалентность и идентичность могут обозначать разные вещи.
В данном случае ты показал два объекта, которые не эквивалентны и не идентичны.
То есть ничего не доказал.
S>>>Для строк доказать их логическую неидентичность невозможно. G>>Я не понимаю уже что такое логическая идентичность. Как она в языке выражается? S>Никак
То есть его просто нет, его нельзя на доказать\ни опровергнуть\и выразить в программе.
S>>>На то что для существования ООП нужно что бы идентичные объекты всегда были эквивалентны. Откуда это? G>>http://msdn.microsoft.com/en-us/library/system.object.equals.aspx G>>Для любого другого языка с возможность переопределить equals можно найти подобные правила. S>Эти правила требуют формального соответствия вводимому отношению эквивалентности математическому понятию отношения эквивалентности, т.к. фреймворк в своей работе полагается на свойства отношения эквивалентности (рефлексивность, транзитивности, симметричность + кое-что из floating-point специфики). Рефлексивность требует что бы объект был эквивалентен самому себе. Но ни слова об идентичности.
Выделенное есть идентичность.
"Эквивалентен самому себе" формально записывается как Object.ReferenceEquals(a, b) == true => a.Equals(b)
Ты только что упоминул то что я тебе уже раз 10 написал.
S>Твоя ссылка не доказывает твоего утверждения.
Прочитай, там явное требование чтобы x.Equals(x) == true, но внутри Equals у тебя две ссылки this и obj. И единственная реализация данного требования делать Object.ReferenceEquals(this, obj), то есть опираться на совпадение ссылок. Причем такое можно найти и для java.
S>>>>>Вообще это не всегда выполняется. Из логической идентичности ссылочная эквивалентность не следует. G>>>>Покажи пример. S>>>пример с двумя строками равного содержимого. G>>Они эквивалентны, но не идентичны. S>Докажи что логически не идентичны.
Я не знаю что такое "логически идентичны", ты не привел определение.
Здравствуйте, gandjustas, Вы писали:
I>>В C# этого нет в языке, но при этом в дотнет есть такой тип — ссылки. Т.е. это вопрос только конкретного языка. G>Нет. Есть более общее, математическое понятие ссылки. Где-то оно может быть адресом или каким-то другим представлением. Но суть в том что эти ссылки можно сравнить и для идентичных (одинаковых, same) объектов они совпадут.
Есть масса способов сделать ссылки побитово различными при этом они будт ссылаться на один и тот же объект.
G>>>Еще раз, не идентичность, а идентифицируемость. В C# для объектов reference-типов идентифицируемость по ссылке. I>>Здесь под идентичностью пониматся не идентичность а идентифицируемость, надо бы уже привыкнуть G>Ниче не понял.
Да вроде всё просто — на этом форуме термин "identity" используется в русском варианте как "идентичность", но означает "идентифицируемость"
То есть как минимум для ООП-тем нужно иметь ввиду, что здесь "идентичность" есть "идентифицируемость".
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>В C# этого нет в языке, но при этом в дотнет есть такой тип — ссылки. Т.е. это вопрос только конкретного языка. G>>Нет. Есть более общее, математическое понятие ссылки. Где-то оно может быть адресом или каким-то другим представлением. Но суть в том что эти ссылки можно сравнить и для идентичных (одинаковых, same) объектов они совпадут.
I>Есть масса способов сделать ссылки побитово различными при этом они будт ссылаться на один и тот же объект.
Ну так и я про то же, поэтому оперируем "математической" ссылкой, которая инварианта битовому представлению и другим особенностям реализации.
Для простоты берем ссылки как в C#, внутрь их влезть нельзя.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>Они эквивалентны, но не идентичны. S>>>Можешь это доказать? Строго, делая верифицируемые выкладки из определения. Только без догадок о том что физический адрес это атрибут объекта.
G>>Да
G>>
G>>var a = "string";
G>>var b = "string"
G>>Debug.Assert((object)a != (object)b); //(1)
G>>Debug.Assert(Object.Equals(a,b)); //(2)
G>>
G>>Очевидно что приведение типа не изменяет объект, таким образом a и b разные объекты (1), то есть не идентичны, но они эквивалентны (2) S>Ты показал отличие ссылочной эквивалентности от эквивалентности, определенной для строки по умолчанию.
То что ты называешь ссылочной эквивалентностью является по идентичностью.
S>К логической идентичности ни то ни другое не имеет отношения.
К логической идентичности ничего не имеет отношения как так ты её выразить не можешь, ни словами ни кодом, ни доказать её отсутствие или присутствие.
S>Давай так. Ты допускаешь существование понятия "логическая идентичность" или ты будешь все время игнорировать "логическая" и подразумевать при этом "физическую идентичность"? Если для тебя нет понятия логической идентичности, то мы просто обсуждаем разные понятия и наши доказательства ни к чему не приведут.
Я вообще будут игнорировать твои понятия пока ты им не приведешь формальные определения. То есть чтобы можно было написать код, который это проверит для любых объектов.
S>>>Я не придумываю определения, я ими пользуюсь. G>>В википедии определение откровенно слабое, неформальное. S>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm S>По ссылке выше три формальных определения. Допускают ли они трактовку, в которой логическая эквивалентность имеет место? Если нет, почему бы там сразу не написано "один и тот же объект"?
Потому что "один и тот же" можно сказать когда есть два объекта. А тут попытались написать определение identity для одного.
S>>>>>логическая идентичность и эквивалентность — это разные термины. G>>>>Чем разные? S>>>Обозначают разные вещи. G>>Ну так приведи определения. Я не понимаю что ты имеешь ввиду под этими разными вещами. S>Ссылку на определения идентичности я дал, отношение эквивалентности — вот
Да нет, меня как раз интересует твое понимание идентичности.
G>>>>В данном случае Object.ReferenceEquals(a,b) == false и a.Equals(b) == false. Других формальных утверждений про данный код ты сделать не можешь. G>>>>Ты ничего не доказал. S>>>Я показал что эквивалентность и идентичность могут обозначать разные вещи. G>>В данном случае ты показал два объекта, которые не эквивалентны и не идентичны. S>Следует добавить в пример реализацию отношения эквивалентности? Я могу это сделать.
Ну, ты сделаешь два экивалентных, но не идентичных объекта.
S>>>>>Для строк доказать их логическую неидентичность невозможно. G>>>>Я не понимаю уже что такое логическая идентичность. Как она в языке выражается? S>>>Никак G>>То есть его просто нет, его нельзя на доказать\ни опровергнуть\и выразить в программе. S>Опровергнуть можно, я показал как.
Ты ничего не показал. Покажи как свойство "логической идентичности" можно выразить в программе.
G>>>>Для любого другого языка с возможность переопределить equals можно найти подобные правила. S>>>Эти правила требуют формального соответствия вводимому отношению эквивалентности математическому понятию отношения эквивалентности, т.к. фреймворк в своей работе полагается на свойства отношения эквивалентности (рефлексивность, транзитивности, симметричность + кое-что из floating-point специфики). Рефлексивность требует что бы объект был эквивалентен самому себе. Но ни слова об идентичности. G>>Выделенное есть идентичность. S>Физическая но не логическая. Перестань игнорировать термины, описание которых я приводил неоднократно. Или мы обсуждаем одну и ту же вещь, либо не обсуждаем вовсе за бессмысленностью.
Чем физическая отличается от логической, приведи код. Рассуждения без кода не нужны.
G>>"Эквивалентен самому себе" формально записывается как Object.ReferenceEquals(a, b) == true => a.Equals(b) S>Object.ReferenceEquals(a,b) не факт что выполняется для логической идентичности. G>>Ты только что упоминул то что я тебе уже раз 10 написал. S>Мы говорим не об одном и том же.
Возможно. Ты придумываешь вещи, которые отсутствуют.
G>>Прочитай, там явное требование чтобы x.Equals(x) == true, но внутри Equals у тебя две ссылки this и obj. И единственная реализация данного требования делать Object.ReferenceEquals(this, obj), то есть опираться на совпадение ссылок. Причем такое можно найти и для java. S>x.Equals(x) — требование рефлексивности. Оно будет удовлетворено и для логической идентичности. Я забыл, о что мы доказывали.
Object.ReferenceEquals(this, obj) это какая идентичность? После этого сразу напиши код для получения другой идентичности.
S>>>Докажи что логически не идентичны. G>>Я не знаю что такое "логически идентичны", ты не привел определение. S>Определения идентичности я приводил.
Формально, код давай. Без кода это пустой треп.
S>Нужно еще формально показать что из него вытекает лишь физическая идентичность и никак не логическая. Покуда это не сделано строго и формально, я считаю что понятие логической идентичности вытекает из определения идентичности. Описание того, что такое логическая идентичность я приводил.
В чем отличия физической и логической идентичности? Кодом.
S>допустим S>
S>"object identity — identity is that property of an object that distinguishes each object from all others" [Khos-86]
S>Откуда тут следует что под that property подразумевается физическая уникальность экземпляра? Для меня это не очевидно. А значит могут существовать другие свойства объекта. Наблюдаемое поведение объекта — вполне одно из таких свойств.
Концептуально — ниоткуда, а в контретной реализации ООП — очень даже понятно откуда. Других реализаций ООП не видел.
S>Если ты отбрасываешь понятие логической идентичности потому как не видишь, как оно может вытечь из определения идентичности, давай на этом закончим. Ну или по крайней мере приостановим доказательства друг-другу своих утверждений до тех пор, пока не разберемся с определением идентичности и не найдем общее понимание его.
Я его отбрасываю потому что оно неформализуемо.
Вообще странно ты пытаешься поступить. Есть вполне формальное определение identity — отличить объект от всех остальных, для этого в C# например еcть Object.ReferenceEquals, который как-бы говорит нам о сравнении ссылок. Ты придумываешь какое-то определение, которое неформализуемо и непредставимо в языке и разводишь на основании этого демагогию.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Ты показал отличие ссылочной эквивалентности от эквивалентности, определенной для строки по умолчанию. G>>То что ты называешь ссылочной эквивалентностью является по идентичностью. S>Тебе недостаточно различных определений, ты продолжаешь настаивать, но не приводишь ссылки на то что это одно и то же.
Ты сам приводишь все нужные ссылки. Только выводы делаешь неправильные.
S>Словами: идентичность — это такое свойство объекта, которое позволяет отличать его от остальных. S>Опровергнуть идентичность можно следующими способами — сравнить поведение объектов.
Identity не зависит от поведения и состояния. http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
object identity — a characteristic of an object that provides a means to uniquely denote or refer to the object independent of its state or behavior
Сам же приводил.
S>>>Давай так. Ты допускаешь существование понятия "логическая идентичность" или ты будешь все время игнорировать "логическая" и подразумевать при этом "физическую идентичность"? Если для тебя нет понятия логической идентичности, то мы просто обсуждаем разные понятия и наши доказательства ни к чему не приведут. G>>Я вообще будут игнорировать твои понятия пока ты им не приведешь формальные определения. То есть чтобы можно было написать код, который это проверит для любых объектов.
S>>>По ссылке выше три формальных определения. Допускают ли они трактовку, в которой логическая эквивалентность имеет место? Если нет, почему бы там сразу не написано "один и тот же объект"? G>>Потому что "один и тот же" можно сказать когда есть два объекта. А тут попытались написать определение identity для одного. S>Дай определение идентичности, которому ты доверяешь. http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
всем трем доверяю, причем одновременно, а не по-отдельности.
S>>>Ссылку на определения идентичности я дал, отношение эквивалентности — вот G>>Да нет, меня как раз интересует твое понимание идентичности. S>Выше
Оно неверно
S>>>Следует добавить в пример реализацию отношения эквивалентности? Я могу это сделать. G>>Ну, ты сделаешь два экивалентных, но не идентичных объекта. S>Ты можешь показать их неидентичность не используя сравнение ссылок?
Нет, потому что ссылка и есть identity. Ты можешь показать другое — показывай. Формально, кодом.
S>ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта?
В концептуальном определении их нет, но реализация identity во всех известных мне языках с поддержкой ООП опирается на ссылки в том или ином виде. Вообще слабо себе представляю ООП без ссылок.
S>>>Опровергнуть можно, я показал как. G>>Ты ничего не показал. Покажи как свойство "логической идентичности" можно выразить в программе. S>Существование отличий в поведении дает логическую неидентичность. Показать тебе все способы нахождения отличий?
Идентичность не зависит от поведения. Отличия в поведении — неидентичны. Зачем разделять на физическую и логическую?
S>>>Физическая но не логическая. Перестань игнорировать термины, описание которых я приводил неоднократно. Или мы обсуждаем одну и ту же вещь, либо не обсуждаем вовсе за бессмысленностью. G>>Чем физическая отличается от логической, приведи код. Рассуждения без кода не нужны. S>Логическая определяется через поведение объекта, а не через ссылку. Проверять всевозможное поведение объекта слишком муторно для форума.
Идентичность не зависит от поведения. Совпадения поведения в некотором смысле, который ты заранее задаешь, дает эквивалентность, а не идентичность.
S>>>Мы говорим не об одном и том же. G>>Возможно. Ты придумываешь вещи, которые отсутствуют. S>Их не я придумал. Есть несколько источников, где эти вещи описаны. Отрицай существование этих источников.
Да пусть хоть на каждом шагу написано, но оно не становится от этого формализуемым, ты не можешь доказать что что-то есть, следовательно этого нет.
S>>>x.Equals(x) — требование рефлексивности. Оно будет удовлетворено и для логической идентичности. Я забыл, о что мы доказывали. G>>Object.ReferenceEquals(this, obj) это какая идентичность? После этого сразу напиши код для получения другой идентичности. S>Это ссылочная эквивалентность а не идентичность. Из нее следует физическая идентичность. Из физической идентичности следует ссылочная эквивалентность. Но это не одно и то же. Понятия разные, но наблюдаются они у объекта одновременно. Смотри определения.
Если A -> B && B -> A, то A == B, это формальная логика, можешь с ней не спорить. Ты только что доказал что совпадение ссылок есть "физическая идентичность", теперь осталось выяснить чем логическая идентичность отличается от физической идентичности.
Для этого просто приведи код, где будет "логическая идентичность" как некоторое выражение, возвращающее true для двух объектов, но не будет "физической идентичности" (равенства ссылок). Ну и естественно это должно быть выражение для любого типа, а не для какого-то класса.
S>>>Определения идентичности я приводил. G>>Формально, код давай. Без кода это пустой треп. S>Если для тебя это треп, то давай завязывать. Я тебе уже устал повторять, что доказать идентичность даже объекта самому себе кодом невозможно. Формально определение идентичности ссылается на свойства, которые позволяют отличать объекты друг от друга.
Я просто поверю создателям языка что Object.ReferenceEquals — сравнивает identity. Причем ссылки, которые сравниваются, вполне соответствуют всем трем определениям отсюда.
А ты, если не веришь, попробуй доказать обратное.
Одним написанием определений ты ничего не докажешь. Нужен код.
S>>>Нужно еще формально показать что из него вытекает лишь физическая идентичность и никак не логическая. Покуда это не сделано строго и формально, я считаю что понятие логической идентичности вытекает из определения идентичности. Описание того, что такое логическая идентичность я приводил. G>>В чем отличия физической и логической идентичности? Кодом. S>Докажи идентичность объекта самому себе кодом, что бы сошлось с определением.
Идентичность не нужно доказывать, она или есть, или нет. Это неотъемлемое свойство объекта. Идентичность и позволяет отличить объект от других, то есть id(a) == id(b) только когда a и b это один и тот же объект.
S>>>Откуда тут следует что под that property подразумевается физическая уникальность экземпляра? Для меня это не очевидно. А значит могут существовать другие свойства объекта. Наблюдаемое поведение объекта — вполне одно из таких свойств. G>>Концептуально — ниоткуда, а в контретной реализации ООП — очень даже понятно откуда. Других реализаций ООП не видел. S>Это не значит, что других реализаций не может быть.
Приведи реализацию, я склонен считать что если в программировании что-то невозможно сделать в коде, то этого просто нет. Программирование не требует затрат больших энергии на проведение эксперимента.
S>>>Если ты отбрасываешь понятие логической идентичности потому как не видишь, как оно может вытечь из определения идентичности, давай на этом закончим. Ну или по крайней мере приостановим доказательства друг-другу своих утверждений до тех пор, пока не разберемся с определением идентичности и не найдем общее понимание его.
G>>Я его отбрасываю потому что оно неформализуемо. S>Оно формализуемо.
Так приведи код, который проверит "логическую идентичность".
G>>Вообще странно ты пытаешься поступить. Есть вполне формальное определение identity — отличить объект от всех остальных, для этого в C# например еcть Object.ReferenceEquals, который как-бы говорит нам о сравнении ссылок. S>ReferenceEquals для сравнения ссылок, он не определяет идентичность формально. В нескольких источниках написано что неравенство ссылок не приводит к различным идентичностям. Оспаривай эти источники.
Уже писали про это: наприемр если взять указатель на область памяти или на COM объект, то он может иметь разные адреса при указании на один объект, но в любом случае существует "инвариантный" указатель, который будет совпадать. Вот этот инвариантный указатель можно считать ссылкой в общем (в математическом понимании). Ссылки в C# инварианты, и внутрь залезть нельзя.
В соответствии с высказыванием ты утверждаешь что бывает так что Object.ReferenceEquals(a,b) == false, но это один и тот же объект.
Приведи пример языка где инвариантные ссылки не совпадают, но это один и тот же объект.
G>> Ты придумываешь какое-то определение, которое неформализуемо и непредставимо в языке и разводишь на основании этого демагогию. S>Я пользуюсь формальным определением. То что из него следует лишь физическая идентичность — не факт для меня. И еще раз — мопед не мой. Я указал как минимум 3 источника. Почему ты обвиняешь в придумывании и демагогии именно меня?
Потому что ты опираешься на неформализуемое определение логической идентичности.
S>Скажи что все мои источники нагло врут, либо я их неверно понимаю. На этом закончим.
Во-ервых не все, во-вторых не врут, а заблуждаются или смешивают концепцию с деталями реализации.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>Если рассматривать ООП с точки зрения Кея, то и erlang с процессами более чем соответствует. ANS>Это упрощение. Ты из акцента на messaging (подразумевается наличие чего-то еще), оставил *только* messaging. А ведь была еще и концепция "только объект", которая подразумевает "рекурсивный дизайн", когда объекты состоят из объектов на макро и микро уровне. В Erlang процессы (как единица хранения состояния) и сообщения есть только на макро уровне.
Да, я это написал именно к вопросу о попытке натянуть некоторые свойства ООП на SOA.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>>И пытаешься углядеть в вики скрытый смысл, которого там нет. S>>Еще как минимум один источник говорит о наличии логической идентичности. AFAIR, вы на него ссылались весной. S>Логическая идентичность — термин, выдуманный лично вами.
Я не могу это опровергнуть, могу лишь дать ссылку на статью, автор которой не я http://c2.com/cgi/wiki?ObjectIdentity
Со своей стороны могу сказать что то что логическую идентичность выдумал я, выдумали лично вы.
S>Больше им не пользуется никто. Все остальные отличают идентичность от иных видов эквивалентности.
Как минимум автор указанной статьи им пользуется. Вы не можете игнорировать существование этой и других статей, к которым я непричастен.
S>Идентичность — это такое отношение эквивалентности, при котором объект эквивалентен себе и не эквивалентен больше никакому другому объекту.
Это ниоткуда не следует.
S>>ок, COM особый случай. S>И именно для него и изоморфных ему случаев введена оговорка в Wiki о том, что ссылочная эквивалентность достаточное, но не необходимое условие для идентичности.
Не уверен в этом. Классические определения, данные до появления кома, допускают логическую эквивалентность.
S>Ещё раз повторю банальые истины: S>1. эквивалентность объектов и эквивалентность ссылок — разные вещи, т.к. ссылка не есть объект. Именно поэтому две различных ссылки могут указывать на один и тот же объект.
Очевидно. S>2. для любого отношения эквивалентности, заданного для объектов, идентичность ==> эта эквивалентность. В силу рефлексивности.
Я говорил о том что логическая идентичность не ведет к ссылочной эквивалентности. Физическая идентичность ведет к любым эквивалентностям в силу рефлексивности.
S>What makes up the identity of an object in an object-oriented system? A common answer is "object identity" is defined by being in the same spot in memory, which is called "reference equality" and matches Java's == operator. A consequence of this situation is if two objects are identical, a change to one will always affect the other. This distinguishes identity from the notion of "being equal," which can change over time. In fact, multiple notions of being equal are possible, such as String.equals() and String.equalsIgnoreCase().
S>Using reference equality as the only notion of object identity seems a good solution at first, but unfortunately this point of view is a little naive.
И? Я вижу здесь только подтверждение моим словам. Нет никаких упоминаний "логической идентичности" vs "физической идентичности".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Я не могу это опровергнуть, могу лишь дать ссылку на статью, автор которой не я http://c2.com/cgi/wiki?ObjectIdentity S>Со своей стороны могу сказать что то что логическую идентичность выдумал я, выдумали лично вы.
S>>Больше им не пользуется никто. Все остальные отличают идентичность от иных видов эквивалентности. S>Как минимум автор указанной статьи им пользуется. Вы не можете игнорировать существование этой и других статей, к которым я непричастен.
А вы не обратили внимание, что во фрагменте Ричарда Хендерсона речь идёт о базах данных, а не об ООП?
У него "логически идентичными" называются те "объекты" (не в смысле ООП, а в более широком смысле), которые имеют т.н. value-семантику. В частности, для них главной является эквивалентность состояния. С точки зрения строгой теории, никакой идентичности у них нет.
S>>Идентичность — это такое отношение эквивалентности, при котором объект эквивалентен себе и не эквивалентен больше никакому другому объекту. S>Это ниоткуда не следует.
Правильно, потому что это определение.
S>Не уверен в этом. Классические определения, данные до появления кома, допускают логическую эквивалентность.
Напримеру, какие?
S>Я говорил о том что логическая идентичность не ведет к ссылочной эквивалентности. Физическая идентичность ведет к любым эквивалентностям в силу рефлексивности.
А я говорил о том, что никакой "логической идентичности" в ООП нет. Та "логическая идентичность", на которую вы ссылаетесь, в ООП не применяется. Она применяется для value-типов, которые ведут себя не так, как объекты.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>Ты сам приводишь все нужные ссылки. Только выводы делаешь неправильные.
Я уверен в своей правоте. Словами о неправильных выводах меня не убедить.
S>>Опровергнуть идентичность можно следующими способами — сравнить поведение объектов. G>Identity не зависит от поведения и состояния.
G>
G>object identity — a characteristic of an object that provides a means to uniquely denote or refer to the object independent of its state or behavior
G>Сам же приводил.
Верно не зависит. Изменение состояния и поведение объекта не изменяет его идентичность. Фраза об этом. Потому изменив состояние одного объетка и не увидев изменения другого объекта можно опровергнуть их идентичность.
S>>Дай определение идентичности, которому ты доверяешь. G>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm G>всем трем доверяю, причем одновременно, а не по-отдельности.
Я не вижу как оттуда вытекает лишь физический аспект идентичности.
G>>>Да нет, меня как раз интересует твое понимание идентичности. S>>Выше G>Оно неверно
В чем его отличие от тех, которым ты доверяешь?
G>>>Ну, ты сделаешь два экивалентных, но не идентичных объекта. S>>Ты можешь показать их неидентичность не используя сравнение ссылок? G>Нет, потому что ссылка и есть identity. Ты можешь показать другое — показывай. Формально, кодом.
Где об этом сказано? Вот синклер написал что разные ссылки могут ссылаться на один объект. В таком случае идентичность этого объекта самому себе будет опровергнута.
S>>ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта? G>В концептуальном определении их нет, но реализация identity во всех известных мне языках с поддержкой ООП опирается на ссылки в том или ином виде. Вообще слабо себе представляю ООП без ссылок.
Это не проблемы концепции. Допустим, в некой реализации ссылки нельзя сравнивать. Ты скажешь что это не ООП на том основании что в известных тебе реализациях это не так?
S>>Существование отличий в поведении дает логическую неидентичность. Показать тебе все способы нахождения отличий? G>Идентичность не зависит от поведения. Отличия в поведении — неидентичны. Зачем разделять на физическую и логическую?
Идентичность не зависит от поведения, но опираясь на наблюдаемое поведение можно опровергнуть логическую идентичность двух объектов.
S>>Логическая определяется через поведение объекта, а не через ссылку. Проверять всевозможное поведение объекта слишком муторно для форума. G>Идентичность не зависит от поведения. Совпадения поведения в некотором смысле, который ты заранее задаешь, дает эквивалентность, а не идентичность.
Эквивалентность можно построить на чем угодно, удовлетворив выполнение свойств отношения эквивалентности.
S>>Их не я придумал. Есть несколько источников, где эти вещи описаны. Отрицай существование этих источников. G>Да пусть хоть на каждом шагу написано, но оно не становится от этого формализуемым, ты не можешь доказать что что-то есть, следовательно этого нет.
Ты не можешь доказать физическую идентичность. Следовательно ее нет?
S>>Это ссылочная эквивалентность а не идентичность. Из нее следует физическая идентичность. Из физической идентичности следует ссылочная эквивалентность. Но это не одно и то же. Понятия разные, но наблюдаются они у объекта одновременно. Смотри определения. G> G>Если A -> B && B -> A, то A == B, это формальная логика, можешь с ней не спорить.
Нет такой логики. Есть такая:
A => B && B => A, то A <=> B (читается тогда и только тогда) не путай их. Не делает чести.
G>Ты только что доказал что совпадение ссылок есть "физическая идентичность", теперь осталось выяснить чем логическая идентичность отличается от физической идентичности.
Тем что она не опирается на расположение в памяти.
G>Для этого просто приведи код, где будет "логическая идентичность" как некоторое выражение, возвращающее true для двух объектов, но не будет "физической идентичности" (равенства ссылок). Ну и естественно это должно быть выражение для любого типа, а не для какого-то класса.
С чего бы для любого типа? Для конкретного типа — пожалуйста
class Monostate
{
static int a;
public int A { get { return a; } set { a = value; } }
}
var a = new Monostate();
var b = new Monostate();
a.A = 42;
Assert(42 == b.A);
Только как ты не можешь доказать физическую идентичность объекта самому себе, так и я не смогу доказать логическую идентичность a и b. Тем не менее, я их считаю их идентичными согласно определению.
S>>Если для тебя это треп, то давай завязывать. Я тебе уже устал повторять, что доказать идентичность даже объекта самому себе кодом невозможно. Формально определение идентичности ссылается на свойства, которые позволяют отличать объекты друг от друга. G>Я просто поверю создателям языка что Object.ReferenceEquals — сравнивает identity. Причем ссылки, которые сравниваются, вполне соответствуют всем трем определениям отсюда.
Это не доказательство идентичности кодом. Ты оперируешь кучей допущений, сделанными создателями платформы. Что у объектов есть ссылки, что ссылки можно сравнивать, что из равенства ссылок следует что объекты расположены по одному адресу, что объекты, расположенные по одному адресу не могут обладать свойствами, отличающими их друг от друга.
Что будешь делать если ссылки сравнить нельзя, либо как подметил Ikemefula, если две неравные ссылки ссылаются на один объект и из неравенства ссылок не следует неидентичность?
G>А ты, если не веришь, попробуй доказать обратное. G>Одним написанием определений ты ничего не докажешь. Нужен код.
Ты не написал код, убеждающий в идентичности объекта самому себе строго
S>>Докажи идентичность объекта самому себе кодом, что бы сошлось с определением. G>Идентичность не нужно доказывать, она или есть, или нет. Это неотъемлемое свойство объекта.
Тогда не проси с меня код G>Идентичность и позволяет отличить объект от других, то есть id(a) == id(b) только когда a и b это один и тот же объект.
Это выдумка, которая не следует из определения идентичности. В частности в определении не упоминается "один и тот же".
G>>>Концептуально — ниоткуда, а в контретной реализации ООП — очень даже понятно откуда. Других реализаций ООП не видел. S>>Это не значит, что других реализаций не может быть. G>Приведи реализацию, я склонен считать что если в программировании что-то невозможно сделать в коде, то этого просто нет. Программирование не требует затрат больших энергии на проведение эксперимента.
Мне необязательно доказывать тебе возможность существования другой реализации конкретным примером. Хотя ключ я уже дал. Представь себе ООП систему, где невозможно сравнение ссылок либо убеди себя что такой не может существовать.
G>>>Я его отбрасываю потому что оно неформализуемо. S>>Оно формализуемо. G>Так приведи код, который проверит "логическую идентичность".
Приведи код, который проверит физическую идентичность формально, а не по ReferenceEquals.
G>Уже писали про это: наприемр если взять указатель на область памяти или на COM объект, то он может иметь разные адреса при указании на один объект, но в любом случае существует "инвариантный" указатель, который будет совпадать. Вот этот инвариантный указатель можно считать ссылкой в общем (в математическом понимании). Ссылки в C# инварианты, и внутрь залезть нельзя.
Это частный случай с COM, который не исчерпывает широту определения. G>В соответствии с высказыванием ты утверждаешь что бывает так что Object.ReferenceEquals(a,b) == false, но это один и тот же объект.
Я такого не утвреждаю. G>Приведи пример языка где инвариантные ссылки не совпадают, но это один и тот же объект.
Это не обязательно. Я рассуждаю о концептуальной модели, а не о частной ее реализации.
S>>Я пользуюсь формальным определением. То что из него следует лишь физическая идентичность — не факт для меня. И еще раз — мопед не мой. Я указал как минимум 3 источника. Почему ты обвиняешь в придумывании и демагогии именно меня? G>Потому что ты опираешься на неформализуемое определение логической идентичности.
а ты пользуешься неформализуемым определением физической идентичности.
S>>Скажи что все мои источники нагло врут, либо я их неверно понимаю. На этом закончим. G>Во-ервых не все, во-вторых не врут, а заблуждаются или смешивают концепцию с деталями реализации.
Давай завязывать. Мы так ни к чему не придем, просто потратим время.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: S>>Опровергнуть идентичность можно следующими способами — сравнить поведение объектов. Если изменение состояния одного объекта не приводит к изменению состояния другого — объекты не идентичны. Если такие отличия не могут быть найдены, то это свидетельствует об идентичности, но быть уверенным что они идентичны нельзя. S>Это — нет. Вы берёте базовое свойство ООП-модели и начинаете выражать его через другие два свойства, которые на самом деле от него зависят. S>Вы почти всё понимаете правильно, кроме одного: идентичность обеспечивается в ООП независимым от поведения и состояния способом. S>Всё. Точка.
С этим согласен. Но я не вижу, что я понял неправильно. Я показал как можно доказать неидентичность объектов, исходя из этого свойства идентичности.
S>Способов реализации этой идентичности — масса. S>В системах с persistent storage в качестве identity используют OID — явный идентификатор, присущий любому объекту.
Это не относится к OO идентичности. S>По OID всегда можно понять, идёт ли речь об одном и том же объекте, или нет, безо всяких апелляций к его поведению (которое может быть сейчас вообще недоступно, если объект offline).
тоже. S>В системах с flat моделью памяти и неперемещаемыми объектами в качестве identity можно использовать адрес объекта.
это верно S>В системах типа COM для обеспечения идентичности приходится делать специальные приседания — QueryInterface для IUnknown.
да.
Но формально по определению — если найдется свойство объекта, которое будет его отличать от другого, они будут неидентичны. ссылка не является свойством объекта.
S>Ссылочную эквивалентность можно использовать для идентичности в том случае, если соблюдаются определённые требования к ссылкам. В частности, в Java и .Net эти требования соблюдаются. В COM — нет.
Для определения физической идентичности можно (не в COM).
На COM предлагаю забить, потому как с ним явно оговорено, что ссылочная эквивалентность у него по IUnknown. Учитывая это он ведет себя вполне ожидаемо и соответственно объеткам в других популярных языках/платформах.
S>Вообще, в целом, ссылка отличается от identity тем, что ссылку можно гарантированно разрешить, то есть выполнить dereference. S>Identity нам такой возможности давать не обязана.
Верно. S>Из определения ссылки следует, что из ссылочной эквивалентности следует идентичность — ссылка однозначно определяет объект.
Ссылочная эквивалентность налагает дополнительное требование к концепции — существование ссылок и возможность проверить их эквивалентность, из которой должно следовать что объекты находятся по одному адресу и не могут обладать свойствами, отличающими их друг от друга. Слишком много допущений. S>То есть у двух разных объектов гарантированно разные ссылки.
Это верно. Но это не вытекает из определения идентичности.
S>>Ты можешь показать их неидентичность не используя сравнение ссылок? ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта? S>Если хочется экспериментов с идентичностью в .Net, можно невиртуально вызвать object.GetHashCode() на двух "одинаковых" строках. Его реализация как раз возвращает различные int-ы для различных объектов
Не знал. Не буду проверять, но они могли бы вернуть один int. И что тогда?
S>Но в целом, рекомендую перестать спорить с очевидным.
Для меня очевидно другое S>В .Net идентичность через ссылочную эквивалентность принята по определению.
Можно определение, которое бы гарантировало идентичность через ссылочную экивалентность напрямую, а не через серию уточнений? S>Она лучше, чем предлагаемая "логическая идентичность" (которую в .Net называют просто "эквивалентностью") потому, что работает для всех объектов, а не только для immutable.
То что она лучше — это неважно.
S>>Существование отличий в поведении дает логическую неидентичность. Показать тебе все способы нахождения отличий? S>Неэквивалентность.
неидентичность. Как показать неэквивалентность я посмотрю у конкретного отношения эквивалентности.
S>Предлагаю вместо новоизобретённого термина "логическая идентичность" использовать общепонятный "эквивалентность поведения". В отличие от "логической идентичности", любое определение которой будет оксюмороном, этот термин легко определить формально.
Окей, я согласен заменить логическую идентичность на эквивалентность поведения. Этот термин хорошо отражает суть. Но надо заметить что формально "эквивалентность поведения" подпадает под определение идентичности. Иначе — мы будем подразумевать что-то разное.
S>Два объекта будут поведенчески эквивалентны, если их реакция на любое сообщение будет одинаковой.
Это определение не годится. Нужно такое: если невозможно найти свойства, отличающие их
S>Через эквивалентность поведения выражается понятие состояния — два поведенчески эквивалентных объекта будут находиться в одном состоянии. Напомню, что напрямую наблюдать состояние объекта в ООП нельзя — это чёрный ящик.
Согласен
S>Эквивалентность поведения нельзя использовать для идентичности — это отдельное отношение эквивалентности, и оно разбивает объекты на другие классы эквивалентности.
Другое чем физическая идентичность — согласен. Но оно вытекает из определения идентичности.
S>>Их не я придумал. Есть несколько источников, где эти вещи описаны. Отрицай существование этих источников. S>Пока что ни один источник приведён не был. Было приведено неправильное толкование статьи из википедии.
их все можно обвинить в неправильном толковании википедии
Но по-моему налицо повсеместное неправильное толкования определения идентичности.
S>>Скажи что все мои источники нагло врут, либо я их неверно понимаю. На этом закончим. S>Неверно понимаете.
По-моему вы неверно понимаете.
На этом можно закруглиться.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>>Больше им не пользуется никто. Все остальные отличают идентичность от иных видов эквивалентности. S>>Как минимум автор указанной статьи им пользуется. Вы не можете игнорировать существование этой и других статей, к которым я непричастен. S>А вы не обратили внимание, что во фрагменте Ричарда Хендерсона речь идёт о базах данных, а не об ООП? S>У него "логически идентичными" называются те "объекты" (не в смысле ООП, а в более широком смысле), которые имеют т.н. value-семантику. В частности, для них главной является эквивалентность состояния. С точки зрения строгой теории, никакой идентичности у них нет.
Я нахожу что его логическая идентичность вписывается в определение идентичности.
S>>>Идентичность — это такое отношение эквивалентности, при котором объект эквивалентен себе и не эквивалентен больше никакому другому объекту. S>>Это ниоткуда не следует. S>Правильно, потому что это определение.
S>>Не уверен в этом. Классические определения, данные до появления кома, допускают логическую эквивалентность. S>Напримеру, какие?
например, эти http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
S>>Я говорил о том что логическая идентичность не ведет к ссылочной эквивалентности. Физическая идентичность ведет к любым эквивалентностям в силу рефлексивности. S>А я говорил о том, что никакой "логической идентичности" в ООП нет. Та "логическая идентичность", на которую вы ссылаетесь, в ООП не применяется. Она применяется для value-типов, которые ведут себя не так, как объекты.
То что value не объекты, вы не смогли меня убедить весной.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>>>
A consequence of this situation is if two objects are identical, a change to one will always affect the other.
S>>>И? Я вижу здесь только подтверждение моим словам. Нет никаких упоминаний "логической идентичности" vs "физической идентичности".
S>>Нет способа изменить лишь один из них. Они удовлетворяют процитированному. Т.е. согласно процитированному являются идентичными.
G>Нет, не являются.
G>Исходое выражение : если А, то Б, где А — идентичность двух объектов, Б — изменение свойств отражающееся на обоих. G>В логике "если x, то y" называют импликацией. G>Она верна в том числе когда А — ложно и Б — истинно. В коде выше именно Б истинно, но А ложно.
G>Но импликация ложна, когда посылка истинна, а следствие ложно. То есть выражение вида "если изменения одного объекта влияют на другой, то они эквивалентны" ложно.
Верно. Прошу прощения. запутался. Искренне благодарю за внимательность.
Но вот следствие из википедии
The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
согласно ему a и b идентичны. Верно? Да и ссылка на same type есть, т.е. для любого типа это не надо показывать.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>Ты сам приводишь все нужные ссылки. Только выводы делаешь неправильные. S>Я уверен в своей правоте. Словами о неправильных выводах меня не убедить.
Но это не делает тебя правым
S>>>Опровергнуть идентичность можно следующими способами — сравнить поведение объектов. G>>Identity не зависит от поведения и состояния.
G>>
G>>object identity — a characteristic of an object that provides a means to uniquely denote or refer to the object independent of its state or behavior
G>>Сам же приводил. S>Верно не зависит. Изменение состояния и поведение объекта не изменяет его идентичность. Фраза об этом. Потому изменив состояние одного объетка и не увидев изменения другого объекта можно опровергнуть их идентичность.
Так опровергни идентичность объектов для которых object.ReferenceEquals(a,b) == true, если ты утверждаешь что object.ReferenceEquals не является выражением идентичности.
S>>>Дай определение идентичности, которому ты доверяешь. G>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm G>>всем трем доверяю, причем одновременно, а не по-отдельности. S>Я не вижу как оттуда вытекает лишь физический аспект идентичности.
Нету отдельно физического и логического аспекта, ты их выдумал.
G>>>>Да нет, меня как раз интересует твое понимание идентичности. S>>>Выше G>>Оно неверно S>В чем его отличие от тех, которым ты доверяешь?
Ты не привел формального определения.
G>>>>Ну, ты сделаешь два экивалентных, но не идентичных объекта. S>>>Ты можешь показать их неидентичность не используя сравнение ссылок? G>>Нет, потому что ссылка и есть identity. Ты можешь показать другое — показывай. Формально, кодом. S>Где об этом сказано?
Может и нигде, но object.ReferenceEquals позволяет отличить один объект от другого как раз с помощью ссылки. Именно это и можно принять за identity. И действительно, если object.ReferenceEquals(a,b) == true, то любое изменение a отразится на b.
S>Вот синклер написал что разные ссылки могут ссылаться на один объект. В таком случае идентичность этого объекта самому себе будет опровергнута.
Это зависит от реализации ссылки в языке, конкретно в C# ссылка и есть identity. А если в каком-то языке это не так, то там все равно есть способ получить некоторое инвариантное значение, которое мы и будем называть ссылкой. Например в БД это ключ записи.
S>>>ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта? G>>В концептуальном определении их нет, но реализация identity во всех известных мне языках с поддержкой ООП опирается на ссылки в том или ином виде. Вообще слабо себе представляю ООП без ссылок. S>Это не проблемы концепции. Допустим, в некой реализации ссылки нельзя сравнивать. Ты скажешь что это не ООП на том основании что в известных тебе реализациях это не так?
Ок, приведи такую реализацию.
Но это ты пытаешься сменить тему. По сути ты хотел доказать что неравенство ссылок в C# может быть и для идентичных объектов. Тебе то не удастся. Поэтому ты начала извращать понятие identity разводя демагогию.
S>>>Существование отличий в поведении дает логическую неидентичность. Показать тебе все способы нахождения отличий? G>>Идентичность не зависит от поведения. Отличия в поведении — неидентичны. Зачем разделять на физическую и логическую? S>Идентичность не зависит от поведения, но опираясь на наблюдаемое поведение можно опровергнуть логическую идентичность двух объектов.
Что такое логическая идентичность?
S>>>Логическая определяется через поведение объекта, а не через ссылку. Проверять всевозможное поведение объекта слишком муторно для форума. G>>Идентичность не зависит от поведения. Совпадения поведения в некотором смысле, который ты заранее задаешь, дает эквивалентность, а не идентичность. S>Эквивалентность можно построить на чем угодно, удовлетворив выполнение свойств отношения эквивалентности.
Можно.
S>>>Их не я придумал. Есть несколько источников, где эти вещи описаны. Отрицай существование этих источников. G>>Да пусть хоть на каждом шагу написано, но оно не становится от этого формализуемым, ты не можешь доказать что что-то есть, следовательно этого нет. S>Ты не можешь доказать физическую идентичность. Следовательно ее нет?
Ок, давай выяснять что такое физическая идентичность. Покажи чем физическая идентичность отличается от ссылки? Напомню что в прошлом посте ты показал эквивалентность этих понятий.
S>>>Это ссылочная эквивалентность а не идентичность. Из нее следует физическая идентичность. Из физической идентичности следует ссылочная эквивалентность. Но это не одно и то же. Понятия разные, но наблюдаются они у объекта одновременно. Смотри определения. G>> G>>Если A -> B && B -> A, то A == B, это формальная логика, можешь с ней не спорить. S>Нет такой логики. Есть такая: S>A => B && B => A, то A <=> B (читается тогда и только тогда) не путай их. Не делает чести.
Другой распространенной операцией является эквивалентность. Ее аналог в разговорной речи — фразы, подобные словосочетанию тогда и только тогда, когда ... или если и только если ... Для ее обозначения используется символ <-> или просто =.
На википедии кстати статьи про логическую эквивалентность нет, надо что-то кроме википедии читать
G>>Ты только что доказал что совпадение ссылок есть "физическая идентичность", теперь осталось выяснить чем логическая идентичность отличается от физической идентичности. S>Тем что она не опирается на расположение в памяти.
Раскрою тайну: ссылки в C# тоже не опираются на расположение в памяти в общем случае, так как объекты могут перемещаться. Ссылки — не адреса.
G>>Для этого просто приведи код, где будет "логическая идентичность" как некоторое выражение, возвращающее true для двух объектов, но не будет "физической идентичности" (равенства ссылок). Ну и естественно это должно быть выражение для любого типа, а не для какого-то класса. S>С чего бы для любого типа? Для конкретного типа — пожалуйста S>
S>class Monostate
S>{
S> static int a;
S> public int A { get { return a; } set { a = value; } }
S>}
S>var a = new Monostate();
S>var b = new Monostate();
S>a.A = 42;
S>Assert(42 == b.A);
S>
См выделенное. Ты по сути построил класс все экземпляры которого могут быть эквивалентны между собой.
S>Только как ты не можешь доказать физическую идентичность объекта самому себе, так и я не смогу доказать логическую идентичность a и b.
Видимо ты не те определения выбрал что не можешь доказать что-то из них.
S>Тем не менее, я их считаю их идентичными согласно определению.
Согласно определению они как раз неидентичны, потому что я тебе легко приведу выражение отличающее их друг от друга (угадай какое).
S>>>Если для тебя это треп, то давай завязывать. Я тебе уже устал повторять, что доказать идентичность даже объекта самому себе кодом невозможно. Формально определение идентичности ссылается на свойства, которые позволяют отличать объекты друг от друга. G>>Я просто поверю создателям языка что Object.ReferenceEquals — сравнивает identity. Причем ссылки, которые сравниваются, вполне соответствуют всем трем определениям отсюда. S>Это не доказательство идентичности кодом. Ты оперируешь кучей допущений, сделанными создателями платформы. Что у объектов есть ссылки, что ссылки можно сравнивать, что из равенства ссылок следует что объекты расположены по одному адресу, что объекты, расположенные по одному адресу не могут обладать свойствами, отличающими их друг от друга.
Ну ведь эти "допущения" не нарушаются, так? Значит все таки ссылка — identity?
S>Что будешь делать если ссылки сравнить нельзя, либо как подметил Ikemefula, если две неравные ссылки ссылаются на один объект и из неравенства ссылок не следует неидентичность?
Приведи язык где нельзя сравнить ссылки? Если ссылки не одинаковы в битовом представлении, то есть инвариантный формат, их надо привести и сравнить.
Для простоты давай называть ссылкой инвариантый формат, чтобы не усложнять рассуждения.
G>>А ты, если не веришь, попробуй доказать обратное. G>>Одним написанием определений ты ничего не докажешь. Нужен код. S>Ты не написал код, убеждающий в идентичности объекта самому себе строго
object.ReferenceEquals(a,a) не? ведь ссылка работает как identity, тебе не удалось этого опровергнуть.
S>>>Докажи идентичность объекта самому себе кодом, что бы сошлось с определением. G>>Идентичность не нужно доказывать, она или есть, или нет. Это неотъемлемое свойство объекта. S>Тогда не проси с меня код G>>Идентичность и позволяет отличить объект от других, то есть id(a) == id(b) только когда a и b это один и тот же объект. S>Это выдумка, которая не следует из определения идентичности. В частности в определении не упоминается "один и тот же".
Да, там упоминается "отличить от других". Давай пререфразирую, id(a) != id(b) только когда a и b — разные объекты. Опять-таки формальная логика рулит, я просто сделал отрицание обеих частей выражения, таблица истинности не поменялась.
G>>>>Концептуально — ниоткуда, а в контретной реализации ООП — очень даже понятно откуда. Других реализаций ООП не видел. S>>>Это не значит, что других реализаций не может быть. G>>Приведи реализацию, я склонен считать что если в программировании что-то невозможно сделать в коде, то этого просто нет. Программирование не требует затрат больших энергии на проведение эксперимента. S>Мне необязательно доказывать тебе возможность существования другой реализации конкретным примером. Хотя ключ я уже дал. Представь себе ООП систему, где невозможно сравнение ссылок либо убеди себя что такой не может существовать.
Ок, представим. Как ты в такой системе обеспечишь identity? Как ты напишешь выражение, которое позволяет отличить один объект от другого?
G>>>>Я его отбрасываю потому что оно неформализуемо. S>>>Оно формализуемо. G>>Так приведи код, который проверит "логическую идентичность". S>Приведи код, который проверит физическую идентичность формально, а не по ReferenceEquals.
Давай начнем с определения "физической идентичности", что это такое? Как оно выражается в языке?
G>>Уже писали про это: наприемр если взять указатель на область памяти или на COM объект, то он может иметь разные адреса при указании на один объект, но в любом случае существует "инвариантный" указатель, который будет совпадать. Вот этот инвариантный указатель можно считать ссылкой в общем (в математическом понимании). Ссылки в C# инварианты, и внутрь залезть нельзя. S>Это частный случай с COM, который не исчерпывает широту определения.
И? Ну приведи случай реализации ООП где
1)Ссылки на объекты нельзя сравнить
2)Ссылки на один и тот же объект могут быть различными
3)Что будет identity в таком случае?
4)Как отличать объекты один от другого?
G>>В соответствии с высказыванием ты утверждаешь что бывает так что Object.ReferenceEquals(a,b) == false, но это один и тот же объект. S>Я такого не утвреждаю.
А что тогда утверждаешь? только кодом.
G>>Приведи пример языка где инвариантные ссылки не совпадают, но это один и тот же объект. S>Это не обязательно. Я рассуждаю о концептуальной модели, а не о частной ее реализации.
Рассуждать можно о чем угодно, даже том чего не существует. В программировании легко провести эксперимент, он не требует ничего кроме умственных усилий и немного времени. Покажи пример того о чем ты пытаешься рассуждать.
S>>>Я пользуюсь формальным определением. То что из него следует лишь физическая идентичность — не факт для меня. И еще раз — мопед не мой. Я указал как минимум 3 источника. Почему ты обвиняешь в придумывании и демагогии именно меня? G>>Потому что ты опираешься на неформализуемое определение логической идентичности. S>а ты пользуешься неформализуемым определением физической идентичности.
Я вообще не делю идентичность на физическую и логическую.
Я говорю что во всех практических реализациях есть ссылки на объекты (инвариантные ссылки если угодно), которые как раз выполняют роль identity. При этом сами ссылки могут не совпадать (COM), но приводятся к инварианту, которые совпадают для одинаковых объектов, также ссылки могут иметь непостоянное битовое представление (.NET и Java). Могут быть сложными значениями — ключи строк в БД.
Ты же понамешал сюда логическую и физическую идентичность, при этом не можешь дать определение ни одной, ни другой.
Это и есть демагогия.
Здравствуйте, samius, Вы писали:
S>Нет способа изменить лишь один из них. Они удовлетворяют процитированному. Т.е. согласно процитированному являются идентичными.
Ошибка в логике. Из идентичности следует изменение "обоих". Из "изменения обоих" идентичность никак не следует.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали: S>Я нахожу что его логическая идентичность вписывается в определение идентичности.
В определение идентичности из ООП — нет.
S>>Напримеру, какие? S>например, эти http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
Ну вы сами-то хоть читайте, на что ссылаетесь!
Все три определения говорят об идентичности, которая отличает объект от всех остальных объектов. Понимаете, от всех!
И вы тут же в пример "логической идентичности" приводите две разных экземпляра строки, у которых ваше определение идентичности даёт одинаковый результат!
Далее, читаем там же
This means the objects can be distinguished from each other without comparing their values or their behavior.
А вы пытаетесь рассказать про идентичность, которая работает как раз через сравнение поведения.
S>То что value не объекты, вы не смогли меня убедить весной.
Очень может быть. Вас вообще очень трудно в чём-то убедить. Вы ухитряетёсь цитировать источники, которые вас же опровергают, в защиту своих заблуждений.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Это не проблемы концепции. Допустим, в некой реализации ссылки нельзя сравнивать. Ты скажешь что это не ООП на том основании что в известных тебе реализациях это не так?
Если в этой реализации не предложен другой способ получения идентити объекта, то я таки скажу, что это — не ООП.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Я уверен в своей правоте. Словами о неправильных выводах меня не убедить. G>Но это не делает тебя правым
Тоже верно.
S>>Верно не зависит. Изменение состояния и поведение объекта не изменяет его идентичность. Фраза об этом. Потому изменив состояние одного объетка и не увидев изменения другого объекта можно опровергнуть их идентичность. G>Так опровергни идентичность объектов для которых object.ReferenceEquals(a,b) == true, если ты утверждаешь что object.ReferenceEquals не является выражением идентичности.
Я нигде не утверждал что объекты с равными ссылками могут быть неидентичными.
S>>Я не вижу как оттуда вытекает лишь физический аспект идентичности. G>Нету отдельно физического и логического аспекта, ты их выдумал.
не я
S>>В чем его отличие от тех, которым ты доверяешь? G>Ты не привел формального определения.
Приводил
G>>>Нет, потому что ссылка и есть identity. Ты можешь показать другое — показывай. Формально, кодом. S>>Где об этом сказано? G>Может и нигде, но object.ReferenceEquals позволяет отличить один объект от другого как раз с помощью ссылки. Именно это и можно принять за identity. И действительно, если object.ReferenceEquals(a,b) == true, то любое изменение a отразится на b.
Это верно. Но из того что любое изменение a отразится на b не следует равенство ссылок.
S>>Вот синклер написал что разные ссылки могут ссылаться на один объект. В таком случае идентичность этого объекта самому себе будет опровергнута. G>Это зависит от реализации ссылки в языке, конкретно в C# ссылка и есть identity. А если в каком-то языке это не так, то там все равно есть способ получить некоторое инвариантное значение, которое мы и будем называть ссылкой. Например в БД это ключ записи.
Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором.
S>>>>ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта? G>>>В концептуальном определении их нет, но реализация identity во всех известных мне языках с поддержкой ООП опирается на ссылки в том или ином виде. Вообще слабо себе представляю ООП без ссылок. S>>Это не проблемы концепции. Допустим, в некой реализации ссылки нельзя сравнивать. Ты скажешь что это не ООП на том основании что в известных тебе реализациях это не так? G>Ок, приведи такую реализацию.
В этом нет необходимости. G>Но это ты пытаешься сменить тему. По сути ты хотел доказать что неравенство ссылок в C# может быть и для идентичных объектов. Тебе то не удастся. Поэтому ты начала извращать понятие identity разводя демагогию.
Ты слишком узко смотришь на определение идентичности.
S>>Идентичность не зависит от поведения, но опираясь на наблюдаемое поведение можно опровергнуть логическую идентичность двух объектов. G>Что такое логическая идентичность?
Это идентичность, основанная на отсутствии свойств объектов, отличающих их. Под свойствами я подразумеваю не поля объекта и не свойства аксессоры к полям. Физический адрес я тоже не отношу к свойствам объекта.
S>>Ты не можешь доказать физическую идентичность. Следовательно ее нет? G>Ок, давай выяснять что такое физическая идентичность. Покажи чем физическая идентичность отличается от ссылки? Напомню что в прошлом посте ты показал эквивалентность этих понятий.
Они отличаются определением.
S>>>>Это ссылочная эквивалентность а не идентичность. Из нее следует физическая идентичность. Из физической идентичности следует ссылочная эквивалентность. Но это не одно и то же. Понятия разные, но наблюдаются они у объекта одновременно. Смотри определения. G>>> G>>>Если A -> B && B -> A, то A == B, это формальная логика, можешь с ней не спорить. S>>Нет такой логики. Есть такая: S>>A => B && B => A, то A <=> B (читается тогда и только тогда) не путай их. Не делает чести. G>
G>Ты привел одно и тоже заменив -> на => и == на <=>. G>http://www.ctc.msiu.ru/materials/Book2/ch_07_sheets/01_logic/03_implies/
G>
G>Другой распространенной операцией является эквивалентность. Ее аналог в разговорной речи — фразы, подобные словосочетанию тогда и только тогда, когда ... или если и только если ... Для ее обозначения используется символ <-> или просто =.
То что ты мне привел — это эквивалентность между высказываниями или формулами, когда они принимают одни и те же истинностные значения. Из эквивалентности высказываний не следует эквивалентность понятий, заданными разными определениями. Ты же мне написал что физическая идентичность эквивалентна равеству ссылок, а потом поставил знак ==.
G>На википедии кстати статьи про логическую эквивалентность нет, надо что-то кроме википедии читать
выбирай, что читать.
S>>Тем что она не опирается на расположение в памяти. G>Раскрою тайну: ссылки в C# тоже не опираются на расположение в памяти в общем случае, так как объекты могут перемещаться. Ссылки — не адреса.
Не прямые адреса, разве что.
G>>>Для этого просто приведи код, где будет "логическая идентичность" как некоторое выражение, возвращающее true для двух объектов, но не будет "физической идентичности" (равенства ссылок). Ну и естественно это должно быть выражение для любого типа, а не для какого-то класса. S>>С чего бы для любого типа? Для конкретного типа — пожалуйста S>>
S>> static int a;
S>> public int A { get { return a; } set { a = value; } }
S>>
G>См выделенное. Ты по сути построил класс все экземпляры которого могут быть эквивалентны между собой.
не я его построил. Это известный паттерн.
Следствие в википедии говорит об объектах одного типа. Откуда ты взял "для любого типа" — не знаю.
S>>Только как ты не можешь доказать физическую идентичность объекта самому себе, так и я не смогу доказать логическую идентичность a и b. G>Видимо ты не те определения выбрал что не можешь доказать что-то из них.
Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет.
S>>Тем не менее, я их считаю их идентичными согласно определению. G>Согласно определению они как раз неидентичны, потому что я тебе легко приведу выражение отличающее их друг от друга (угадай какое).
Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности.
S>>Это не доказательство идентичности кодом. Ты оперируешь кучей допущений, сделанными создателями платформы. Что у объектов есть ссылки, что ссылки можно сравнивать, что из равенства ссылок следует что объекты расположены по одному адресу, что объекты, расположенные по одному адресу не могут обладать свойствами, отличающими их друг от друга. G>Ну ведь эти "допущения" не нарушаются, так? Значит все таки ссылка — identity?
Нет. Это значит что из равенства ссылок следует identity. То что верно обратное ты не показал. Извини, в определении идентичности ничего про ссылки нет, поэтому тебе придется формально доказывать что идентичные объекты имеют равные ссылки.
И то, если покажешь, то получишь лишь эквивалентность высказываний, но не эквивалентность понятий.
S>>Что будешь делать если ссылки сравнить нельзя, либо как подметил Ikemefula, если две неравные ссылки ссылаются на один объект и из неравенства ссылок не следует неидентичность? G>Приведи язык где нельзя сравнить ссылки? Если ссылки не одинаковы в битовом представлении, то есть инвариантный формат, их надо привести и сравнить.
Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. G>Для простоты давай называть ссылкой инвариантый формат, чтобы не усложнять рассуждения.
Незачем. Тебе C# позволяет привести ссылку к инвариантному формату?
G>>>Одним написанием определений ты ничего не докажешь. Нужен код. S>>Ты не написал код, убеждающий в идентичности объекта самому себе строго G>object.ReferenceEquals(a,a) не? ведь ссылка работает как identity, тебе не удалось этого опровергнуть.
Тебе не удалось это доказать.
G>>>Идентичность и позволяет отличить объект от других, то есть id(a) == id(b) только когда a и b это один и тот же объект. S>>Это выдумка, которая не следует из определения идентичности. В частности в определении не упоминается "один и тот же". G>Да, там упоминается "отличить от других". Давай пререфразирую, id(a) != id(b) только когда a и b — разные объекты. Опять-таки формальная логика рулит, я просто сделал отрицание обеих частей выражения, таблица истинности не поменялась.
Не рулит логика, когда неверен посыл. Докажи что разные объекты а и b будут иметь различные if(a) и id(b). Формально из определения, пожалуйста, а не руководствуясь домыслами о равенстве ссылок.
S>>Мне необязательно доказывать тебе возможность существования другой реализации конкретным примером. Хотя ключ я уже дал. Представь себе ООП систему, где невозможно сравнение ссылок либо убеди себя что такой не может существовать. G>Ок, представим. Как ты в такой системе обеспечишь identity? Как ты напишешь выражение, которое позволяет отличить один объект от другого?
ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity.
G>>>Так приведи код, который проверит "логическую идентичность". S>>Приведи код, который проверит физическую идентичность формально, а не по ReferenceEquals. G>Давай начнем с определения "физической идентичности", что это такое? Как оно выражается в языке?
Определение то же самое. Выражения в языке нет. ReferenceEquals выражает равенство ссылок а не идентичность. Покажи что не найдется свойства, по которым можно отличить объект от самого себя. Кодом!
S>>Это частный случай с COM, который не исчерпывает широту определения. G>И? Ну приведи случай реализации ООП где G>1)Ссылки на объекты нельзя сравнить
приводил G>2)Ссылки на один и тот же объект могут быть различными
добавим к C#-- то свойство, что ссылка включает в себя время ее получения. Вот такой я странный. G>3)Что будет identity в таком случае?
То же самое, см. формальное определение. G>4)Как отличать объекты один от другого?
Зачем? Механизм доставки сообщений по заданному identity работает. Большего не требуется. Я не собираюсь этот язык внедрять в производство или решать на нем какие-либо задачи.
G>>>В соответствии с высказыванием ты утверждаешь что бывает так что Object.ReferenceEquals(a,b) == false, но это один и тот же объект. S>>Я такого не утвреждаю. G>А что тогда утверждаешь? только кодом.
Я утверждаю что из неравенства ссылок может следовать same identity. Кодом я identity записать не могу. Да и ты пока не смог.
G>>>Приведи пример языка где инвариантные ссылки не совпадают, но это один и тот же объект. S>>Это не обязательно. Я рассуждаю о концептуальной модели, а не о частной ее реализации. G>Рассуждать можно о чем угодно, даже том чего не существует. В программировании легко провести эксперимент, он не требует ничего кроме умственных усилий и немного времени. Покажи пример того о чем ты пытаешься рассуждать.
См. пример с monostate.
G>>>Потому что ты опираешься на неформализуемое определение логической идентичности. S>>а ты пользуешься неформализуемым определением физической идентичности. G>Я вообще не делю идентичность на физическую и логическую.
Я заметил. Но формализовать кодом просто определение идентичности ты тоже не смог пока.
G>Я говорю что во всех практических реализациях есть ссылки на объекты (инвариантные ссылки если угодно), которые как раз выполняют роль identity. При этом сами ссылки могут не совпадать (COM), но приводятся к инварианту, которые совпадают для одинаковых объектов, также ссылки могут иметь непостоянное битовое представление (.NET и Java). Могут быть сложными значениями — ключи строк в БД.
Я говорю об концептуальной модели а не о практических реализациях.
G>Ты же понамешал сюда логическую и физическую идентичность, при этом не можешь дать определение ни одной, ни другой. G>Это и есть демагогия.
Я давал. Еще раз. Физическая идентичность — идентичность основанная на равенстве ссылок/адресов/хэндлов/уникальных системных идентификаторов. Хочется назвать ее суррогатной идентичностью, т.к. ссылки и т.п. не имеют отношения к объекту, его состоянию и поведению. Логическая идентичность — идентичность, которая основывается на наблюдаемом поведении объекта. И да, я знаю что поведение и состояние не влияют на идентичность. Потому предлагается устанавливать идентичность по разнице в наблюдаемом поведении.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Нет способа изменить лишь один из них. Они удовлетворяют процитированному. Т.е. согласно процитированному являются идентичными. S>Ошибка в логике. Из идентичности следует изменение "обоих". Из "изменения обоих" идентичность никак не следует.
gandjustas-у уже ответил, не на то сослался.
Вот из вики.
The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Но вот следствие из википедии S>>
S>>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>>согласно ему a и b идентичны. Верно? Да и ссылка на same type есть, т.е. для любого типа это не надо показывать.
G>Это глупость написана.
Это надо доказывать. G>Банально опровергается сравнением ссылок.
Для этого надо доказать что все идентичные объекты обладают равными ссылками. Формально.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>С этим согласен. Но я не вижу, что я понял неправильно. Я показал как можно доказать неидентичность объектов, исходя из этого свойства идентичности. S>Нет. S>>Это не относится к OO идентичности. S>Относится. Плоха была бы ОО-модель, если бы работала только для одного адресного пространства.
Не я предлагал привязываться к адресному пространству. Но в разных адресных пространствах легко обнаружить противоречие определению идентичности для идентичных объектов.
S>>Ссылочная эквивалентность налагает дополнительное требование к концепции — существование ссылок и возможность проверить их эквивалентность, из которой должно следовать что объекты находятся по одному адресу и не могут обладать свойствами, отличающими их друг от друга. Слишком много допущений. S>Смотря где. В чистой теории — да. Но в чистой теории словосочетание "свойство идентичности" означает всего лишь наличие функции ID(o:object), которая возвращает значение из некоторого множества, на котором определено отношение эквивалентности.
Да. S>При этом ID(o1) == ID(o2) тогда и только тогда, когда o1 и o2 обозначают один и тот же объект.
Откуда это следует? Именно про один и тот же объект.
S>В чистой теории можно "обозначить" объект как o1 или как o2, никак не оперируя ссылками.
да
S>На практике же ОО-систем без ссылок не бывает — понятие ссылки и разыменования необходимо для того, чтобы писать сколь-нибудь полезные программы. В программе нельзя сказать "отправить сообщение объекту, обозначенному как о1".
В программе на C++ можно отправить сообщение объекту, обозначенному идентификатором o1 без ссылки.
S>Поэтому этих допущений не "слишком много", а как раз нормально. Далее, про находимость "по одному адресу" я бы упоминать не рекомендовал — адрес в программировании является значительно более сильным понятием, чем ссылка, и, в отличие от последней, допускает значительно больше операций. S>Кроме того, употреблять "объекты находятся" во множественном числе здесь не имеет смысла, даже отвлекаясь от понятия адреса. S>Правильно говорить так: "из ссылочной эквивалентности следует то, что ссылки ссылаются на один и тот же объект".
Согласен.
S>>>То есть у двух разных объектов гарантированно разные ссылки. S>>Это верно. Но это не вытекает из определения идентичности. S>Это вытекает из определения ссылки.
Я неверно ответил по поводу разных. У разных объектов ссылки разные. Но то что у двух идентичных объектов ссылки разные — неочевидно. И не вытекает из определения идентичности.
S>>Не знал. Не буду проверять, но они могли бы вернуть один int. И что тогда? S>Да, в общем-то, ничего.
S>>Можно определение, которое бы гарантировало идентичность через ссылочную экивалентность напрямую, а не через серию уточнений? S>Конечно S>http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf, секция 8.2.5.1, стр. 30. S>
S>Otherwise, if their exact type is a reference type, then they are identical if and only if the locations of the values are the same.
В ECMA собственное определение идентичности. Я не вижу его соответсвия или даже похожести на определение идентичности в ООП. S>value-типы в .Net выходят за рамки чистого ООП, поэтому для них идентичность определена по-другому. S>Секция 8.2.5 там же описывает ваш пример со строками с точки зрения стандарта.
S>
S>Thus, the values of variables A and B are identical, the values of variables A and C as well as B and C are not identical, and the values of all three of A, B, and C are equal
S>>Окей, я согласен заменить логическую идентичность на эквивалентность поведения. Этот термин хорошо отражает суть. Но надо заметить что формально "эквивалентность поведения" подпадает под определение идентичности. Иначе — мы будем подразумевать что-то разное. S>Нет, не попадает. Два различимых объекта могут демонстрировать одинаковое поведение, находясь в одинаковом состоянии.
Тогда эквивалентность поведение это не то же, что логическая эквивалентность.
S>>>Два объекта будут поведенчески эквивалентны, если их реакция на любое сообщение будет одинаковой. S>>Это определение не годится. Нужно такое: если невозможно найти свойства, отличающие их S>Нет. S>1. Что вы называете "свойствами"?
Нечто, по чему можно отличить объекты. S>2. Зачем вы их пихаете в понятие "эквивалентного поведения"? Очевидно, что эквивалентность поведения должна определяться в терминах поведения, и ничего больше. Пример на пальцах: "цветовая эквивалентность" для предметов не должна подразумевать одинаковость их формы.
Я именно про поведение. Если в контракте объекта сказано что когда мы вызовем SetValue(42), то после этого будем получать GetValue() == 42, то это такое свойство поведения, по которому мы его сможем отличить от объектов, для которых мы не вызывали SetValue(42).
S>>Другое чем физическая идентичность — согласен. Но оно вытекает из определения идентичности. S>Что откуда вытекает?
Определение идентичности не указыват о том, что свойства, отличающие объекты есть именно ссылки/адреса/хэндлы и т.п. Значит может быть что-то еще, что их отличает. Я подразумеваю что это может быть наблюдаемое поведение.
S>>Но по-моему налицо повсеместное неправильное толкования определения идентичности. S>Нет, неправильное толкование определения идентичности сосредоточено ровно в одном человеке.
Не неправильное, а не такое как у участников дискуссии.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: S>>Я нахожу что его логическая идентичность вписывается в определение идентичности. S>В определение идентичности из ООП — нет.
S>>>Напримеру, какие? S>>например, эти http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm S>Ну вы сами-то хоть читайте, на что ссылаетесь! S>Все три определения говорят об идентичности, которая отличает объект от всех остальных объектов. Понимаете, от всех!
От всех с другой идентичностью. S>И вы тут же в пример "логической идентичности" приводите две разных экземпляра строки, у которых ваше определение идентичности даёт одинаковый результат! S>Далее, читаем там же S>
S>This means the objects can be distinguished from each other without comparing their values or their behavior.
S>А вы пытаетесь рассказать про идентичность, которая работает как раз через сравнение поведения.
А что это вы процитировали? Какое это имеет отношение к определениям, кроме того что оно написано под ними? Наверное, чья-то догадка?
S>>То что value не объекты, вы не смогли меня убедить весной. S>Очень может быть. Вас вообще очень трудно в чём-то убедить. Вы ухитряетёсь цитировать источники, которые вас же опровергают, в защиту своих заблуждений.
Возможно.
Прокомментируйте, пожалуйста еще раз следствия из вики
1. If the references do not compare equal, then it's not necessarily guaranteed that the identity of the objects behind those references is different.
2. The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Это не проблемы концепции. Допустим, в некой реализации ссылки нельзя сравнивать. Ты скажешь что это не ООП на том основании что в известных тебе реализациях это не так?
S>Если в этой реализации не предложен другой способ получения идентити объекта, то я таки скажу, что это — не ООП.
Из вики:
A reference can be used to refer to an object with a specific identity. A reference contains the information that is necessary for the identity property to be realized in the programming language, and allows access to the object with the identity. A type of a target of a reference is a role.
Здесь не сказано что должен быть способ получения идентити объекта. Здесь сказано что ссылка может быть использована для доступа к объекту со специфичной идентити.
Здравствуйте, samius, Вы писали:
S>Вот из вики. S>
S>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
Ну и в каком из этих двух мест по-вашему ошибка?
Ваш подход мне вообще очень нравится. Вот написано определение, которое всем понятно и однозначно. Но вас оно не устраивает, вы начинаете искать всякие комментарии и следствия из него, в поисках фразы, которую можно проинтерпретировать по-другому. Зачем?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>>При этом ID(o1) == ID(o2) тогда и только тогда, когда o1 и o2 обозначают один и тот же объект. S>Откуда это следует? Именно про один и тот же объект.
Из определения. Перечитайте его ещё раз: идентичность — свойство объекта, позволяющее отличить его от всех других объектов, независимо от их состояния и поведения.
S>В программе на C++ можно отправить сообщение объекту, обозначенному идентификатором o1 без ссылки.
Нет.
S>Я неверно ответил по поводу разных. У разных объектов ссылки разные. Но то что у двух идентичных объектов ссылки разные — неочевидно. И не вытекает из определения идентичности.
Этого никто не утверждал.
S>В ECMA собственное определение идентичности. Я не вижу его соответсвия или даже похожести на определение идентичности в ООП.
Странно, а я — вижу. Требованиям, предъявляемым к идентичности в ООП, ECMA-шное удовлетворяет.
S>Тогда эквивалентность поведение это не то же, что логическая эквивалентность.
Значит, вам ещё предстоит придумать определение логической эквивалентности. Как мы только что выяснили, эквивалентность поведения — это не она.
S>Я именно про поведение. Если в контракте объекта сказано что когда мы вызовем SetValue(42), то после этого будем получать GetValue() == 42, то это такое свойство поведения, по которому мы его сможем отличить от объектов, для которых мы не вызывали SetValue(42). S>Определение идентичности не указыват о том, что свойства, отличающие объекты есть именно ссылки/адреса/хэндлы и т.п. Значит может быть что-то еще, что их отличает. Я подразумеваю что это может быть наблюдаемое поведение.
Вы копаете не в ту сторону. По определению идентичности, она должна работать независимо от поведения.
S>Не неправильное, а не такое как у участников дискуссии.
Да-да. Весь мир идёт не в ногу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Здесь не сказано что должен быть способ получения идентити объекта. Здесь сказано что ссылка может быть использована для доступа к объекту со специфичной идентити.
Здесь — не сказано. Но есть определение идентити, и есть требование наличия такой идентити в определении того, что такое ООП.
Не нужно читать бесчисленные возможные следствия из различных реализаций идентити для того, чтобы понять, что если нет идентити — то нет и ООП. Чего ещё нужно-то?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Вот из вики. S>>
S>>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>Ну и в каком из этих двух мест по-вашему ошибка?
Вы же утверждаете что здесь ошибка. Я привел пример объектов одного типа, шарящих состояние, которые попадают под эту формулировку.
S>Ваш подход мне вообще очень нравится. Вот написано определение, которое всем понятно и однозначно.
Значит не всем оно поянтно. S>Но вас оно не устраивает, вы начинаете искать всякие комментарии и следствия из него, в поисках фразы, которую можно проинтерпретировать по-другому. Зачем?
Затем что я могу привести пример двух различных объектов с same identity. Что я деалю не так?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>>При этом ID(o1) == ID(o2) тогда и только тогда, когда o1 и o2 обозначают один и тот же объект. S>>Откуда это следует? Именно про один и тот же объект. S>Из определения. Перечитайте его ещё раз: идентичность — свойство объекта, позволяющее отличить его от всех других объектов, независимо от их состояния и поведения.
Помните, пол года назад вы утверждали что у неизменяемых объектов нет идентичности? А я пытался докопаться, что отнимает у них идентичность?
S>>В программе на C++ можно отправить сообщение объекту, обозначенному идентификатором o1 без ссылки. S>Нет.
MyObj obj; obj.Foo();
Где здесь ссылка?
S>>Я неверно ответил по поводу разных. У разных объектов ссылки разные. Но то что у двух идентичных объектов ссылки разные — неочевидно. И не вытекает из определения идентичности. S>Этого никто не утверждал.
Отлично
S>>В ECMA собственное определение идентичности. Я не вижу его соответсвия или даже похожести на определение идентичности в ООП. S>Странно, а я — вижу. Требованиям, предъявляемым к идентичности в ООП, ECMA-шное удовлетворяет.
Оно как минимум выпадает из него (в вашей трактовке) в контексте value-объектов, т.к. допускает существование двух различных объектов same identity. А значит не может быть использовано для того что бы отличить один объект от всех остальных.
S>>Тогда эквивалентность поведение это не то же, что логическая эквивалентность. S>Значит, вам ещё предстоит придумать определение логической эквивалентности. Как мы только что выяснили, эквивалентность поведения — это не она.
Это срочно?
S>>Я именно про поведение. Если в контракте объекта сказано что когда мы вызовем SetValue(42), то после этого будем получать GetValue() == 42, то это такое свойство поведения, по которому мы его сможем отличить от объектов, для которых мы не вызывали SetValue(42). S>>Определение идентичности не указыват о том, что свойства, отличающие объекты есть именно ссылки/адреса/хэндлы и т.п. Значит может быть что-то еще, что их отличает. Я подразумеваю что это может быть наблюдаемое поведение. S>Вы копаете не в ту сторону. По определению идентичности, она должна работать независимо от поведения.
В некоторых источниках сказано что изменение объекта не приводит к изменению его идентичности. Это тоже можно трактовать как независимость идентичности от состояния и поведения.
S>>Не неправильное, а не такое как у участников дискуссии. S>Да-да. Весь мир идёт не в ногу.
Ваше понимание идентичности тоже какое-то не такое. Почему у иммутабельных объектов нет идентичности? Откуда это вытекает? Только не надо вспоминать семантику value-объектов В определении идентичности о ней нет упоминания.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>От всех с другой идентичностью. S>Это вы додумываете. В определениях такого нет.
Да, додумываю.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Здесь не сказано что должен быть способ получения идентити объекта. Здесь сказано что ссылка может быть использована для доступа к объекту со специфичной идентити. S>Здесь — не сказано. Но есть определение идентити, и есть требование наличия такой идентити в определении того, что такое ООП.
Identity — это такая функция ID: obj->(?), переводящая объект или ссылку в неизвестно что, что можно сравнить. Нигде не написано что это неизвестно что (?) не может иметь связи с поведением. Вот я и предлагаю использовать область значений, завязанную на наблюдаемое поведение. Что не так? S>Не нужно читать бесчисленные возможные следствия из различных реализаций идентити для того, чтобы понять, что если нет идентити — то нет и ООП. Чего ещё нужно-то?
identity есть.
Здравствуйте, samius, Вы писали:
S>Вы же утверждаете что здесь ошибка. Я привел пример объектов одного типа, шарящих состояние, которые попадают под эту формулировку.
Но они не попадают под формулировку из вашей предыдущей цитаты. Очевидно, в какой-то из цитат перепутаны местами причина и следствие. Как вы думаете, в какой?
Я считаю — что в той, которая следует из определения. Цитата википедии, очевидно, из википедийного же определения не следует.
S>Затем что я могу привести пример двух различных объектов с same identity. Что я деалю не так?
Вы не так понимаете смысл термина identity. Разве это не очевидно?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали: S>Помните, пол года назад вы утверждали что у неизменяемых объектов нет идентичности? А я пытался докопаться, что отнимает у них идентичность? S>>>В программе на C++ можно отправить сообщение объекту, обозначенному идентификатором o1 без ссылки. S>>Нет. S>MyObj obj; obj.Foo(); S>Где здесь ссылка?
obj. Вы же ещё помните, что ссылка — это не адрес? S>Оно как минимум выпадает из него (в вашей трактовке) в контексте value-объектов, т.к. допускает существование двух различных объектов same identity. А значит не может быть использовано для того что бы отличить один объект от всех остальных.
Ещё раз напомню, что value-типы дотнета не попадают в классическое ООП.
S>>Вы копаете не в ту сторону. По определению идентичности, она должна работать независимо от поведения. S>В некоторых источниках сказано что изменение объекта не приводит к изменению его идентичности. Это тоже можно трактовать как независимость идентичности от состояния и поведения.
Ну, и замечательно. В чём вопрос-то? В том, как правильно пользоваться формальной логикой? Поясню: если есть какое-то следствие из идентичности, справедливое также для какого-то другого отношения, это не означает, что это другое отношение тоже можно использовать для идентичности.
S>Ваше понимание идентичности тоже какое-то не такое. Почему у иммутабельных объектов нет идентичности? Откуда это вытекает? Только не надо вспоминать семантику value-объектов В определении идентичности о ней нет упоминания.
Хорошо, вы правы. У immutable-объектов есть идентичность, если это объекты в смысле ООП.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Вы же утверждаете что здесь ошибка. Я привел пример объектов одного типа, шарящих состояние, которые попадают под эту формулировку. S>Но они не попадают под формулировку из вашей предыдущей цитаты. Очевидно, в какой-то из цитат перепутаны местами причина и следствие. Как вы думаете, в какой? S>Я считаю — что в той, которая следует из определения. Цитата википедии, очевидно, из википедийного же определения не следует.
Вы считаете что в формулировке
The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
надо поменять причину и следствие? Но тогда мы получим что-то не совсем осмысленное.
IF object identity of two objects of the same type is the same, THEN every change to either object is also a change to the other object.
Для чего здесь уточнение same type? Что бы мы не взяли объекты с same identity но разного типа? Если забить на эту неувязку с same type, то в остальном — вполне осмысленная и верифицируемая фраза. Если бы она была в таком виде в википедии я бы не удивился.
S>>Затем что я могу привести пример двух различных объектов с same identity. Что я деалю не так? S>Вы не так понимаете смысл термина identity. Разве это не очевидно?
Я вижу что я понимаю смысл термина не так как остальные на этом форуме. Это для меня очевидно.
Здравствуйте, samius, Вы писали: S>Identity — это такая функция ID: obj->(?), переводящая объект или ссылку в неизвестно что, что можно сравнить. S>Нигде не написано что это неизвестно что (?) не может иметь связи с поведением.
Написано. Но вам это читать неинтересно. Вы предпочитаете читать между строк и мелким шрифтом, напрочь игнорируя всё остальное.
S>Вот я и предлагаю использовать область значений, завязанную на наблюдаемое поведение. Что не так?
Как что?
1. Ваше предложение не вполне соответствует определению, которое требует от идентичности независимости от состояния и поведения. В частности, такое определение требует наличия идентичности даже у объектов без поведения совсем.
2. Ваше предложение противоречит определению, которое требует от идентичности возможности различать разные объекты. Тем не менее, вы упорно приводите примеры, когда ваше определение идентичности приводит к неразличимости разных объектов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: S>>Помните, пол года назад вы утверждали что у неизменяемых объектов нет идентичности? А я пытался докопаться, что отнимает у них идентичность? S> S>>>>В программе на C++ можно отправить сообщение объекту, обозначенному идентификатором o1 без ссылки. S>>>Нет. S>>MyObj obj; obj.Foo(); S>>Где здесь ссылка? S>obj. Вы же ещё помните, что ссылка — это не адрес?
Я еще помню что идентификатор это не ссылка. Правда это идентификатор не объекта, а переменной. Но все равно, я считаю что обошелся без ссылки.
S>>Оно как минимум выпадает из него (в вашей трактовке) в контексте value-объектов, т.к. допускает существование двух различных объектов same identity. А значит не может быть использовано для того что бы отличить один объект от всех остальных. S>Ещё раз напомню, что value-типы дотнета не попадают в классическое ООП.
Согласно чему?
S>>>Вы копаете не в ту сторону. По определению идентичности, она должна работать независимо от поведения. S>>В некоторых источниках сказано что изменение объекта не приводит к изменению его идентичности. Это тоже можно трактовать как независимость идентичности от состояния и поведения. S>Ну, и замечательно. В чём вопрос-то? В том, как правильно пользоваться формальной логикой? Поясню: если есть какое-то следствие из идентичности, справедливое также для какого-то другого отношения, это не означает, что это другое отношение тоже можно использовать для идентичности.
Не вижу другого отношения.
S>>Ваше понимание идентичности тоже какое-то не такое. Почему у иммутабельных объектов нет идентичности? Откуда это вытекает? Только не надо вспоминать семантику value-объектов В определении идентичности о ней нет упоминания. S>Хорошо, вы правы. У immutable-объектов есть идентичность, если это объекты в смысле ООП.
Отлично. Я тоже признаюсь. Я готов признать вашу с ganjustas-ом правоту относительно трактовки идентичности. Единственное что меня еще смущает — я допускаю другую трактовку. Можно списывать на мою упертость, но я все-таки считаю что определение не вполне однозначно. И некоторые моменты все-таки наводят на сомения.
Здравствуйте, samius, Вы писали:
S>Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором.
Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки.
S>Это идентичность, основанная на отсутствии свойств объектов, отличающих их. Под свойствами я подразумеваю не поля объекта и не свойства аксессоры к полям. Физический адрес я тоже не отношу к свойствам объекта.
Подставив в твоё определение определение из википедии получаем:
Логическая идентичность — это идентичность, основанная на отсутствии "википедия-идентичности".
Здорово, правда?
S>Не прямые адреса, разве что.
Нет. Ссылки имеют другую алгебру, чем адреса.
Адреса можно сравнивать; можно вычитать. По адресу объекта можно определить, что он находится внутри другого объекта.
Со ссылкой ничего подобного сделать нельзя. Поэтому не надо, пожалуйста, называть ссылки адресами.
S>Следствие в википедии говорит об объектах одного типа. Откуда ты взял "для любого типа" — не знаю.
Если бы следствие в википедии являлось действительно следствием, то его можно было бы формально доказать, исходя из определения там же. Увы.
S>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет.
Смешные упражнения. Ок, пусть у нас будет ООП-система, в которой ссылки сравнивать нельзя — из неравенства ссылок не следует ничего интересного. Отлично, чтобы отличать объекты друг от друга, мы запихаем внутрь каждого экземпляра GUID.
0. Этот GUID будет волшебным образом генерироваться при всяком создании объекта, будь то "с нуля" или при клонировании объекта.
1. Этот ID будет недоступен коду самого объекта; его будет невозможно изменить в течение всего времени жизни.
2. Сделаем волшебную функцию ID(obj), которая будет залезать внутрь объекта и возвращать его GUID.
3. Объект никак не сможет повлиять на реализацию этой функции.
Введённая нами функция ID удовлетворяет определению идентичности: она одинаковая для одного и того же объекта; она разная для разных объектов в силу 0; она не зависит от состояния объекта в силу 1; она не зависит от поведения объекта в силу 3.
S>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности.
Не надо путать определение идентичности и реализацию идентичности.
Применимость ссылок для идентичности в дотнете нетрудно доказать в два хода.
S>Нет. Это значит что из равенства ссылок следует identity. То что верно обратное ты не показал. Извини, в определении идентичности ничего про ссылки нет, поэтому тебе придется формально доказывать что идентичные объекты имеют равные ссылки.
Да. Определение идентичности из ECMA — это memory location. Её применимость в качестве identity, если даже и не верить стандарту на слово, легко доказать.
Осталось сделать одно из двух:
1. найти место в ECMA, где сказано, что there cannot be two different references to the same memory location
2. найти место в ECMA, где сказано, что сравнение ссылок заведомо определяет, ссылаются ли они обе на одно и то же memory location.
На всякий случай поясню п.2: мы можем иметь ссылки, внутри устроенные как длинные указатели в DOS — пара (сегмент, смещение), где сегменты частично перекрываются. В такой схеме можно иметь две побитово различные ссылки на одно и то же место в памяти.
Вариант 1 явно запрещает использование таких схем; вариант 2 разрешает использовать такие схемы, если есть подходящая реализация оператора == для таких ссылок.
S>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет.
Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL.
Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает.
А если мы придумали способ, например ту самую волшебную функцию ID(obj), которая возвращает что-то сравнимое, не используя "биты" ссылки, то автоматически получаем реализацию оператора сравнения для ссылок:
S>Незачем. Тебе C# позволяет привести ссылку к инвариантному формату?
Конечно. Ссылка в C# уже имеет инвариантный формат.
S>Не рулит логика, когда неверен посыл. Докажи что разные объекты а и b будут иметь различные if(a) и id(b). Формально из определения, пожалуйста, а не руководствуясь домыслами о равенстве ссылок.
Зачем это доказывать? Это и есть определение идентичности.
S>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity.
Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений.
S>добавим к C#-- то свойство, что ссылка включает в себя время ее получения. Вот такой я странный. G>>3)Что будет identity в таком случае? S>То же самое, см. формальное определение. G>>4)Как отличать объекты один от другого? S>Зачем? Механизм доставки сообщений по заданному identity работает. Большего не требуется. Я не собираюсь этот язык внедрять в производство или решать на нем какие-либо задачи.
Механизма доставки по identity нету. Есть механизм доставки по ссылке. При таком определении ссылки вам ещё придётся доказывать, что ссылка имеет отношение к identity
S>Я утверждаю что из неравенства ссылок может следовать same identity.
Это утверждение очевидно неверно. При неравных ссылках same identity может быть, но вот следовать из них оно никак не может.
S>Я давал. Еще раз. Физическая идентичность — идентичность основанная на равенстве ссылок/адресов/хэндлов/уникальных системных идентификаторов. Хочется назвать ее суррогатной идентичностью, т.к. ссылки и т.п. не имеют отношения к объекту, его состоянию и поведению. Логическая идентичность — идентичность, которая основывается на наблюдаемом поведении объекта. И да, я знаю что поведение и состояние не влияют на идентичность. Потому предлагается устанавливать идентичность по разнице в наблюдаемом поведении.
Такое определение идентичности не работает для изменяемых объектов. Потому что в течение жизни она у них будет изменяться.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>надо поменять причину и следствие? Но тогда мы получим что-то не совсем осмысленное. S>IF object identity of two objects of the same type is the same, THEN every change to either object is also a change to the other object.
Мы получим почти точную перефразировку фразы, которую вы привели из другого источника. S>Для чего здесь уточнение same type? Что бы мы не взяли объекты с same identity но разного типа? Если забить на эту неувязку с same type, то в остальном — вполне осмысленная и верифицируемая фраза. Если бы она была в таком виде в википедии я бы не удивился.
Если это следствие, то оно должно выводиться из определения. Кокретно это следствие никак не выводится.
S>Я вижу что я понимаю смысл термина не так как остальные на этом форуме. Это для меня очевидно.
И как все остальные в мире — тоже. Вы сами привели уже кучу ссылок. Везде получается так, что идентичность в ООП позволяет отличать любые объекты друг от друга.
Вне ООП можно определять идентичность по-другому. Но это будет уже не ООП.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Я еще помню что идентификатор это не ссылка. Правда это идентификатор не объекта, а переменной. Но все равно, я считаю что обошелся без ссылки.
Ну и зря вы так считаете. А если я напишу MyObj &obj2 = obj, то ссылка появится?
Расскажите мне в деталях, чем obj2 семантически будет отличаться от obj.
S>Согласно чему?
Согласно определению ООП.
S>Не вижу другого отношения.
Ну как же, у вас всё время фигурирует какая-то "логическая идентичность", неуловимо отличающаяся от "физической идентичности", которой пользуются все остальные. Она, очевидно, вводит другое отношение между объектами, не такое, как у всех. Почему же вы его не видите?
S>Отлично. Я тоже признаюсь. Я готов признать вашу с ganjustas-ом правоту относительно трактовки идентичности. Единственное что меня еще смущает — я допускаю другую трактовку. Можно списывать на мою упертость, но я все-таки считаю что определение не вполне однозначно. И некоторые моменты все-таки наводят на сомения.
Определение в ООП вполне однозначно. То, что вы пытаетесь ввести в качестве логической идентичности — это эквивалентность в смысле дотнетного стандарта.
Для value-типов в дотнете она же принята за идентичность.
Именно о ней же ведёт речь тот единственный чувак, который упомянул сам термин logical, or internal identity.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Между строк читаю что ID не зависит от изменения состояний и поведения конкретного объекта.
Это не между строк, это часть определения. S>Но не вижу причин почему не отличать объекты по какой-то величине из области значений ID, которая имеет связь с поведением.
Даже если отвлечься от противоречий с определением, у меня вызывает крайнее сомнение сама возможность формализации такого критерия.
Покажите мне схему реализации метода IsIdentic(o1, o2), которая гарантированно возвращает false для объектов с разным поведением, и true для объектов с одинаковым. Метод должен быть вычислимым, и не должен менять состояние объектов. Я не предполагаю конкретного языка программирования, но как вы себе это представляете?
S>Без изменяемого поведения. Отсутствие изменяемого поведения — это тоже поведение. Не могу себе представить объект без поведения совсем. Ничего не делает — значит такое у него поведение.
Чтобы вы начали себе представлять объект без поведения, желательно ввести формальное определение поведения.
Можно попробовать по аналогии — начать представлять себе объект без состояния; (а то ведь можно сказать что "это у него такое состояние), а потом уже можно и без поведения представить.
S>>2. Ваше предложение противоречит определению, которое требует от идентичности возможности различать разные объекты. S>Оно позволяет различать объекты с разным поведением.
Определение выдвигает более сильное требование — иметь возможность различать объекты независимо от поведения. А, значит, и объекты с одинаковым поведением.
S>>Тем не менее, вы упорно приводите примеры, когда ваше определение идентичности приводит к неразличимости разных объектов. S>Да, но разных объектов с неразличимым поведением.
Мало ли что у них ещё неразличимо. Они разные — этого достаточно для несоответствия определению.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>Определение в ООП вполне однозначно. То, что вы пытаетесь ввести в качестве логической идентичности — это эквивалентность в смысле дотнетного стандарта.
Что такое эквивалентность в смысле дотнетного стандарта? В ECMA-355 нет самостоятельного определения экивалентности, только упоминание ее в различных контекстах.
S>Для value-типов в дотнете она же принята за идентичность. S>Именно о ней же ведёт речь тот единственный чувак, который упомянул сам термин logical, or internal identity.
структурная эквивалентность в смысле побитового совпадения областей памяти? Я пытался ввести эквивалентность поведения, что очевидно не то же самое, что структурная эквивалентность.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором. S>Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки.
выполняет роль, но не является.
S>>Это идентичность, основанная на отсутствии свойств объектов, отличающих их. Под свойствами я подразумеваю не поля объекта и не свойства аксессоры к полям. Физический адрес я тоже не отношу к свойствам объекта. S>Подставив в твоё определение определение из википедии получаем: S>Логическая идентичность — это идентичность, основанная на отсутствии "википедия-идентичности". S>Здорово, правда?
Действительно здорово. Что-то я плохо спал
S>>Не прямые адреса, разве что. S>Нет. Ссылки имеют другую алгебру, чем адреса. S>Адреса можно сравнивать; можно вычитать. По адресу объекта можно определить, что он находится внутри другого объекта. S>Со ссылкой ничего подобного сделать нельзя. Поэтому не надо, пожалуйста, называть ссылки адресами.
Договорились.
S>>Следствие в википедии говорит об объектах одного типа. Откуда ты взял "для любого типа" — не знаю. S>Если бы следствие в википедии являлось действительно следствием, то его можно было бы формально доказать, исходя из определения там же. Увы.
Верно. Тем более, в исправленной форме это следствие действительно упоминается неоднократно.
Приближаюсь к объявлению капитуляции
S>>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет. S>Смешные упражнения. Ок, пусть у нас будет ООП-система, в которой ссылки сравнивать нельзя — из неравенства ссылок не следует ничего интересного. Отлично, чтобы отличать объекты друг от друга, мы запихаем внутрь каждого экземпляра GUID. S>0. Этот GUID будет волшебным образом генерироваться при всяком создании объекта, будь то "с нуля" или при клонировании объекта. S>1. Этот ID будет недоступен коду самого объекта; его будет невозможно изменить в течение всего времени жизни. S>2. Сделаем волшебную функцию ID(obj), которая будет залезать внутрь объекта и возвращать его GUID. S>3. Объект никак не сможет повлиять на реализацию этой функции. S>Введённая нами функция ID удовлетворяет определению идентичности: она одинаковая для одного и того же объекта; она разная для разных объектов в силу 0; она не зависит от состояния объекта в силу 1; она не зависит от поведения объекта в силу 3.
Это своя реализация идентичности. Не интересно.
S>>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности. S>Не надо путать определение идентичности и реализацию идентичности. S>Применимость ссылок для идентичности в дотнете нетрудно доказать в два хода.
Для конкретной реализации — да.
S>>Нет. Это значит что из равенства ссылок следует identity. То что верно обратное ты не показал. Извини, в определении идентичности ничего про ссылки нет, поэтому тебе придется формально доказывать что идентичные объекты имеют равные ссылки. S>Да. Определение идентичности из ECMA — это memory location. Её применимость в качестве identity, если даже и не верить стандарту на слово, легко доказать.
memory location — это специальный случай. Он сильнее, чем то что подразумевается в определении идентичности. S>Осталось сделать одно из двух: S>1. найти место в ECMA, где сказано, что there cannot be two different references to the same memory location S>2. найти место в ECMA, где сказано, что сравнение ссылок заведомо определяет, ссылаются ли они обе на одно и то же memory location. S>На всякий случай поясню п.2: мы можем иметь ссылки, внутри устроенные как длинные указатели в DOS — пара (сегмент, смещение), где сегменты частично перекрываются. В такой схеме можно иметь две побитово различные ссылки на одно и то же место в памяти. S>Вариант 1 явно запрещает использование таких схем; вариант 2 разрешает использовать такие схемы, если есть подходящая реализация оператора == для таких ссылок.
Да, для ECMA понятия идентичности это верно. Но обобщить до определения идентичности в ООП это нельзя.
S>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL.
Компилировать FCL в C#-- не надо, нет такой цели S>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает.
Чихать что не заработает. Я не собираюсь удовлетворять ECMA-335. S>А если мы придумали способ, например ту самую волшебную функцию ID(obj), которая возвращает что-то сравнимое, не используя "биты" ссылки, то автоматически получаем реализацию оператора сравнения для ссылок: S>
Имеет смысл если ID вычислима. Но я не говорил что она вычислима.
S>>Незачем. Тебе C# позволяет привести ссылку к инвариантному формату? S>Конечно. Ссылка в C# уже имеет инвариантный формат.
Действительно.
S>>Не рулит логика, когда неверен посыл. Докажи что разные объекты а и b будут иметь различные if(a) и id(b). Формально из определения, пожалуйста, а не руководствуясь домыслами о равенстве ссылок. S>Зачем это доказывать? Это и есть определение идентичности.
В той трактовке, что позволяет отличать любой объект от всех остальных — да.
S>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений.
Ну дак мы их отличать можем в теории, по некой невычислимой функции. Существования такой функции достаточно, вычислимость ее — это просто очень полезный бонус
S>>добавим к C#-- то свойство, что ссылка включает в себя время ее получения. Вот такой я странный. G>>>3)Что будет identity в таком случае? S>>То же самое, см. формальное определение. G>>>4)Как отличать объекты один от другого? S>>Зачем? Механизм доставки сообщений по заданному identity работает. Большего не требуется. Я не собираюсь этот язык внедрять в производство или решать на нем какие-либо задачи. S>Механизма доставки по identity нету. Есть механизм доставки по ссылке. При таком определении ссылки вам ещё придётся доказывать, что ссылка имеет отношение к identity
мы можем отличать объекты с отличным поведением (но только их). Отличать объекты с неотличимым поведением не нужно. Но это уже видимо моя додумка.
S>>Я утверждаю что из неравенства ссылок может следовать same identity. S>Это утверждение очевидно неверно. При неравных ссылках same identity может быть, но вот следовать из них оно никак не может.
Про "следовать" погорячился. можем одновременно наблюдать неравенство ссылок и same identity.
S>>Я давал. Еще раз. Физическая идентичность — идентичность основанная на равенстве ссылок/адресов/хэндлов/уникальных системных идентификаторов. Хочется назвать ее суррогатной идентичностью, т.к. ссылки и т.п. не имеют отношения к объекту, его состоянию и поведению. Логическая идентичность — идентичность, которая основывается на наблюдаемом поведении объекта. И да, я знаю что поведение и состояние не влияют на идентичность. Потому предлагается устанавливать идентичность по разнице в наблюдаемом поведении. S>Такое определение идентичности не работает для изменяемых объектов. Потому что в течение жизни она у них будет изменяться.
Вот по этим изменениям я и предлагал определять идентичность.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Между строк читаю что ID не зависит от изменения состояний и поведения конкретного объекта. S>Это не между строк, это часть определения. S>>Но не вижу причин почему не отличать объекты по какой-то величине из области значений ID, которая имеет связь с поведением. S>Даже если отвлечься от противоречий с определением, у меня вызывает крайнее сомнение сама возможность формализации такого критерия.
Формализация есть. Вычислимости нет. S>Покажите мне схему реализации метода IsIdentic(o1, o2), которая гарантированно возвращает false для объектов с разным поведением, и true для объектов с одинаковым. Метод должен быть вычислимым, и не должен менять состояние объектов. Я не предполагаю конкретного языка программирования, но как вы себе это представляете?
Не представляю, и я писал об этом. Вы даже со мной тогда согласились. Гарантированно убедиться в идентичности поведения двух черных ящиков нельзя. Можно только опровергнуть, если сильно повезет.
S>>Без изменяемого поведения. Отсутствие изменяемого поведения — это тоже поведение. Не могу себе представить объект без поведения совсем. Ничего не делает — значит такое у него поведение. S>Чтобы вы начали себе представлять объект без поведения, желательно ввести формальное определение поведения. S>Можно попробовать по аналогии — начать представлять себе объект без состояния; (а то ведь можно сказать что "это у него такое состояние), а потом уже можно и без поведения представить.
Под объектом без состояния я понимаю объект без изменяемого состояния. При условии детерминированности оно же будет означать неизменность поведения.
S>>>2. Ваше предложение противоречит определению, которое требует от идентичности возможности различать разные объекты. S>>Оно позволяет различать объекты с разным поведением. S>Определение выдвигает более сильное требование — иметь возможность различать объекты независимо от поведения. А, значит, и объекты с одинаковым поведением.
Вычислять? Нет, там такого требования нет. Определять — да. Определить мы можем, предположив что дождались результата невычислимого ID.
S>>>Тем не менее, вы упорно приводите примеры, когда ваше определение идентичности приводит к неразличимости разных объектов. S>>Да, но разных объектов с неразличимым поведением. S>Мало ли что у них ещё неразличимо. Они разные — этого достаточно для несоответствия определению.
Это смущает.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Но вот следствие из википедии S>>>
S>>>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>>>согласно ему a и b идентичны. Верно? Да и ссылка на same type есть, т.е. для любого типа это не надо показывать.
G>>Это глупость написана. S>Это надо доказывать. G>>Банально опровергается сравнением ссылок. S>Для этого надо доказать что все идентичные объекты обладают равными ссылками. Формально.
Это в спецификации языка C# написано, синклер приводил. Для других языков можно найти аналогичное.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>надо поменять причину и следствие? Но тогда мы получим что-то не совсем осмысленное. S>>IF object identity of two objects of the same type is the same, THEN every change to either object is also a change to the other object. S>Мы получим почти точную перефразировку фразы, которую вы привели из другого источника.
Верно. За исключением same type.
S>>Для чего здесь уточнение same type? Что бы мы не взяли объекты с same identity но разного типа? Если забить на эту неувязку с same type, то в остальном — вполне осмысленная и верифицируемая фраза. Если бы она была в таком виде в википедии я бы не удивился. S>Если это следствие, то оно должно выводиться из определения. Кокретно это следствие никак не выводится.
Да.
S>>Я вижу что я понимаю смысл термина не так как остальные на этом форуме. Это для меня очевидно. S>И как все остальные в мире — тоже. Вы сами привели уже кучу ссылок. Везде получается так, что идентичность в ООП позволяет отличать любые объекты друг от друга.
Да S>Вне ООП можно определять идентичность по-другому. Но это будет уже не ООП.
Да.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Я еще помню что идентификатор это не ссылка. Правда это идентификатор не объекта, а переменной. Но все равно, я считаю что обошелся без ссылки. S>Ну и зря вы так считаете. А если я напишу MyObj &obj2 = obj, то ссылка появится?
Ссылка как понятие C++ появится, технически появится алиас.
Но вы скорее всего правы, идентификатор MyObj obj будет соответствовать понятию ссылки в ООП. S>Расскажите мне в деталях, чем obj2 семантически будет отличаться от obj.
S>>Согласно чему? S>Согласно определению ООП.
S>>Не вижу другого отношения. S>Ну как же, у вас всё время фигурирует какая-то "логическая идентичность", неуловимо отличающаяся от "физической идентичности", которой пользуются все остальные. Она, очевидно, вводит другое отношение между объектами, не такое, как у всех. Почему же вы его не видите?
А, в этом смысле? Другое отношение эквивалентности? Это да.
S>>Отлично. Я тоже признаюсь. Я готов признать вашу с ganjustas-ом правоту относительно трактовки идентичности. Единственное что меня еще смущает — я допускаю другую трактовку. Можно списывать на мою упертость, но я все-таки считаю что определение не вполне однозначно. И некоторые моменты все-таки наводят на сомения. S>Определение в ООП вполне однозначно. То, что вы пытаетесь ввести в качестве логической идентичности — это эквивалентность в смысле дотнетного стандарта.
Нет, я пытался ввести не это.
S>Для value-типов в дотнете она же принята за идентичность. S>Именно о ней же ведёт речь тот единственный чувак, который упомянул сам термин logical, or internal identity.
Он — да. Он о структурной эквивалентности.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>>>Но вот следствие из википедии S>>>>
S>>>>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>>>>согласно ему a и b идентичны. Верно? Да и ссылка на same type есть, т.е. для любого типа это не надо показывать.
G>>>Это глупость написана. S>>Это надо доказывать.
Да, Sinclair мне уже открыл глаза на это.
G>>>Банально опровергается сравнением ссылок. S>>Для этого надо доказать что все идентичные объекты обладают равными ссылками. Формально.
G>Это в спецификации языка C# написано, синклер приводил. Для других языков можно найти аналогичное.
Будет время и силы — соберусь с мыслями и подумаю по поводу своего поведения. Прошу, не надо продолжать баталию.
Здравствуйте, samius, Вы писали: S>Что такое эквивалентность в смысле дотнетного стандарта? В ECMA-355 нет самостоятельного определения экивалентности, только упоминание ее в различных контекстах.
Вы опять как-то альтернативно читаете? Та же самая секция 8.2.5, подсекция 8.2.5.2 Equality.
S>структурная эквивалентность в смысле побитового совпадения областей памяти? Я пытался ввести эквивалентность поведения, что очевидно не то же самое, что структурная эквивалентность. Тогда ваше определение не совпадает даже с тем единственным местом, где хоть кто-то кроме вас вводит понятие логической идентичности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>>>Вот синклер написал что разные ссылки могут ссылаться на один объект. В таком случае идентичность этого объекта самому себе будет опровергнута. G>>Это зависит от реализации ссылки в языке, конкретно в C# ссылка и есть identity. А если в каком-то языке это не так, то там все равно есть способ получить некоторое инвариантное значение, которое мы и будем называть ссылкой. Например в БД это ключ записи. S>Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором.
Тогда как отразить identity в языке? Чтобы их можно было сравнить у двух объектов.
S>>>>>ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта? G>>>>В концептуальном определении их нет, но реализация identity во всех известных мне языках с поддержкой ООП опирается на ссылки в том или ином виде. Вообще слабо себе представляю ООП без ссылок. S>>>Это не проблемы концепции. Допустим, в некой реализации ссылки нельзя сравнивать. Ты скажешь что это не ООП на том основании что в известных тебе реализациях это не так? G>>Ок, приведи такую реализацию. S>В этом нет необходимости.
Есть, иначе ты не можешь утверждать что такие существуют.
G>>Но это ты пытаешься сменить тему. По сути ты хотел доказать что неравенство ссылок в C# может быть и для идентичных объектов. Тебе то не удастся. Поэтому ты начала извращать понятие identity разводя демагогию. S>Ты слишком узко смотришь на определение идентичности.
Я смотрю на определения ровно так: http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
При этом учитываю реализацию в современных языках.
S>>>Идентичность не зависит от поведения, но опираясь на наблюдаемое поведение можно опровергнуть логическую идентичность двух объектов. G>>Что такое логическая идентичность? S>Это идентичность, основанная на отсутствии свойств объектов, отличающих их. Под свойствами я подразумеваю не поля объекта и не свойства аксессоры к полям.
То есть поведение. Но по определению оно никаким боком к идентичности не относится.
S>Физический адрес я тоже не отношу к свойствам объекта.
Как выражается идентичность? Построй функцию id(object), чтобы id(a)==id(b) тогда и только тогда a и b совпадают. Необходимо чтобы функция не опиралась на ссылочное сравнение, не опиралась на поведение и состояние и работала для любых типов.
S>>>Ты не можешь доказать физическую идентичность. Следовательно ее нет? G>>Ок, давай выяснять что такое физическая идентичность. Покажи чем физическая идентичность отличается от ссылки? Напомню что в прошлом посте ты показал эквивалентность этих понятий. S>Они отличаются определением.
Определения у тебя неформальны, ты не можешь доказать что между ними какая-то разница есть
S>>>>>Это ссылочная эквивалентность а не идентичность. Из нее следует физическая идентичность. Из физической идентичности следует ссылочная эквивалентность. Но это не одно и то же. Понятия разные, но наблюдаются они у объекта одновременно. Смотри определения. G>>>> G>>>>Если A -> B && B -> A, то A == B, это формальная логика, можешь с ней не спорить. S>>>Нет такой логики. Есть такая: S>>>A => B && B => A, то A <=> B (читается тогда и только тогда) не путай их. Не делает чести. G>>
G>>Ты привел одно и тоже заменив -> на => и == на <=>. G>>http://www.ctc.msiu.ru/materials/Book2/ch_07_sheets/01_logic/03_implies/
G>>
G>>Другой распространенной операцией является эквивалентность. Ее аналог в разговорной речи — фразы, подобные словосочетанию тогда и только тогда, когда ... или если и только если ... Для ее обозначения используется символ <-> или просто =.
S>То что ты мне привел — это эквивалентность между высказываниями или формулами, когда они принимают одни и те же истинностные значения. Из эквивалентности высказываний не следует эквивалентность понятий, заданными разными определениями.
Очень даже следует потому что булева логика работает для предикатов любой природы. Этому на первом курсе любого технического вуза учат.
S>Ты же мне написал что физическая идентичность эквивалентна равеству ссылок, а потом поставил знак ==.
По тому что ты написал это так и есть. G>>На википедии кстати статьи про логическую эквивалентность нет, надо что-то кроме википедии читать S>выбирай, что читать.
Не надо выбирать, надо все читать
S>Следствие в википедии говорит об объектах одного типа.
Оно говорит глупость, которая опровергается банальным сравнением ссылок.
S>>>Только как ты не можешь доказать физическую идентичность объекта самому себе, так и я не смогу доказать логическую идентичность a и b. G>>Видимо ты не те определения выбрал что не можешь доказать что-то из них. S>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет.
Его не надо доказывать, в спецификации языка написано что ссылка есть identity.
S>>>Тем не менее, я их считаю их идентичными согласно определению. G>>Согласно определению они как раз неидентичны, потому что я тебе легко приведу выражение отличающее их друг от друга (угадай какое). S>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности.
Да, в определении есть функция id(object), которая id(a)==id(b) только когда a и b совпадают. Но как это реализовать не имея сравниваемых ссылок? Во всех известных мне реализациях используются ссылки для идентичности. Ты не можешь доказать что возможна идентичность без ссылок.
S>>>Что будешь делать если ссылки сравнить нельзя, либо как подметил Ikemefula, если две неравные ссылки ссылаются на один объект и из неравенства ссылок не следует неидентичность? G>>Приведи язык где нельзя сравнить ссылки? Если ссылки не одинаковы в битовом представлении, то есть инвариантный формат, их надо привести и сравнить. S>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет.
И как ты функцию id(object), которая id(a)==id(b) только когда a и b совпадают. Которая работает для любого типа, приведи код.
G>>Для простоты давай называть ссылкой инвариантый формат, чтобы не усложнять рассуждения. S>Незачем. Тебе C# позволяет привести ссылку к инвариантному формату?
Она уже в инвариантном формате.
G>>>>Одним написанием определений ты ничего не докажешь. Нужен код. S>>>Ты не написал код, убеждающий в идентичности объекта самому себе строго G>>object.ReferenceEquals(a,a) не? ведь ссылка работает как identity, тебе не удалось этого опровергнуть. S>Тебе не удалось это доказать.
Это в спецификации написано, Синклер приводил
G>>>>Идентичность и позволяет отличить объект от других, то есть id(a) == id(b) только когда a и b это один и тот же объект. S>>>Это выдумка, которая не следует из определения идентичности. В частности в определении не упоминается "один и тот же". G>>Да, там упоминается "отличить от других". Давай пререфразирую, id(a) != id(b) только когда a и b — разные объекты. Опять-таки формальная логика рулит, я просто сделал отрицание обеих частей выражения, таблица истинности не поменялась. S>Не рулит логика, когда неверен посыл. Докажи что разные объекты а и b будут иметь различные if(a) и id(b). Формально из определения, пожалуйста, а не руководствуясь домыслами о равенстве ссылок.
object identity — identity is that property of an object that distinguishes each object from all others
Значит существует функция id(object), которая id(a)!=id(b) только когда a и b разные объекты. Соответственно когда они одинаковые объекты, то совпадают.
S>>>Мне необязательно доказывать тебе возможность существования другой реализации конкретным примером. Хотя ключ я уже дал. Представь себе ООП систему, где невозможно сравнение ссылок либо убеди себя что такой не может существовать. G>>Ок, представим. Как ты в такой системе обеспечишь identity? Как ты напишешь выражение, которое позволяет отличить один объект от другого? S>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity.
object identity — identity is that property of an object that distinguishes each object from all others
Выделенное слово означат различать.
G>>>>Так приведи код, который проверит "логическую идентичность". S>>>Приведи код, который проверит физическую идентичность формально, а не по ReferenceEquals. G>>Давай начнем с определения "физической идентичности", что это такое? Как оно выражается в языке? S>Определение то же самое. Выражения в языке нет. ReferenceEquals выражает равенство ссылок а не идентичность. Покажи что не найдется свойства, по которым можно отличить объект от самого себя. Кодом!
Это написано в спецификации языка. Более того, даже если не написано то по всем наблюдаемым признакам ссылка ведет себя как identity — походит под все
определения и реализует все свойства.
G>>>>В соответствии с высказыванием ты утверждаешь что бывает так что Object.ReferenceEquals(a,b) == false, но это один и тот же объект. S>>>Я такого не утвреждаю. G>>А что тогда утверждаешь? только кодом. S>Я утверждаю что из неравенства ссылок может следовать same identity.
Приведи пример, функция id(object), которая id(a)==id(b), но a!=b. При этом работает для любых типов, не опирается на состояние и поведение объекта.
S>Кодом я identity записать не могу. Да и ты пока не смог.
Еще раз: по спецификации ссылка и есть identity, а даже если не так, то по всем наблюдаемым признакам ссылка ведет себя как identity.
G>>>>Приведи пример языка где инвариантные ссылки не совпадают, но это один и тот же объект. S>>>Это не обязательно. Я рассуждаю о концептуальной модели, а не о частной ее реализации. G>>Рассуждать можно о чем угодно, даже том чего не существует. В программировании легко провести эксперимент, он не требует ничего кроме умственных усилий и немного времени. Покажи пример того о чем ты пытаешься рассуждать. S>См. пример с monostate.
Там нет идентичности, я банально могу различить эти два объекта. При same identity это было бы невозможно.
G>>Я говорю что во всех практических реализациях есть ссылки на объекты (инвариантные ссылки если угодно), которые как раз выполняют роль identity. При этом сами ссылки могут не совпадать (COM), но приводятся к инварианту, которые совпадают для одинаковых объектов, также ссылки могут иметь непостоянное битовое представление (.NET и Java). Могут быть сложными значениями — ключи строк в БД. S>Я говорю об концептуальной модели а не о практических реализациях.
Приведи реализацию idenity без ссылок.
G>>Ты же понамешал сюда логическую и физическую идентичность, при этом не можешь дать определение ни одной, ни другой. G>>Это и есть демагогия. S>Я давал. Еще раз. Физическая идентичность — идентичность основанная на равенстве ссылок/адресов/хэндлов/уникальных системных идентификаторов. Хочется назвать ее суррогатной идентичностью, т.к. ссылки и т.п. не имеют отношения к объекту, его состоянию и поведению. Логическая идентичность — идентичность, которая основывается на наблюдаемом поведении объекта. И да, я знаю что поведение и состояние не влияют на идентичность. Потому предлагается устанавливать идентичность по разнице в наблюдаемом поведении.
Значит физическая идентичность — равенство ссылок. Или как еще понимать "основанная на"? А логическая идентичность — не идентичность вообще, потому что не соответствует определению отсюда.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: S>>Что такое эквивалентность в смысле дотнетного стандарта? В ECMA-355 нет самостоятельного определения экивалентности, только упоминание ее в различных контекстах. S>Вы опять как-то альтернативно читаете? Та же самая секция 8.2.5, подсекция 8.2.5.2 Equality.
Да, подсекция equality вводит отношение эквивалентности. Но я искал "equivalent"
S>>структурная эквивалентность в смысле побитового совпадения областей памяти? Я пытался ввести эквивалентность поведения, что очевидно не то же самое, что структурная эквивалентность. S> Тогда ваше определение не совпадает даже с тем единственным местом, где хоть кто-то кроме вас вводит понятие логической идентичности.
Не совпадает. Но некоторые объекты (например, неизменяемые) могут удовлетворить и моей и той версии со структурной эквивалентностью. Хотя они и не обязаны быть эквивалентными структурно.
Предлагаю на этом паузу. Будет время и силы (не сегодня — завтра) я внимательно пробегусь по определениям, попытаюсь переосмыслить, постараюсь не наделать глупостей и обещаю отписать о результатах.
Здравствуйте, samius, Вы писали:
S>>Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки. S>выполняет роль, но не является.
С точки зрения математики, "выполнять роль" и "являться" — одно и то же.
Если вы собираетесь переопределять значение термина "являться", то увольте меня от дальнейшей беседы. Ибо шизофрения — дивный мир, но я в него не вхож.
S>>Если бы следствие в википедии являлось действительно следствием, то его можно было бы формально доказать, исходя из определения там же. Увы. S>Верно. Тем более, в исправленной форме это следствие действительно упоминается неоднократно. S>Приближаюсь к объявлению капитуляции
S>Это своя реализация идентичности. Не интересно.
Что значит "своя"? А вы хотели чужую? Идентичность — это математическое понятие. Реализация идентичности — она всегда своя.
S>Для конкретной реализации — да.
А в общем случае они и не применимы. S>Да, для ECMA понятия идентичности это верно. Но обобщить до определения идентичности в ООП это нельзя.
Это верно.
S>Компилировать FCL в C#-- не надо, нет такой цели
А в чём цель? Я думал, вы хотите получить работоспособную ОО-модель. S>Имеет смысл если ID вычислима. Но я не говорил что она вычислима.
Если она невычислима, то у нас нет "способа отличать один объект от любого другого объекта". Упс. S>В той трактовке, что позволяет отличать любой объект от всех остальных — да.
Это не трактовка, это само определение.
S>Ну дак мы их отличать можем в теории, по некой невычислимой функции. Существования такой функции достаточно, вычислимость ее — это просто очень полезный бонус
Хм. Тут мои познания в computer science заканчиваются. Остаётся только смутное сомнение в
а) существовании невычислимых функций (чем оно отличается от несуществования такой функции?)
б) в применимости невычислимых функций в определениях моделей, применяемых для прикладного программирования. Мне кажется, что во всех местах, когда говорят "свойство того-то" или "функция от того-то", то везде неявно продразумевают "вычислимая детерминированная".
S>мы можем отличать объекты с отличным поведением (но только их). Отличать объекты с неотличимым поведением не нужно. Но это уже видимо моя додумка.
Да, это ваша додумка.
S>Про "следовать" погорячился. можем одновременно наблюдать неравенство ссылок и same identity.
Это правда, и это явно описано в википедии, хотя и не обосновано формально. S>Вот по этим изменениям я и предлагал определять идентичность.
Такая идентичность не будет сохраняться.
Поясню примером:
public class NonIdentic
{
public int A { get; set; }
}
...
var a = new NonIdentic();
var b = new NonIdentic();
(для упрощения предположим, что никаких других методов, кроме явно объявленных, у нас нет)
Вот у нас два экземпляра. Что такое их поведение? Это их реакция на сообщения. Сообщений экземпляру мы можем послать всего два. Пошлём им getA():
var r1 = a.A; var r2 = b.A;
Debug.Assert(r1 == r2);
Так, поведение одинаково.
Пошлём setA():
a.A = 1; b.A = 1;
var r1 = a.A; var r2 = b.A;
Debug.Assert(r1 == r2);
Опять то же самое. Какую бы цепочку сообщений getA/setA мы ни придумали, цепочка ответов от объектов a и b будет совершенно одинаковой. То есть их поведение — одинаково. Значит, у них должна быть одинаковая "логическая identity".
Однако, стоит нам сделать хоть что-то несимметричное, как их поведение тут же станет различным. Упс.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Да, подсекция equality вводит отношение эквивалентности. Но я искал "equivalent"
equivalence
S>Не совпадает. Но некоторые объекты (например, неизменяемые) могут удовлетворить и моей и той версии со структурной эквивалентностью. Хотя они и не обязаны быть эквивалентными структурно.
Ну а зачем нам такое определение идентичности, которое работает не для всех объектов?
Я не против его как отношения эквивалентности. Возможных отношений эквивалентности для объектов очень много. Отношение идентичности выделяется среди всех них особым свойством — оно вводит ровно столько классов эквивалентности, сколько у нас есть экземпляров объектов.
S>Предлагаю на этом паузу. Будет время и силы (не сегодня — завтра) я внимательно пробегусь по определениям, попытаюсь переосмыслить, постараюсь не наделать глупостей и обещаю отписать о результатах.
Ок. Я тоже уже сильно отстал от графика работ
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, Sinclair, Вы писали:
A>Пять копеек.
Это червонец, не меньше
A>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. A>Необходимым является само наличие ссылок (или чего-то, выполняющее их функцию). Функцией ссылки является обеспечение возможности обращения (вызова метода, посылки сообщения и т.п.) к конкретному объекту. A>Кроме того, нужна возможность разным ссылкам ссылаться на один и тот же объект. "Один и тот же объект" означает, что вызовы его методов и изменения его состояния через любую из ссылок, на него ссылающихся, абсолютно эквивалентны.
Более того, мы можем потребовать от реализации идентичности не создавать различные экземпляры объекта, чьи поведения будут неотличимы. Незачем. Тогда понятия "один и тот же объект" и неотличимость поведения будут следовать друг из друга. Как это будет расположено в памяти — никого не должно волновать, т.к. объекты будут формально отличаться по поведению, а не по location-у. Если объект невозможно изменить, он будет "синглтоном". Если можно — то как обычно. И то что его можно будет изменить отдельно от других объектов, определяет его идентичность.
Такая модель реализации будет соответствовать определению идентичности более чем вполне вместе с требованиями независимости ID от состояния и поведения объекта. Практическая ценность такой модели совершенно не интересует. Интересует принципиальная возможность существование идентичности в ООП, отличной от определяющейся через location и равенство ссылок.
В такой модели равенство ссылок все равно будет приводить к идентичности. Но определять равенство ссылок не требуется, а значит его можно опустить
A>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
S>>>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности. S>>Не надо путать определение идентичности и реализацию идентичности. S>>Применимость ссылок для идентичности в дотнете нетрудно доказать в два хода. A>+1 A>А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
идентичность в дотнете определена через locations, что является более сильной моделью, чем идентичность ООП.
S>>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает. A>Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности.
+1
S>>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений. A>Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны. A>Операции сравнения, как элемента языка, не требуется.
И я об этом.
Здравствуйте, artelk, Вы писали:
A>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно.
Вот это утверждение, на мой взгляд, является весьма сильным, и нуждается в доказательстве.
К примеру, я знаю, что стандартные коллекции сразу же перестанут работать.
Можно ли будет их чем-нибудь заменить, я не в курсе.
A>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
Не понял, кто накладывает "более сильные требования", и какие именно требования накладываются?
Опять же — оператор может вернуть false, оставаясь в рамках ECMA? По-моему, это неправда
A>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован.
Почему? В вашей фразе если ... и то ... никак не связаны между собой.
Для возможности использовать ID в качестве ссылки необходимо и достаточно иметь некоторую функцию Retrieve(GUID id), которая будет возвращать нужный нам объект. Но я про это ничего не писал и не предлагал использовать ID в качестве ссылки. Я предлагал использовать его в качестве identity.
A>Исключением является, например, случай, если ID копируется, а объект хранит свое состояние где-то вовне и "копии" разделяют это состояние (например, Active Record, каждый раз обращающийся к базе для получения\сохранения своего состояния с использованием ID в качестве ключа).
Ничего не понял, извините.
A>А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
Я же только что показал, как реализовать идентичность без использования ссылок. Нет, идентичность и ссылки друг из друга в общем случае не выводятся.
A>Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны. A>Операции сравнения, как элемента языка, не требуется.
Можно пояснить,что вы понимаете под "гарантировать тождественность"?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, Sinclair, Вы писали:
A>Пять копеек.
A>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно.
А как тогда узнать что пара объектов — один и тот же? Ведь на эту операцию завязано много чего.
A>Вот если выкинуть, например, из C++ указатели и ссылки, а любые "объекты" передавать по значению — ООП будет невозможен: A>
A>Хитрость еще в том, что даже тут идентификаторы a1 и a2, по сути, все еще являются ссылками. В строках //1 и //2 мы работаем все с тем же объектом. Только в языках с полным отсутствием изменяемого состояния возможно, чтобы идентификатор не был ссылкой.
Это неправда. Несмотря на синтаксическую конструкцию A a2 = a1, которая выглядит как присваивание, выполняется конструктор копирования. Что недвусмысленно говорит о копии объекта. но никак не том же самом объекте.
A>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
Покажи пример такого.
A>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. Не зависимо от того, как реализовано клонирование\копирование — с назначением нового ID или использованием того же.
Почему? Докажи.
A>А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
Ну да, ибо идентичность это функция вида ID(object), подчиняющаяся некоторым правилам. Если получить битовое представление результата этой функции, то его можно назвать "ссылкой". Другое дело что необязательно для каждой ссылки можно получить некоторый объект.
S>>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL. S>>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает. A>Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности.
В чем? Покажешь пример равенства ссылок без идентичности?
S>>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений. A>Первым делом ООП требует возможность гарантировать тождественность.
Тождественность — и есть совпадение identity в ООП.
A>Операции сравнения, как элемента языка, не требуется.
С учетом сказанного выше — требуется.
Здравствуйте, Sinclair, Вы писали:
S>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
S>А рич-модель бесплодно пытается приделать офицерской вдове метод "высечь". Или вместо того, чтобы породить экскаватор, пишет земля.копайся().
Опять же, анемик - явная ерунда, рич - непрактичная выдумка теоретиков.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, artelk, Вы писали:
A>>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. S>Вот это утверждение, на мой взгляд, является весьма сильным, и нуждается в доказательстве.
object.ReferenceEquals — метод из .NET Framework, а не элемент языка C#. S>К примеру, я знаю, что стандартные коллекции сразу же перестанут работать. S>Можно ли будет их чем-нибудь заменить, я не в курсе.
Заставлять реализовывать IEquatable или передавать отдельно IEqualityComparer.
A>>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а). S>Не понял, кто накладывает "более сильные требования", и какие именно требования накладываются?
Метод object.ReferenceEquals, для того, чтобы вернуть true, от переданных параметрами ссылок требует большего, чем чтобы они ссылались на идентичные объекты.
Возврат true означает, что имеет место идентичность. Но идентичность объектов не является достаточным условием, чтобы результатом было true. S>Опять же — оператор может вернуть false, оставаясь в рамках ECMA? По-моему, это неправда
Смотри:
var a1 = new SomeClass(...);
//какой-то кодvar a2 = a1;
//куча произвольного кода, со множеством обращений к объекту по ссылке a1
Если в этой "куче кода" в любых местах заменить обращение к a1 на обращение к a2, то поведение программы будет эквивалентно исходному.
Т.е. объект, на который ссылается a1 идентичен объекту, на который ссылается a2.
interface ISomeClass
{
method1(...);
//
methodN(...);
}
class SomeClass: ISomeClass
{
method1(...){...}
//
methodN(...){...}
}
class SomeClassProxy: ISomeClass
{
private readonly ISomeClass o;
SomeClassProxy(ISomeClass o) {this.o = o;}
method1(...){ o.method1(...); }
//
methodN(...){ o.methodN(...); }
}
ISomeClass a1 = new SomeClass(...);
//какой-то код
ISomeClass a2 = new SomeClassProxy(a1);
//куча произвольного кода, со множеством обращений к объекту по ссылке a1
Если в этой "куче кода" в любых местах заменить обращение к a1 на обращение к a2, то поведение программы будет эквивалентно исходному.
Т.е. объект, на который ссылается a1 идентичен объекту, на который ссылается a2, хотя object.ReferenceEquals(a1, a2) вернет false.
A>>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. S>Почему? В вашей фразе если ... и то ... никак не связаны между собой. S>Для возможности использовать ID в качестве ссылки необходимо и достаточно иметь некоторую функцию Retrieve(GUID id), которая будет возвращать нужный нам объект. Но я про это ничего не писал и не предлагал использовать ID в качестве ссылки. Я предлагал использовать его в качестве identity.
ID id = ...;
Retrieve(id).SomeMethod1();//1
Retrieve(id).SomeMethod2();//2
Если бы конструкция "Retrieve(???)." была элементом языка, то она была бы эквивалентна вызову через точку "???." (просто другой синтаксис), поэтому этот ID являлся бы ссылкой (смысл тот же)...
Если это метод — то нужно определить, что означает "возвращать нужный нам объект". В //1 и //2 мы работаем с тем же объектом? Retrieve возвращает что-то, через что можно обратиться к конкретному объекту? Так это ссылка. Т.е. ссылки уже должны поддерживаться языком.
Ок, по порядку.
samius>>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет.
var z = new Something(...);//генерируется уникальный ID
assert(ID(z) == ID(z));//z - ссылка!
В языке уже должны быть реализованы ссылки, чтобы ID мог бы быть использован для определения identity.
И Something должен быть ссылочным типом (классом).
Если он структура, то в ID передается копия. А копия, по твоей версии, имеет свой уникальный ID.
Второй случай (думаю, ты его имел ввиду), ссылок почти нет:
struct Something
{
public readonly ID id;
public Something()
{
id = ID.GetUniqueId();
}
//Копирование работает обычно, т.е. id копируетсяpublic int State {get;set;}
public Something Clone(){...}
}
var z1 = new Something(...);
z1.State = 1;//1var z2 = z1;//id копируется, значит должны быть идентичны
z2.State = 2;//2
assert(ID(z1) == ID(z2));//true
assert(z1.State == z2.State);//false, как же так?
Ссылки все еще есть, т.к. когда в строчках //1 и //2 мы обращаемся к z1 и z2, последние выступают в роли ссылок.
"z1.State = 1;" — мы обращаемся к тому же "объекту", что только что создали. При отсутствии копирования, структуры сохраняют свою идентичность.
Третий случай:
struct Something
{
public readonly ID id;
public Something()
{
id = ID.GetUniqueId();
//INSERT INTO table (ID, State) VALUES ($id, 0)
}
//Копирование работает обычно, т.е. id копируетсяpublic int State
{
get { //SELECT State FROM table WHERE ID = $id }set { //UPDATE table SET State=$value WHERE ID = $id }
}
public Something Clone(){...}
}
var z1 = new Something(...);
z1.State = 1;//даже если бы обращались к копии структурыvar z2 = z1;//id копируется, значит должны быть идентичны
z2.State = 2;//даже если бы обращались к копии структуры
assert(ID(z1) == ID(z2));//true
assert(z1.State == z2.State);//true!
Более того, ID может работать как ссылка (при наличие Retrieve):
Причем Retrieve может быть как элементом языка, так и функцией, возвращающей копию структуры.
A>>Исключением является, например, случай, если ID копируется, а объект хранит свое состояние где-то вовне и "копии" разделяют это состояние (например, Active Record, каждый раз обращающийся к базе для получения\сохранения своего состояния с использованием ID в качестве ключа). S>Ничего не понял, извините.
Я имел ввиду третий случай.
S>Нет, идентичность и ссылки друг из друга в общем случае не выводятся.
Как-то так:
Сослаться можно только на то, что обладает идентичностью.
Идентичность — возможность сослаться на конкретный объект.
A>>Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны. A>>Операции сравнения, как элемента языка, не требуется. S>Можно пояснить,что вы понимаете под "гарантировать тождественность"?
var a1 = new SomeClass(...);
var a2 = a1;
a2.Method();//тождественно a1.Method()
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, Sinclair, Вы писали:
S>>Здравствуйте, artelk, Вы писали:
A>>>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. S>>Вот это утверждение, на мой взгляд, является весьма сильным, и нуждается в доказательстве. A>object.ReferenceEquals — метод из .NET Framework, а не элемент языка C#.
По секрету
var a = new object();
var b = new object();
Debug.Assert(a == b)
Посмотри в IL во что оператор сравнения компилируется
S>>К примеру, я знаю, что стандартные коллекции сразу же перестанут работать. S>>Можно ли будет их чем-нибудь заменить, я не в курсе. A>Заставлять реализовывать IEquatable или передавать отдельно IEqualityComparer.
Тебя слово Equality не смущает? Оно недвусмысленно говорит об эквивалентности, а не об идентичности. Прочитай посты где были приведены ссылки на стандарт.
A>>>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а). S>>Не понял, кто накладывает "более сильные требования", и какие именно требования накладываются? A>Метод object.ReferenceEquals, для того, чтобы вернуть true, от переданных параметрами ссылок требует большего, чем чтобы они ссылались на идентичные объекты. A>Возврат true означает, что имеет место идентичность. Но идентичность объектов не является достаточным условием, чтобы результатом было true.
Ок, покажи пример когда object.ReferenceEquals возвращает true для разных объектов.
S>>Опять же — оператор может вернуть false, оставаясь в рамках ECMA? По-моему, это неправда
A>Если в этой "куче кода" в любых местах заменить обращение к a1 на обращение к a2, то поведение программы будет эквивалентно исходному. A>Т.е. объект, на который ссылается a1 идентичен объекту, на который ссылается a2.
Путаешь эквивалентность и идентичность. Эквивалентность — любое симметричное, рефлексивное и транзитивное отношение, идентичность двух объектов — такое отношение в котором объект эквивалентен только сам себе, при это отношение не опирается на состояние и поведение объекта.
A>>>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. S>>Почему? В вашей фразе если ... и то ... никак не связаны между собой. S>>Для возможности использовать ID в качестве ссылки необходимо и достаточно иметь некоторую функцию Retrieve(GUID id), которая будет возвращать нужный нам объект. Но я про это ничего не писал и не предлагал использовать ID в качестве ссылки. Я предлагал использовать его в качестве identity.
A>Второй случай (думаю, ты его имел ввиду), ссылок почти нет: A>
A>struct Something
A>{
A> public readonly ID id;
A> public Something()
A> {
A> id = ID.GetUniqueId();
A> }
A> //Копирование работает обычно, т.е. id копируется
A> public int State {get;set;}
A> public Something Clone(){...}
A>}
A>var z1 = new Something(...);
A>z1.State = 1;//1
A>var z2 = z1;//id копируется, значит должны быть идентичны
A>z2.State = 2;//2
A>assert(ID(z1) == ID(z2));//true
A>assert(z1.State == z2.State);//false, как же так?
A>
A>Ссылки все еще есть, т.к. когда в строчках //1 и //2 мы обращаемся к z1 и z2, последние выступают в роли ссылок. A>"z1.State = 1;" — мы обращаемся к тому же "объекту", что только что создали. При отсутствии копирования, структуры сохраняют свою идентичность.
Ага, потому что value типы в CLR не соответствуют ООП. Мы тут рассматриваем только reference-типы.
S>>Нет, идентичность и ссылки друг из друга в общем случае не выводятся. A>Как-то так: A>Сослаться можно только на то, что обладает идентичностью. A>Идентичность — возможность сослаться на конкретный объект.
Нет, определение не говорит нам о возможности "сослаться", то есть об операции dereferencig. Но без нее реализация скорее всего невозможна. Хотя могут быть случаи что не всегда можно сделать dereferencig.
Здравствуйте, gandjustas, Вы писали:
S>>>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
ANS>>Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
G>Ага, фаулер говорит что anemic — не ООП, и все сразу верят.
Ну, я как бы, думал, что ты что-то своё под этим понимаешь. Я тут у многих заметил склонность к изобретению своих трактовок терминов и их ниспровержению. То примитивный мапер лёгким ОРМ обзовут, то еще что. Даже ссылку дал, дабы прояснить горизонты. И любому здравомыслящему человеку сразу видно, что описанное по ссылке не ОО-подход
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
S>>>>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
ANS>>>Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
G>>Ага, фаулер говорит что anemic — не ООП, и все сразу верят.
ANS>Ну, я как бы, думал, что ты что-то своё под этим понимаешь. Я тут у многих заметил склонность к изобретению своих трактовок терминов и их ниспровержению. То примитивный мапер лёгким ОРМ обзовут, то еще что. Даже ссылку дал, дабы прояснить горизонты. И любому здравомыслящему человеку сразу видно, что описанное по ссылке не ОО-подход
Там написано что это не ОО-подход, но доказательств этому нету. Более того по формальным признакам anemic не менее ОО, чем rich.
Здравствуйте, Sinclair, Вы писали:
ANS>>Ну, я как бы, думал, что ты что-то своё под этим понимаешь. Я тут у многих заметил склонность к изобретению своих трактовок терминов и их ниспровержению. То примитивный мапер лёгким ОРМ обзовут, то еще что. Даже ссылку дал, дабы прояснить горизонты. И любому здравомыслящему человеку сразу видно, что описанное по ссылке не ОО-подход S>Ага. При этом старина Мартин пользуется известным маркетинговым приёмом — сначала приводит вполне себе внятное описание Service Objects, а затем пишет "а, ну так это — практически то же самое, что и Transaction Script". А раз Transaction Script — чисто процедурное овно, значит такова же и Anemic Model.
Извини, я до этого места статью был не дочитал Я остановился на втором абзаце. И сходу вопрос, почему "Transaction Script" это "чисто процедурное овно"?
S>А реально изо всех фатальных недостатков Anemic Model приведён только один: затраты на модель предметной области и на ORM без бенефитов. S>Тут я склонен частично согласиться, а частично нет: S>- в современных системах, затраты на поддержание маппинга вполне себе приемлемые. Особено если не пытаться вдуть в domain model сложные иерархии наследования. S>- бенефит по сравнению с прямой манипуляцией RDBMS в том, что у нас есть богатые метаданные. В частности, можно привязывать внятные правила по валидации данных и иметь сквозные гарантии по всему стеку — от UI до базы данных. При этом выносить эти правила в уровень сервисов как раз неудобно.
Вот-вот. Я специально сверху оставил строчку. Похоже я прав, ибо не понимаю при чем тут метаданные. Метаданные это хорошо.
А плохо когда гигантские структуры с гетерами/сетерами передаются туда-сюда. Наличие LazyLoad всё усугубляет, но и без него картина выглядит не очень.
S>В остальном, в принципе, объекты для "предметной области" действительно не нужны. Объекты нужны для того, чтобы манипулировать элементами предметной области,
Так против этого как раз я не возражаю, а только "за".
S>а про это Фаулер напрямую врёт.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
A>>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. G>А как тогда узнать что пара объектов — один и тот же? Ведь на эту операцию завязано много чего.
А требуется ли это многое, чтобы разработка в ООП стиле была возможна?
A>>Вот если выкинуть, например, из C++ указатели и ссылки, а любые "объекты" передавать по значению — ООП будет невозможен: A>>
A>>Хитрость еще в том, что даже тут идентификаторы a1 и a2, по сути, все еще являются ссылками. В строках //1 и //2 мы работаем все с тем же объектом. Только в языках с полным отсутствием изменяемого состояния возможно, чтобы идентификатор не был ссылкой. G>Это неправда. Несмотря на синтаксическую конструкцию A a2 = a1, которая выглядит как присваивание, выполняется конструктор копирования. Что недвусмысленно говорит о копии объекта. но никак не том же самом объекте.
Да, a1 и a2 — ссылки на разные объекты. Посмотри где поставлены комментарии //1 и //2.
A>>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а). G>Покажи пример такого.
Объект и его прокси.
S>>>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>>>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL. S>>>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает. A>>Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности. G>В чем? Покажешь пример равенства ссылок без идентичности? более сильное
Здравствуйте, gandjustas, Вы писали:
ANS>>>>Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
G>>>Ага, фаулер говорит что anemic — не ООП, и все сразу верят.
ANS>>Ну, я как бы, думал, что ты что-то своё под этим понимаешь. Я тут у многих заметил склонность к изобретению своих трактовок терминов и их ниспровержению. То примитивный мапер лёгким ОРМ обзовут, то еще что. Даже ссылку дал, дабы прояснить горизонты. И любому здравомыслящему человеку сразу видно, что описанное по ссылке не ОО-подход
G>Там написано что это не ОО-подход, но доказательств этому нету. Более того по формальным признакам anemic не менее ОО, чем rich.
То, что описано во втором абзаце выглядит не красиво.
По теории код отдельно от данных это не ОО. Если говорить о практической стороне, то ты же сам знаешь, что если в качестве параметра передать в метод структуру из сотни элементов, то метод получает связь со всеми элементами. А если там есть мутаторы, то вообще "Ой".
Как Это можно защищать я не понимаю. Отсюда делаю вывод, что защищают какое-то своё понимание термина "анемик".
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, artelk, Вы писали:
A>>>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. G>>А как тогда узнать что пара объектов — один и тот же? Ведь на эту операцию завязано много чего. A>А требуется ли это многое, чтобы разработка в ООП стиле была возможна?
Это философский вопрос. Но судя по реализации стандартных библиотек java и .net — требуется.
A>>>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а). G>>Покажи пример такого. A>Объект и его прокси.
Пример кода покажи, а то непонятно чем ты.
S>>>>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>>>>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL. S>>>>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает. A>>>Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности. G>>В чем? Покажешь пример равенства ссылок без идентичности? A>более сильное
Ну да, покажи пример идентичности без равенства ссылок.
Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
Здравствуйте, gandjustas, Вы писали:
G>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
Не "не опирается", а не зависит от них (independent). Это значит что функция должна выдавать результат тот же самый для того же объекта в любом состоянии.
var id1 = id(a);
a.UpdateState();
Assert(id1 == id(a));
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
S>Не "не опирается", а не зависит от них (independent).
Это тоже самое.
S>Это значит что функция должна выдавать результат тот же самый для того же объекта в любом состоянии. S>var id1 = id(a); S>a.UpdateState(); S>Assert(id1 == id(a));
Вот только id должно принимать object чтобы не опираться на состояние и поведение. Вот и напиши такую функцию.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Здравствуйте, gandjustas, Вы писали:
G>>>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
S>>Не "не опирается", а не зависит от них (independent). G>Это тоже самое.
нет
S>>Это значит что функция должна выдавать результат тот же самый для того же объекта в любом состоянии. S>>var id1 = id(a); S>>a.UpdateState(); S>>Assert(id1 == id(a)); G>Вот только id должно принимать object чтобы не опираться на состояние и поведение. Вот и напиши такую функцию.
Написать не возьмусь. Я допускаю существование функции, о которой говорю. Соответственно, допуская это, я никому не обязан ее предоставить. Если ты утверждаешь что ее не может существовать, то что бы убедить в этом кого-нибудь, тебе следует показать это формально, а не требовать с меня реализацию на C#.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
G>>>А как тогда узнать что пара объектов — один и тот же? Ведь на эту операцию завязано много чего. A>>А требуется ли это многое, чтобы разработка в ООП стиле была возможна? G>Это философский вопрос. Но судя по реализации стандартных библиотек java и .net — требуется.
Приведи пример задачи, которую, оставаясь в рамках ООП парадигмы, нельзя решить без операции сравнения ссылок.
A>>>>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а). G>>>Покажи пример такого. A>>Объект и его прокси. G>Пример кода покажи, а то непонятно чем ты.
Берем http://exposedobject.codeplex.com/
Код:
dynamic a = new A {X = 42};
dynamic d = ExposedObject.From(a);
Console.WriteLine(d.X);//42
Console.WriteLine(object.ReferenceEquals(a, d));//false!!!
Идентичность в .NET — более узкое понятие, чем в ООП.
Или ты будешь утверждать, что a и d не идентичны?
S>>>>>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>>>>>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL. S>>>>>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает. A>>>>Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности. G>>>В чем? Покажешь пример равенства ссылок без идентичности? A>>более сильное G>Ну да, покажи пример идентичности без равенства ссылок. G>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
"Равенство ссылок без идентичности" != "идентичность без равенства ссылок" .
Пример привел выше
Здравствуйте, gandjustas, Вы писали:
G> Например до смешного популяризировали паттерн Repository, который при наличии мощных ORM почти не нужен.
И, кстати,
1. обвинять популяризатора в том, что предлагаемое ими стало популярным — это странно.
2. мне помнится ты, утверждал, что мощные ORM это фигня, а вот "лёгкие" — это вещь.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Здравствуйте, gandjustas, Вы писали:
G>>>>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
S>>>Не "не опирается", а не зависит от них (independent). G>>Это тоже самое. S>нет
С точки зрения математики — да. Функция не зависит от некоторых параметров, это значит что при вычислении функции они не используются, значит что не опирается на них.
Мы же не в лингвистическом клубе, а на техническом форуме.
S>>>Это значит что функция должна выдавать результат тот же самый для того же объекта в любом состоянии. S>>>var id1 = id(a); S>>>a.UpdateState(); S>>>Assert(id1 == id(a)); G>>Вот только id должно принимать object чтобы не опираться на состояние и поведение. Вот и напиши такую функцию. S>Написать не возьмусь. Я допускаю существование функции, о которой говорю. Соответственно, допуская это, я никому не обязан ее предоставить. Если ты утверждаешь что ее не может существовать, то что бы убедить в этом кого-нибудь, тебе следует показать это формально, а не требовать с меня реализацию на C#.
Именно обязан. В математике нет "презумпции невиновности", есть аксиомы, остальное надо доказывать.
Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет
Ты доказать существование такой функции id, которая не является object.ReferenceEquals в C# не можешь. Значит нет такой функции. Значит object.ReferenceEquals является функцией сравнения identity, значит ссылка и есть identity.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>Фаулер опирается на заблуждение
ANS>Это не заблуждение, это примитивизация.
Нет, это именно заблужение. До буча с мейером никто не говорил что объекты — данные+методы, обязательно вместе. Откуда это они взяли — неизвестно. Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния.
G>>Причем это очень далеко ушло от первоначальных идей ООП и преимуществ, которые они давали. ANS>например, про преимущества ты поскипал, а придрался к "теории".
Я придрался к "теории" фаулера и компании, а не к ООП.
Здравствуйте, samius, Вы писали:
G>>Вот только id должно принимать object чтобы не опираться на состояние и поведение. Вот и напиши такую функцию. S>Написать не возьмусь. Я допускаю существование функции, о которой говорю. Соответственно, допуская это, я никому не обязан ее предоставить. Если ты утверждаешь что ее не может существовать, то что бы убедить в этом кого-нибудь, тебе следует показать это формально, а не требовать с меня реализацию на C#.
То есть ктото должен приводить формальное доказательство что твои допущения и выводы где то ущербны ?
Во всём мире другой подход — допускатель не просто допускает, а делает своё допущение верифицируемым и фальсифицируемым. И как то эта часть в твоих допущениях отсутствует, потому неудивительно, что в трёх приведеных тобой определениях идентити указано "independent of its state or behavior", но ты всё равно за уши притягиваешь это самое поведение. И уж совсем неудивительно видеть "повсеместное неправильное толкования ".
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, artelk, Вы писали:
G>>>>А как тогда узнать что пара объектов — один и тот же? Ведь на эту операцию завязано много чего. A>>>А требуется ли это многое, чтобы разработка в ООП стиле была возможна? G>>Это философский вопрос. Но судя по реализации стандартных библиотек java и .net — требуется. A>Приведи пример задачи, которую, оставаясь в рамках ООП парадигмы, нельзя решить без операции сравнения ссылок.
Collection.Remove(object), если не переопределять equals, то она вычисляется как сравнение ссылок.
A>dynamic a = new A {X = 42};
A>dynamic d = ExposedObject.From(a);
A>Console.WriteLine(d.X);//42
A>Console.WriteLine(object.ReferenceEquals(a, d));//false!!!
A>
Ты привел пример разных объектов.
A>Идентичность в .NET — более узкое понятие, чем в ООП. A>Или ты будешь утверждать, что a и d не идентичны?
Конечно не идентичны, они даже не эквивалентны. У них даже типы разные.
G>>>>В чем? Покажешь пример равенства ссылок без идентичности? A>>>более сильное G>>Ну да, покажи пример идентичности без равенства ссылок. G>>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта. A>"Равенство ссылок без идентичности" != "идентичность без равенства ссылок" .
Да, это я ночью писал, ошибся. Тебе нужен пример где два объекта идентичны, то есть это один объект по сути. Но ссылки на него не равны.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>> Например до смешного популяризировали паттерн Repository, который при наличии мощных ORM почти не нужен.
ANS>И, кстати, ANS>1. обвинять популяризатора в том, что предлагаемое ими стало популярным — это странно.
Совсем нет, ибо популярной стала идея, которая в наше время не нужна.
ANS>2. мне помнится ты, утверждал, что мощные ORM это фигня, а вот "лёгкие" — это вещь.
Да, вещь. На самом деле почти любой orm делает паттерн repository ненужным.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>Да, вещь. На самом деле почти любой orm делает паттерн repository ненужным.
ANS>Это ничего, что сегодня так называемые "ORM" без реализации Репозитория никому не нужны и их днём с огнём не сыскать?
Я не про это, я как раз про обратный эффект что несмотря на то что repository, query object, unit of work, data mapper, identity map и многие другие паттерны уже встроены в orm, люди продолжают писать свои приложения реализуя паттерны самостоятельно, которые внутри делегируют все тому же orm.
При этом называют это правильной архитектурой.
Все это потому что фаулер и компания привели довольно мало технических доводов про использование тех или иных паттернов, зато очень много маркетологического буллшита.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
S>>>>Не "не опирается", а не зависит от них (independent). G>>>Это тоже самое. S>>нет G>С точки зрения математики — да. Функция не зависит от некоторых параметров, это значит что при вычислении функции они не используются, значит что не опирается на них.
С точки зрения математики функция это правило однозначного отображения области определения в область значений. Независимость функции от чего либо не означает неучастие этого чего-либо в неких вычислениях (что такое вычисление в отношении математической функции?), а означает отсутствие влияния этого чего-либо на результат. Я могу задать функцию, которая будет учитывать фазу луны, но если результат функции будет тем же для любой фазы луны — это значит что функция не будет зависеть от фазы луны. G>Мы же не в лингвистическом клубе, а на техническом форуме.
Не я привел термин "опираться".
S>>Написать не возьмусь. Я допускаю существование функции, о которой говорю. Соответственно, допуская это, я никому не обязан ее предоставить. Если ты утверждаешь что ее не может существовать, то что бы убедить в этом кого-нибудь, тебе следует показать это формально, а не требовать с меня реализацию на C#. G>Именно обязан. В математике нет "презумпции невиновности", есть аксиомы, остальное надо доказывать.
Функция Дирихле существует? Напиши, пожалуйста ее на С#, что бы работала для иррациональных чисел тоже. Или на чем угодно другом, но что бы работала... Может хотя бы доказательство ее существования предъявишь?
Что бы не разводить на пустом месте болтовню: существование функций (т.е. правил отображения) можно оспорить лишь определением функции. Например, если правило неоднозначно — его нельзя принять за функцию. Иначе, функция существует как только сформулировали правило. Оспаривают и доказывают утверждения о свойствах этих правил/функций.
Как только я сформулирую правило (я его еще не сформулировал) — ты можешь оспаривать тот факт что это правило сответствует определению функции, удовлетворяет понятию идентичности в ООП. Но вот оспаривать существование такого правила — с этим обращайся к филологам.
G>Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет
2) это ты придумал. identity — это то что отличает объекты от остальных. Именно identity говорит где одинаковые объекты, а где разные. Иначе тебе придется показать мне определение одинаковых объектов в OOP. Только не надо про memory location
G>Ты доказать существование такой функции id, которая не является object.ReferenceEquals в C# не можешь. Значит нет такой функции.
Значит функции Дирихле тоже нет G>Значит object.ReferenceEquals является функцией сравнения identity, значит ссылка и есть identity.
это написано в определении identity ECMA. А отношение этого всего к OOP Identity лишь то, что identity на memory location ему удовлетворяет, но не исчерпывает его. Подтверждение этому — пример identity на GUID-ах, которое приводил Синклер. Если ты не считаешь что такой identity на GUID-ах может быть принят за OOP identity, то с этим не ко мне
А я у Синклера попрошу прощения за такую стрелку.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>>>Формально идентичность это id(object), id(a)==id(b) тогда и только тогда когда a и b совпадают. При этом функция id не опирается на состояние и поведение объекта.
S>>>>>Не "не опирается", а не зависит от них (independent). G>>>>Это тоже самое. S>>>нет G>>С точки зрения математики — да. Функция не зависит от некоторых параметров, это значит что при вычислении функции они не используются, значит что не опирается на них. S>С точки зрения математики функция это правило однозначного отображения области определения в область значений. Независимость функции от чего либо не означает неучастие этого чего-либо в неких вычислениях (что такое вычисление в отношении математической функции?), а означает отсутствие влияния этого чего-либо на результат. Я могу задать функцию, которая будет учитывать фазу луны, но если результат функции будет тем же для любой фазы луны — это значит что функция не будет зависеть от фазы луны.
Тривиальные вычисления, которые всегда дают одинаковый результат на любых входных данных, можно исключить из рассмотретрения, заменив их константами.
Проделав это простое преобразование у тебя функция не опирается на фазы луны.
S>>>Написать не возьмусь. Я допускаю существование функции, о которой говорю. Соответственно, допуская это, я никому не обязан ее предоставить. Если ты утверждаешь что ее не может существовать, то что бы убедить в этом кого-нибудь, тебе следует показать это формально, а не требовать с меня реализацию на C#. G>>Именно обязан. В математике нет "презумпции невиновности", есть аксиомы, остальное надо доказывать. S>Функция Дирихле существует?
Да.
S>Напиши, пожалуйста ее на С#, что бы работала для иррациональных чисел тоже. Или на чем угодно другом, но что бы работала... Может хотя бы доказательство ее существования предъявишь?
Не получится, в компьютере нет иррациональных чисел.
То есть функция дирихле всегда будет возвращать 1.
S>Как только я сформулирую правило (я его еще не сформулировал) — ты можешь оспаривать тот факт что это правило сответствует определению функции, удовлетворяет понятию идентичности в ООП. Но вот оспаривать существование такого правила — с этим обращайся к филологам.
Ты еще должен доказать что оно аксиомам не противоречит как минимум. Тебе это пока не удалось сделать.
G>>Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет
S>2) это ты придумал. identity — это то что отличает объекты от остальных. Именно identity говорит где одинаковые объекты, а где разные. Иначе тебе придется показать мне определение одинаковых объектов в OOP.
Ты говоришь что я что-то придумал, а потом повторяешь то же самое что я сказал другими словами. Формализуй выделенное выше, получится ровно то же самое.
G>>Ты доказать существование такой функции id, которая не является object.ReferenceEquals в C# не можешь. Значит нет такой функции. S>Значит функции Дирихле тоже нет
Она есть, но на компьютере её выразить нельзя так как иррациональных числе нет.
То есть функция дирихле всегда будет возвращать 1.
G>>Значит object.ReferenceEquals является функцией сравнения identity, значит ссылка и есть identity. S>это написано в определении identity ECMA. А отношение этого всего к OOP Identity лишь то, что identity на memory location ему удовлетворяет, но не исчерпывает его. Подтверждение этому — пример identity на GUID-ах, которое приводил Синклер. Если ты не считаешь что такой identity на GUID-ах может быть принят за OOP identity, то с этим не ко мне
А я не говорил про memory location. Более того, неоднократно тебе пояснял что ссылка в разных системах может быть разная.
Это ты понимаешь ссылку узко, как memory location.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>С точки зрения математики функция это правило однозначного отображения области определения в область значений. Независимость функции от чего либо не означает неучастие этого чего-либо в неких вычислениях (что такое вычисление в отношении математической функции?), а означает отсутствие влияния этого чего-либо на результат. Я могу задать функцию, которая будет учитывать фазу луны, но если результат функции будет тем же для любой фазы луны — это значит что функция не будет зависеть от фазы луны. G>Тривиальные вычисления, которые всегда дают одинаковый результат на любых входных данных, можно исключить из рассмотретрения, заменив их константами. G>Проделав это простое преобразование у тебя функция не опирается на фазы луны.
Это будет другая функция. Равная, но другая, потому как будет задана другим правилом.
G>>>Именно обязан. В математике нет "презумпции невиновности", есть аксиомы, остальное надо доказывать. S>>Функция Дирихле существует? G>Да.
И что, тебе не надо доказывать ее существование кодом на C#? Почему к моей функции у тебя другое отношение?
S>>Напиши, пожалуйста ее на С#, что бы работала для иррациональных чисел тоже. Или на чем угодно другом, но что бы работала... Может хотя бы доказательство ее существования предъявишь? G>Не получится, в компьютере нет иррациональных чисел. G>То есть функция дирихле всегда будет возвращать 1.
Жаль
S>>Как только я сформулирую правило (я его еще не сформулировал) — ты можешь оспаривать тот факт что это правило сответствует определению функции, удовлетворяет понятию идентичности в ООП. Но вот оспаривать существование такого правила — с этим обращайся к филологам. G>Ты еще должен доказать что оно аксиомам не противоречит как минимум. Тебе это пока не удалось сделать. G>>>Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет
Это не аксиомы, это определение идентичности OOP. Я докажу что она не противоречит. Только ты их неверно понимаешь. Оба пункта.
S>>2) это ты придумал. identity — это то что отличает объекты от остальных. Именно identity говорит где одинаковые объекты, а где разные. Иначе тебе придется показать мне определение одинаковых объектов в OOP. G>Ты говоришь что я что-то придумал, а потом повторяешь то же самое что я сказал другими словами. Формализуй выделенное выше, получится ровно то же самое.
Для меня не то же самое. Покажи определение одинаковых объектов, а то твоя версия пункта 2 опирается на него..
G>>>Ты доказать существование такой функции id, которая не является object.ReferenceEquals в C# не можешь. Значит нет такой функции. S>>Значит функции Дирихле тоже нет G>Она есть, но на компьютере её выразить нельзя так как иррациональных числе нет. G>То есть функция дирихле всегда будет возвращать 1.
Окей, т.е. на С# она невыразима? Почему ты требуешь от меня выразить другую функцию, существование которой оспариваешь?
G>>>Значит object.ReferenceEquals является функцией сравнения identity, значит ссылка и есть identity. S>>это написано в определении identity ECMA. А отношение этого всего к OOP Identity лишь то, что identity на memory location ему удовлетворяет, но не исчерпывает его. Подтверждение этому — пример identity на GUID-ах, которое приводил Синклер. Если ты не считаешь что такой identity на GUID-ах может быть принят за OOP identity, то с этим не ко мне G>А я не говорил про memory location. Более того, неоднократно тебе пояснял что ссылка в разных системах может быть разная. G>Это ты понимаешь ссылку узко, как memory location.
ссылка в дотнете есть ECMA identity по определению ECMA-335. Это верно?
Определение identity в ECMA-335 не является переформулировкой identity OOP. Это не одно и то же. Согласен?
Identity в ECMA-335 — это двоичное отношение, основанное на memory location. Так?
Теперь все выглядит так, будто ты утверждаешь, что identity в ECMA-335 это единственный способ удовлетворения OOP identity. Нет ведь? Не единственный?
Может существуют другие? Да, Синклер привел identity на GUID-ах. Плюнем на то что область значений GUID-а конечна, здесь неважно. Допустим что счетна.
Ну а если существуют другие, то возможно и мой identity подойдет. Я еще формально не пытался его определить, а ты уже требуешь от меня функцию на C#.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>С точки зрения математики функция это правило однозначного отображения области определения в область значений. Независимость функции от чего либо не означает неучастие этого чего-либо в неких вычислениях (что такое вычисление в отношении математической функции?), а означает отсутствие влияния этого чего-либо на результат. Я могу задать функцию, которая будет учитывать фазу луны, но если результат функции будет тем же для любой фазы луны — это значит что функция не будет зависеть от фазы луны. G>>Тривиальные вычисления, которые всегда дают одинаковый результат на любых входных данных, можно исключить из рассмотретрения, заменив их константами. G>>Проделав это простое преобразование у тебя функция не опирается на фазы луны. S>Это будет другая функция. Равная, но другая, потому как будет задана другим правилом.
Тем не менее её можно использовать в рассуждениях вместо оригинальной.
А вообще, что ты хочешь доказать?
G>>>>Именно обязан. В математике нет "презумпции невиновности", есть аксиомы, остальное надо доказывать. S>>>Функция Дирихле существует? G>>Да. S>И что, тебе не надо доказывать ее существование кодом на C#? Почему к моей функции у тебя другое отношение?
Я же говорю, я могу написать функцию дирихле на C# или любом другом языке, но она всегда будет возвращать 1, так как нет в компьютере иррациональных чисел. Поэтому полезность её равна нулю.
Ты же не можешь написать на C# функцию id(object), которая id(a)==id(b) только когда a и b — один объект, при этом функция не должна зависеть от состояния и поведения и при этом она не будет совпадать с object.ReferenceEquals.
S>>>Как только я сформулирую правило (я его еще не сформулировал) — ты можешь оспаривать тот факт что это правило сответствует определению функции, удовлетворяет понятию идентичности в ООП. Но вот оспаривать существование такого правила — с этим обращайся к филологам. G>>Ты еще должен доказать что оно аксиомам не противоречит как минимум. Тебе это пока не удалось сделать. G>>>>Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет S>Это не аксиомы, это определение идентичности OOP.
В нашем случае аксимоы, так как они даны и их не нужно доказывать.
S>Я докажу что она не противоречит. Только ты их неверно понимаешь. Оба пункта.
Читать как "я выдумаю свое понимание, а на основе него докажу все что угодно". Ну доказывай, ты не один кто неправильно понимает, но гораздо больше людей все правильно понимают.
S>>>2) это ты придумал. identity — это то что отличает объекты от остальных. Именно identity говорит где одинаковые объекты, а где разные. Иначе тебе придется показать мне определение одинаковых объектов в OOP. G>>Ты говоришь что я что-то придумал, а потом повторяешь то же самое что я сказал другими словами. Формализуй выделенное выше, получится ровно то же самое. S>Для меня не то же самое. Покажи определение одинаковых объектов, а то твоя версия пункта 2 опирается на него..
Одинаковый — один и тот же, я даже специально same написал по английски в скобках чтобы ты понимал о чем речь.
G>>>>Ты доказать существование такой функции id, которая не является object.ReferenceEquals в C# не можешь. Значит нет такой функции. S>>>Значит функции Дирихле тоже нет G>>Она есть, но на компьютере её выразить нельзя так как иррациональных числе нет. G>>То есть функция дирихле всегда будет возвращать 1. S>Окей, т.е. на С# она невыразима?
Выразима, но толку мало. В C# есть тип вещественных чисел, они по своей природе рациональны, так как имеют конечную запись в битовом представлении, которая отображается на рациональные числа. Типа иррациональных чисел нет и прцессор не умеет с ними работать Их можно ввести искусственно и просто спрашивать у числа является ли оно рациональным. Но не все вычисления однозначно дают рациональные\иррациональные числа в результате, в этом и проблема.
S>Почему ты требуешь от меня выразить другую функцию, существование которой оспариваешь?
То что ты пытаешься сделать — даже записать не получится.
G>>А я не говорил про memory location. Более того, неоднократно тебе пояснял что ссылка в разных системах может быть разная. G>>Это ты понимаешь ссылку узко, как memory location. S>ссылка в дотнете есть ECMA identity по определению ECMA-335. Это верно?
Да
S>Определение identity в ECMA-335 не является переформулировкой identity OOP. Это не одно и то же. Согласен?
Согласен, оно является реализацией.
S>Identity в ECMA-335 — это двоичное отношение, основанное на memory location. Так?
Да, см (1) ниже
8.2.5.1 Identity
The identity operator is defined by the CTS as follows.
• If the values have different exact types, then they are not identical.
• Otherwise, if their exact type is a value type, then they are identical if and only if the bit
sequences of the values are the same, bit by bit.
• Otherwise, if their exact type is a reference type, then they are identical if and only if the
locations of the values are the same. (1)
Identity is implemented on System.Object via the ReferenceEquals method. (2)
S>Теперь все выглядит так, будто ты утверждаешь, что identity в ECMA-335 это единственный способ удовлетворения OOP identity.
Я так не утверждаю, более того, я говорил что в других системах есть и другие способы. Ты же утвреждал
что в C# возможно identity без совпадения ссылок, хотя стандарт говорит обратное (см (2) выше).
S>>ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity).
G>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю.
Для C# две строки с одинаковым содержимым.
Здравствуйте, gandjustas, Вы писали:
G>Я не про это, я как раз про обратный эффект что несмотря на то что repository, query object, unit of work, data mapper, identity map и многие другие паттерны уже встроены в orm, люди продолжают писать свои приложения реализуя паттерны самостоятельно, которые внутри делегируют все тому же orm. G>При этом называют это правильной архитектурой.
Сомневаюсь в массовости этого явления. Это ж идиотизм. Но даже если такое явление и есть, то при чем тут Фаулер?
G>Все это потому что фаулер и компания привели довольно мало технических доводов про использование тех или иных паттернов, зато очень много маркетологического буллшита.
Ну, не знаю не знаю. Мне кажется раз в любом фреймворке это есть значит правильную штуку описали.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>Я не про это, я как раз про обратный эффект что несмотря на то что repository, query object, unit of work, data mapper, identity map и многие другие паттерны уже встроены в orm, люди продолжают писать свои приложения реализуя паттерны самостоятельно, которые внутри делегируют все тому же orm. G>>При этом называют это правильной архитектурой.
ANS>Сомневаюсь в массовости этого явления. Это ж идиотизм.
Погугли "repository pattern" и ты удивишься как много рекомендаций по его реализации, и как мало рекомендаций не делать этого.
ANS>Но даже если такое явление и есть, то при чем тут Фаулер?
При том что "фаулер и ко" продолжают сейчас популяризировать те идеи, которые были актуальны 10-15 лет назад.
G>>Все это потому что фаулер и компания привели довольно мало технических доводов про использование тех или иных паттернов, зато очень много маркетологического буллшита. ANS>Ну, не знаю не знаю. Мне кажется раз в любом фреймворке это есть значит правильную штуку описали.
На тот момент правильную. Но скорее не описали, а "продали". Причем так продали, что народ до сих пор "хавает", хоть и давится.
Ведь никто из "фаулер и ко" не написал: "не делайте repository, он уже есть". За такие утверждения начинают гнать ссаными тряпками.
Причем им это выгодно. Они таким образом продолжают повышать свой статус, продавать за реальные деньги тренинги по DDD, это же золотая жила из недалеких программистов.
Здравствуйте, gandjustas, Вы писали:
ANS>>Сомневаюсь в массовости этого явления. Это ж идиотизм. G>Погугли "repository pattern" и ты удивишься как много рекомендаций по его реализации, и как мало рекомендаций не делать этого.
Что не так с паттерном репозиторий ? Дай пример или ссылку.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
S>>Функция Дирихле существует? Напиши, пожалуйста ее на С#, что бы работала для иррациональных чисел тоже.
I>И давно C# научили работать с иррациональными числами ?
Как давно на C# запретили писать следующее:
var sqrt2 = new Sqrt(2);
Assert(sqrt2 * sqrt2 == 2);
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
A>>Приведи пример задачи, которую, оставаясь в рамках ООП парадигмы, нельзя решить без операции сравнения ссылок. G>Collection.Remove(object), если не переопределять equals, то она вычисляется как сравнение ссылок.
artelk> Приведи пример задачи, которую нельзя решить без использования object.ReferenceEquals.
gandjustas> Хорошо, задача: нужно реализовать object.ReferenceEquals с текущим его поведением.
Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы?
A>>Берем http://exposedobject.codeplex.com/ A>>Код: A>>
A>>dynamic a = new A {X = 42};
A>>dynamic d = ExposedObject.From(a);
A>>Console.WriteLine(d.X);//42
A>>Console.WriteLine(object.ReferenceEquals(a, d));//false!!!
A>>
G>Ты привел пример разных объектов.
A>>Идентичность в .NET — более узкое понятие, чем в ООП. A>>Или ты будешь утверждать, что a и d не идентичны? G>Конечно не идентичны, они даже не эквивалентны. У них даже типы разные.
Ок, берем код ExposedObject, меняем там BindingFlags.NonPublic на BindingFlags.FlattenHierarchy, переопределяем методы из Equals, GetHashCode, ToString и создаем GetType. Делегируем все в агрегируемый объект.
class A
{
public int X { get; set; }
public override string ToString()
{
return string.Format("X = {0}", X);
}
public override bool Equals(object obj)
{
var o = obj as A;
return o != null && o.X == X;
}
}
var a = new A {X = 42};
dynamic o = a;
dynamic ex = ExposedObject.From(o);
Console.WriteLine(ex.X);//42
Console.WriteLine(ex.GetType().GetProperty("X").GetValue(a, null));//42
Console.WriteLine(ex);//X = 42
Console.WriteLine((A)ex);//X = 42
Console.WriteLine(ex.Equals(o));//true
Console.WriteLine(ex.GetType() == a.GetType());//true
Console.WriteLine(ex.GetType() == typeof(A));//true
Console.WriteLine(ex.GetHashCode() == a.GetHashCode());//true
Console.WriteLine(object.ReferenceEquals(a, ex));//false!!!
Что не работает:
Console.WriteLine(o is A);//true
Console.WriteLine(o as A != null);//true
Console.WriteLine(ex is A);//false
Console.WriteLine(ex as A != null);//false
Опкод isinst придумали задолго до динамиков, поэтому они в этом месте не доделанные.
Да и наличие даункаста не является необходимым условием для ООП.
G>Тебе нужен пример где два объекта идентичны, то есть это один объект по сути. Но ссылки на него не равны.
Ссылки ссылаются на идентичные объекты, если они взаимозаменыемы с сохранением поведения программы.
Если в коде программы используется object.ReferenceEquals, то, очевидно, такой пример привести нельзя. По определению.
Ок, другой пример:
class Something
{
private readonly ID id;
public Something()
{
id = ID.GetUniqueId();
//INSERT INTO table (ID, State) VALUES ($id, 0)
}
private Something(ID id)
{
this.id = id;
}
public static IEnumerable<Something> GetAll()
{
foreach(id in//SELECT ID FROM table)yield return new Something(id)
}
public int State
{
get { //SELECT State FROM table WHERE ID = $id }set { //UPDATE table SET State=$value WHERE ID = $id }
}
}
Здравствуйте, gandjustas, Вы писали:
G>Ну да, покажи пример идентичности без равенства ссылок.
internal interface IA
{
int F();
}
class A : IA
{
int IA.F()
{
return 1;
}
public int F()
{
return 2;
}
}
A a1 = new A();
IA a2 = a1;
Console.WriteLine(object.ReferenceEquals(a1, a2));//true
Console.WriteLine(a1.F());
Console.WriteLine(a2.F());
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Извини, я до этого места статью был не дочитал Я остановился на втором абзаце. И сходу вопрос, почему "Transaction Script" это "чисто процедурное овно"?
А ты нажми на ссылку "Transaction Script", которую он приводит.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>Тривиальные вычисления, которые всегда дают одинаковый результат на любых входных данных, можно исключить из рассмотретрения, заменив их константами. G>>>>Проделав это простое преобразование у тебя функция не опирается на фазы луны. S>>>Это будет другая функция. Равная, но другая, потому как будет задана другим правилом. G>>Тем не менее её можно использовать в рассуждениях вместо оригинальной. G>>А вообще, что ты хочешь доказать? S>Я хочу тебе доказать что опираться и зависеть — это не одно и то же. Тем более, я смутно понимаю, что такое опираться в отношении функций.
То есть ты что-то хочешь доказать когда этого не понимаешь?
G>>Ты же не можешь написать на C# функцию id(object), которая id(a)==id(b) только когда a и b — один объект, при этом функция не должна зависеть от состояния и поведения и при этом она не будет совпадать с object.ReferenceEquals. S>Моя функция id не будет иметь отношения к ReferenceEquals и она не обязана будет возвращать те же результаты. Она будет удовлетворять определению identity OOP, а не ECMA-335.
Ок, напиши её.
G>>>>>>Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет S>>>Это не аксиомы, это определение идентичности OOP. G>>В нашем случае аксимоы, так как они даны и их не нужно доказывать. S>Дано определение идентичности.
И в определении идентичности прописано что она не зависит от состояние и поведения. Также в нем написано что позволяет отличить объект от других объектов.
S>>>Для меня не то же самое. Покажи определение одинаковых объектов, а то твоя версия пункта 2 опирается на него.. G>>Одинаковый — один и тот же, я даже специально same написал по английски в скобках чтобы ты понимал о чем речь. S>Same объекты это те, для которы ID(obj) совпадает. У тебя это понятие относительно ООП по-другому выглядит?
Я тебе тоже самое писал. Читай внимательно 2), выше выделил жирным
S>Ты же мне говоришь что ID опирается на понятие разных объектов.
object identity — identity is that property of an object that distinguishes each object from all others
identity позволяет отличать объекты друг от друга.
S>>>Почему ты требуешь от меня выразить другую функцию, существование которой оспариваешь? G>>То что ты пытаешься сделать — даже записать не получится. S>Как и Дирихле на C#.
Ей вполне получится записать если сделать искусственный тип, свойством которого будет рациональность. Но это свойство не будет корректно обрабатываться при вычислениях. Поэтому толку от функции мало.
S>Окей. Но это ведь ECMA, а не OOP. Я утверждал что существует другое identity, которое не совпадает с identity на memory location. Потому я не собираюсь доказывать какое-либо отношение того identity к ReferenceEquals.
ты утверждал это конкретно в контексте C#. но так и не смог показать функцию.
Потом расширил границы, выдумывая системы где ООП реализованно без сравнения ссылок, но id в такой системе не смог.
G>>
S>>>>ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity).
G>>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю.
G>>Для C# две строки с одинаковым содержимым.
S>Все верно. Я говорил об идентичности OOP. Но ты об идентичности ECMA-335.
Мы ведь за C# говорили. В ECMA явно прописано что является identity, ты этому противоречить пытаешься.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
ANS>>>Сомневаюсь в массовости этого явления. Это ж идиотизм. G>>Погугли "repository pattern" и ты удивишься как много рекомендаций по его реализации, и как мало рекомендаций не делать этого.
I>Что не так с паттерном репозиторий ? Дай пример или ссылку.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
A>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы?
Например когда мы хотим поместить в коллекцию объекты класса, который не имеет equals и написан не нами.
Как объекты такого класса будут сравниваться? Ты же понимаешь что equals переопределяет очень малый процент классов
A>>>Берем http://exposedobject.codeplex.com/ A>>>Код: A>>>
A>>>dynamic a = new A {X = 42};
A>>>dynamic d = ExposedObject.From(a);
A>>>Console.WriteLine(d.X);//42
A>>>Console.WriteLine(object.ReferenceEquals(a, d));//false!!!
A>>>
G>>Ты привел пример разных объектов.
A>>>Идентичность в .NET — более узкое понятие, чем в ООП. A>>>Или ты будешь утверждать, что a и d не идентичны? G>>Конечно не идентичны, они даже не эквивалентны. У них даже типы разные.
A>Ок, берем код ExposedObject, меняем там BindingFlags.NonPublic на BindingFlags.FlattenHierarchy, переопределяем методы из Equals, GetHashCode, ToString и создаем GetType. Делегируем все в агрегируемый объект. A>
A>Console.WriteLine(ex.Equals(o));//true
A>Console.WriteLine(object.ReferenceEquals(a, ex));//false!!!
A>
Ты привел пример эквивалентных, но не идентичных объектов.
Мог бы не напрягаться, а взять две строки.
The identity operator is defined by the CTS as follows.
• If the values have different exact types, then they are not identical.
• Otherwise, if their exact type is a value type, then they are identical if and only if the bit
sequences of the values are the same, bit by bit.
• Otherwise, if their exact type is a reference type, then they are identical if and only if the
locations of the values are the same.
Identity is implemented on System.Object via the ReferenceEquals method.
То что ты приводишь называется эквивалентностью
8.2.5.2 Equality
For value types, the equality operator is part of the definition of the exact type. Definitions of equality should
obey the following rules:
• Equality should be an equivalence operator, as defined above.
• Identity should imply equality, as stated earlier.
• If either (or both) operand is a boxed value, equality should be computed by
o first unboxing any boxed operand(s), and then
o applying the usual rules for equality on the resulting values.
Equality is implemented on System.Object via the Equals method.
A>Ок, другой пример: A>
A>class Something
A>{
A> private readonly ID id;
A> public Something()
A> {
A> id = ID.GetUniqueId();
A> //INSERT INTO table (ID, State) VALUES ($id, 0)
A> }
A> private Something(ID id)
A> {
A> this.id = id;
A> }
A> public static IEnumerable<Something> GetAll()
A> {
A> foreach(id in//SELECT ID FROM table)
A> yield return new Something(id)
A> }
A> public int State
A> {
A> get { //SELECT State FROM table WHERE ID = $id }
A> set { //UPDATE table SET State=$value WHERE ID = $id }
A> }
A>}
A>
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Ну да, покажи пример идентичности без равенства ссылок. A>
A>internal interface IA
A>{
A> int F();
A>}
A>class A : IA
A>{
A> int IA.F()
A> {
A> return 1;
A> }
A> public int F()
A> {
A> return 2;
A> }
A>}
A>A a1 = new A();
A>IA a2 = a1;
A>Console.WriteLine(object.ReferenceEquals(a1, a2));//true
A>Console.WriteLine(a1.F());
A>Console.WriteLine(a2.F());
A>
A>Таки нашел
Что нашел? что разные методы вызываются?
Это ссылки на один объект, а ты пытаешться искать разницу в поведении. Причем даже не объектов, а компилятора.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>При том что "фаулер и ко" продолжают сейчас популяризировать те идеи, которые были актуальны 10-15 лет назад.
ANS>Зашел к Фаулеру на сайт. В самом верху ссылка на http://martinfowler.com/dsl.html А в низу есть: ANS>
ANS>Popular Articles
ANS>* New Methodology
ANS>* Dependency Injection
ANS>* Mocks aren’t Stubs
ANS>* Is Design Dead?
ANS>* Continuous Integratio
ANS>имхо, зря ты на него бочку катиш
New Methodology, Is Design Dead? — все про agile, сплошной маркетинг, статья 10-летней давности. Половина из книжки Бека про XP.
Яж говорю, фаулер устарел. Он до сих пор "продает" то что было актуально 10 лет назад, а сейчас уже стало нормальным и перекочевало из разряда новшеств в разряд инструментов.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>А вообще, что ты хочешь доказать? S>>Я хочу тебе доказать что опираться и зависеть — это не одно и то же. Тем более, я смутно понимаю, что такое опираться в отношении функций. G>То есть ты что-то хочешь доказать когда этого не понимаешь?
Да
S>>Моя функция id не будет иметь отношения к ReferenceEquals и она не обязана будет возвращать те же результаты. Она будет удовлетворять определению identity OOP, а не ECMA-335. G>Ок, напиши её.
Думаю, уже скоро.
G>>>>>>>Аксиомы две: 1) у каждого объекта есть identity, которая не зависит от состояния и поведения 2)для одинаковых (same) объектов identity совпадает, для разных — нет S>>>>Это не аксиомы, это определение идентичности OOP. G>>>В нашем случае аксимоы, так как они даны и их не нужно доказывать. S>>Дано определение идентичности. G>И в определении идентичности прописано что она не зависит от состояние и поведения. Также в нем написано что позволяет отличить объект от других объектов.
Это верно.
S>>Same объекты это те, для которы ID(obj) совпадает. У тебя это понятие относительно ООП по-другому выглядит? G>Я тебе тоже самое писал. Читай внимательно 2), выше выделил жирным
Там, где ты выделил жирным, ты описал свойство identity через понятие одинаковых и разных объектов. Я пишу что наоборот, identity определяет где разные, а где одинаковые (same) объекты.
Но ECMA-335 вводит идентичность взаимно-однозначным образом с location: they are identical if and only if the locations of the values are the same, отсюда и путаница.
Призываю четко разделять где мы говорим об объектах OOP, а где об объектах ECMA-335. Не нужно проецировать ECMA-335 определение обратно на OOP. По ECMA если объекты в разных location, то это разные объекты. По OOP identity ничего такого нет. ECMA-335 identity гораздо сильнее OOP identity, что позволяет в некоторой степени ослаблять ECMA-335, оставаясь в рамках OOP.
S>>Ты же мне говоришь что ID опирается на понятие разных объектов.
G>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
G>
G>object identity — identity is that property of an object that distinguishes each object from all others
G>identity позволяет отличать объекты друг от друга.
Позволяет отличать — да. Но оно же и задает, где разные а где одинаковые объекты. Не путай с ECMA, где идентичность определена через location.
G>>>То что ты пытаешься сделать — даже записать не получится. S>>Как и Дирихле на C#. G>Ей вполне получится записать если сделать искусственный тип, свойством которого будет рациональность. Но это свойство не будет корректно обрабатываться при вычислениях. Поэтому толку от функции мало.
Я не понял, что такое искусственный тип со свойством рациональность.
S>>Окей. Но это ведь ECMA, а не OOP. Я утверждал что существует другое identity, которое не совпадает с identity на memory location. Потому я не собираюсь доказывать какое-либо отношение того identity к ReferenceEquals. G>ты утверждал это конкретно в контексте C#. но так и не смог показать функцию.
Кое-какую функцию я, скорее всего, покажу. Позже. G>Потом расширил границы, выдумывая системы где ООП реализованно без сравнения ссылок, но id в такой системе не смог.
Предоставить код id без сравнения ссылок я не пытался и не обещал. Обвинять меня в том что я этого не смог не надо. Но предоставить альтернативное отношение идентичности я смогу. Оно будет рабочим на C# и будет формально удовлетворять определению идентичности OOP ничуть не хуже чем идентичность от ECMA-335. Надо только заметить, что "рабочим" это не значит что FCL будет с ним корректно работать вместе со всеми коллекциями и т.п.
G>>>
S>>>>>ссылка обеспечивает все что нужно, что бы обратится к объекту с identity. Но из этого не следует что из идентичности следует совпадение ссылок. По крайней мере для логической идентичности это не следует (http://c2.com/cgi/wiki?ObjectIdentity).
G>>>>Для конкретного языка — следует, можешь обратный пример привести? Я таких не знаю.
G>>>Для C# две строки с одинаковым содержимым.
S>>Все верно. Я говорил об идентичности OOP. Но ты об идентичности ECMA-335. G>Мы ведь за C# говорили. В ECMA явно прописано что является identity, ты этому противоречить пытаешься.
Слушай, не надо из меня делать идиота. Я с самого начала противопоставлял различные виды идентичности, логическую и физическую. Там я так и написал, что из логической идентичности (это НЕ идентичность ECMA-335) не следует совпадение ссылок (идентичность ECMA-335).
Было бы слишком наглым бредом брать разные объекты по ECMA-335 и утверждать что они идентичны по ECMA-335.
Здравствуйте, samius, Вы писали:
S>>>Same объекты это те, для которы ID(obj) совпадает. У тебя это понятие относительно ООП по-другому выглядит? G>>Я тебе тоже самое писал. Читай внимательно 2), выше выделил жирным S>Там, где ты выделил жирным, ты описал свойство identity через понятие одинаковых и разных объектов. Я пишу что наоборот, identity определяет где разные, а где одинаковые (same) объекты.
Если некоторое свойство позволяет отличить разные объекты, то оно же позволяет определить что это один и тот же объект.
Иначе (доказательство от противного), если id(a) != id(b) когда a и b — один и тот же объект, то для любых id(a) и id(b) невозможно сказать это разные или одинаковые объекты.
Поэтому прими за данное что функция id(a) = id(b) только кода a и b — один и тот же объект и не равна в остальных случаях.
S>Но ECMA-335 вводит идентичность взаимно-однозначным образом с location: they are identical if and only if the locations of the values are the same, отсюда и путаница.
Ты и пытался с этим спорить Ладно, не прокатило, вычеркиваем.
S>Призываю четко разделять где мы говорим об объектах OOP, а где об объектах ECMA-335. Не нужно проецировать ECMA-335 определение обратно на OOP. По ECMA если объекты в разных location, то это разные объекты. По OOP identity ничего такого нет. ECMA-335 identity гораздо сильнее OOP identity, что позволяет в некоторой степени ослаблять ECMA-335, оставаясь в рамках OOP.
Да, все верно. НО! Знаешь ли ты еще хоть одну систему где идентичность не реализуется сравнением ссылок?
S>>>Ты же мне говоришь что ID опирается на понятие разных объектов.
G>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
G>>
G>>object identity — identity is that property of an object that distinguishes each object from all others
G>>identity позволяет отличать объекты друг от друга. S>Позволяет отличать — да. Но оно же и задает, где разные а где одинаковые объекты. Не путай с ECMA, где идентичность определена через location.
См выше. С точки зрения математики позволяет отличать == позволяет найти одинаковые, ecma тут не при чем.
G>>>>То что ты пытаешься сделать — даже записать не получится. S>>>Как и Дирихле на C#. G>>Ей вполне получится записать если сделать искусственный тип, свойством которого будет рациональность. Но это свойство не будет корректно обрабатываться при вычислениях. Поэтому толку от функции мало. S>Я не понял, что такое искусственный тип со свойством рациональность.
interface INumebr
{
bool IsRational { get ; }
}
S>>>Окей. Но это ведь ECMA, а не OOP. Я утверждал что существует другое identity, которое не совпадает с identity на memory location. Потому я не собираюсь доказывать какое-либо отношение того identity к ReferenceEquals. G>>ты утверждал это конкретно в контексте C#. но так и не смог показать функцию. S>Кое-какую функцию я, скорее всего, покажу. Позже.
С нетерпением ждем.
G>>Потом расширил границы, выдумывая системы где ООП реализованно без сравнения ссылок, но id в такой системе не смог. S>Предоставить код id без сравнения ссылок я не пытался и не обещал. Обвинять меня в том что я этого не смог не надо. Но предоставить альтернативное отношение идентичности я смогу. Оно будет рабочим на C# и будет формально удовлетворять определению идентичности OOP ничуть не хуже чем идентичность от ECMA-335. Надо только заметить, что "рабочим" это не значит что FCL будет с ним корректно работать вместе со всеми коллекциями и т.п.
Чтобы механизм был рабочим надо:
1)Придумать как обращаться с ними в программе (ссылки, которые при этом нельзя сравнить)
2)Придумать механизм отправки сообщения по ссылке
3)Придумать identity, как функцию id(object)
4)Придумать как сравнивать identity
5)Доказать что между значением id(object) и ссылкой нет взаимно однозначного соответствия.
5 пункт очень важный так как иначе нет смысла вводить искусственную функцию id. При этом помним что ссылка не есть адрес в памяти, и возможные выкрутасы с сегментацией, виртуальной памятью и подобное тому что сделано в COM не катят.
G>>Мы ведь за C# говорили. В ECMA явно прописано что является identity, ты этому противоречить пытаешься. S>Слушай, не надо из меня делать идиота.
Я ниче не делаю, ты сам. Я приводил цитаты из твоих сообщений.
S>Я с самого начала противопоставлял различные виды идентичности, логическую и физическую. Там я так и написал, что из логической идентичности (это НЕ идентичность ECMA-335) не следует совпадение ссылок (идентичность ECMA-335).
Ты так и не смог сказать что такое логическая идентичность, оно у тебя больше похоже на эквивалентность, которая в общем случае идентичностью не является.
S>Было бы слишком наглым бредом брать разные объекты по ECMA-335 и утверждать что они идентичны по ECMA-335.
Нет, ты просто слишком много читал википедии и сам запутался с своих идентичностях.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>>Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки. S>>выполняет роль, но не является. S>С точки зрения математики, "выполнять роль" и "являться" — одно и то же.
Вы меня удивляете. "являться" изоморфно "is a", "принадлежит к"...
"42 является натуральным числом" означает что 42 принадлежит множеству натуральных чисел.
Что означает фраза "42 выполняет роль натурального числа"? Вы будете утвреждать что это одно и то же?
S>Если вы собираетесь переопределять значение термина "являться", то увольте меня от дальнейшей беседы. Ибо шизофрения — дивный мир, но я в него не вхож.
Нет желания отвечать на это
S>>Это своя реализация идентичности. Не интересно. S>Что значит "своя"? А вы хотели чужую? Идентичность — это математическое понятие. Реализация идентичности — она всегда своя.
Не так выразился. Там свое определение идентичности. Они его определили через memory location. Хотелось бы увидеть эквивалентность определению из ООП. Но мы видим только то что идентичность ECMA удовлетворяет определению идентичности ООП, но не исчерпывает его.
S>>Компилировать FCL в C#-- не надо, нет такой цели S>А в чём цель? Я думал, вы хотите получить работоспособную ОО-модель.
Она работоспособна, пока мы не вызовем ID. S>>Имеет смысл если ID вычислима. Но я не говорил что она вычислима. S>Если она невычислима, то у нас нет "способа отличать один объект от любого другого объекта". Упс.
Есть, но он невычислим. S>>В той трактовке, что позволяет отличать любой объект от всех остальных — да. S>Это не трактовка, это само определение.
Идентичность сама и регулирует, где один объект, а где другой.
S>>Ну дак мы их отличать можем в теории, по некой невычислимой функции. Существования такой функции достаточно, вычислимость ее — это просто очень полезный бонус S>Хм. Тут мои познания в computer science заканчиваются. Остаётся только смутное сомнение в S>а) существовании невычислимых функций (чем оно отличается от несуществования такой функции?)
computer science непричем. Есть математическое понятие функции как отображения множеств. Оно не требует вычислимости. Я не думал о том что computer science может использовать какое-то другое понятие. Конечно,когда мы спускаемся к конкретному языку, мы пользуемся его определением функции, которое может отличаться от общего и даже нарушать его. Например, отсутствием детерминированности. Но это не означает что в концептуальной модели мы должны пользоваться определением функции в языках. Кстати, C# не требует вычислимости функций что бы называть ее функцией. И детерминированности не требует. Вообще ничего не требует.
S>б) в применимости невычислимых функций в определениях моделей, применяемых для прикладного программирования. Мне кажется, что во всех местах, когда говорят "свойство того-то" или "функция от того-то", то везде неявно продразумевают "вычислимая детерминированная".
Когда говорят о функции как о математическом объекте, то детерминированность подразумевается (по определению функции), а вычислимость не должна. Хотя обычно функции вычислимы и без специальной оговорки можно ожидать вычислимости.
S>>мы можем отличать объекты с отличным поведением (но только их). Отличать объекты с неотличимым поведением не нужно. Но это уже видимо моя додумка. S>Да, это ваша додумка.
Да. Только вот идентичность сама и указывает, что считать отличным объектом, а что нет. Естественно, что как только мы отказываемся от ECMA идентичности, то понятие ECMA отличий объектов перестает иметь место. На это место встает то понятие отличия объектов, которое задано новой идентичностью. Если моя идентичность укажет что два объекта класса без состояния идентичны, то так оно и будет, невзирая на то что по ECMA они будут различными объектами.
S>>Про "следовать" погорячился. можем одновременно наблюдать неравенство ссылок и same identity. S>Это правда, и это явно описано в википедии, хотя и не обосновано формально.
Да, кое-что там напутали. Но другая identity задает другое отношение same object. S>>Вот по этим изменениям я и предлагал определять идентичность. S>Такая идентичность не будет сохраняться. S>Поясню примером: S>[c#] S>public class NonIdentic S>{ S> public int A { get; set; } S>}
S>... S>Опять то же самое. Какую бы цепочку сообщений getA/setA мы ни придумали, цепочка ответов от объектов a и b будет совершенно одинаковой. То есть их поведение — одинаково. Значит, у них должна быть одинаковая "логическая identity". S>Однако, стоит нам сделать хоть что-то несимметричное, как их поведение тут же станет различным. Упс.
Вот по несимметричным действиям мы и можем их отличать. На самом деле в изменениях нет необходимости. Можно пошуршать в IL коде и увидеть, позволяет ли объект изменять свои поля или нет. Если позволяет — определять его идентичность по location, т.е. по ReferenceEquals. Если не нет — то по полям. Это довольно грубо, но надеюсь, что идея понятна.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, artelk, Вы писали:
A>>>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы?
G>>Например когда мы хотим поместить в коллекцию объекты класса, который не имеет equals и написан не нами. G>>Как объекты такого класса будут сравниваться? Ты же понимаешь что equals переопределяет очень малый процент классов A>Например, назначать коллекции стратегию сравнивания.
Коллекция тоже не тобой написана. Счиатй что у тебя изначально нет возможности переопределит операцию сравнения. Как будет выполняться операция Collection.Remove(item)
A>А вообще, вопрос был не в том, с какими проблемами мы можем столкнуться в текущем проекте, если с завтрашнего дня внезапно появится запрет на вызов ReferenceEquals и всего, что его использует.
Как минимум BCL не соберется\перестанет работать. Ты кстати скорее всего можешь сымитировать ситуацию через profile api, подменив вызов RefenceEquals, если он не intrsink какойнить.
G>>>>Тебе нужен пример где два объекта идентичны, то есть это один объект по сути. Но ссылки на него не равны. A>>>Ссылки ссылаются на идентичные объекты, если они взаимозаменыемы с сохранением поведения программы. G>>Бред. Смотри определения: G>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm A>Хорошая ссылка.
Конечно, прочитай внимательно все три определения. Все три верны и отражают разные аспекты одного и того же.
G>>Читай ECMA-335 A>.NET — это единственная возможная реализация ООП?
Нет, но придумай другую где идентичность не сравнением через ссылок делается.
A>Определение через locations — слишком узко.
Для чего? Практика показывает что для CLR самое то. Ты не можешь расширить это определение (то есть получить идентичность без равенства ссылок) оставаясь в рамках ECMA-335.
G>>То что ты приводишь называется эквивалентностью A>Так в примере не только ж Equals работает.
А без разницы.
A>Если два объекта типа Something имеют одинаковый id, то они идентичны, независимо от того, что вернет object.ReferenceEquals.
Это бред. Твое определение идентичности опирается на состояние, что противоречит определению идентичности. Более того два объекта не будут ни идентичны, ни эквивалентны с точки зрения ecma-335
Источник твоего "вдохновения" в этом случае — РСУБД, которая не является ОО-системой если что
Здравствуйте, samius, Вы писали:
S>Можно пошуршать в IL коде и увидеть, позволяет ли объект изменять свои поля или нет. Если позволяет — определять его идентичность по location, т.е. по ReferenceEquals. Если не нет — то по полям. Это довольно грубо, но надеюсь, что идея понятна.
Это противоречит определению так как ты на состояние будешь ориентироваться.
Это получится как раз определение эквивалентности, но не идентичности.
G>>object identity — a characteristic of an object that provides a means to uniquely denote or refer to the object independent of its state or behavior
G>>Независимо от состояния и поведения
A>Только сдается мне такому определению удовлетворит идентичность, реализованная на основе функции A>
A>bool IsIdentical(object o1, object o2)
A>{
A> return false;
A>}
A>
A>и смысл полностью теряется, т.к. такую функцию можно реализовать вообще для чего угодно.
Нет.
var a = new object();
var b = a;
var c = new object();
Debug.Assert(IsIdentical(a,b) != IsIdentical(a,c));
Ассерт отвалится, с такой функцией мы не можем сказать являются ли разными два объекта или это один и тот же объект. То есть мы не можем отличить объект от других.
Здравствуйте, samius, Вы писали:
S>Identity в ECMA-335 — это двоичное отношение, основанное на memory location. Так?
Прочитал стандарт. Оказывается не так.
8.3 Locations
Values are stored in locations. A location can hold only one value at a time. All locations are typed. The type
of the location embodies the requirements that shall be met by values that are stored in the location.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>Если некоторое свойство позволяет отличить разные объекты, то оно же позволяет определить что это один и тот же объект. G>Иначе (доказательство от противного), если id(a) != id(b) когда a и b — один и тот же объект, то для любых id(a) и id(b) невозможно сказать это разные или одинаковые объекты. G>Поэтому прими за данное что функция id(a) = id(b) только кода a и b — один и тот же объект и не равна в остальных случаях.
Это тафтология, потому как именно id определяет, один и тот же объект или нет. В случае с ECMA это не так, потому как они определяют один и тот же объект или нет по расположению в памяти.
G>Да, все верно. НО! Знаешь ли ты еще хоть одну систему где идентичность не реализуется сравнением ссылок?
Именно OOP систему — нет. Это имеет значение? Я же не утверждаю что выжимание альтернативной идентичности несет в себе офигенные бенефиты, ради которых стоит писать системы. Это скорее всего останется совершенно бесполезным выкоблучиванием.
G>>>
G>>>object identity — identity is that property of an object that distinguishes each object from all others
G>>>identity позволяет отличать объекты друг от друга. S>>Позволяет отличать — да. Но оно же и задает, где разные а где одинаковые объекты. Не путай с ECMA, где идентичность определена через location. G>См выше. С точки зрения математики позволяет отличать == позволяет найти одинаковые, ecma тут не при чем.
Тут все верно. Моя мысль была что OOP ID первичен, а одинаковость определяется им. Коренное отличие ECMA в том, что они определили идентичность через location и поставили <=>. А то что ID позволяет отличать и говорить что "это одно и то же" — это верно.
S>>Я не понял, что такое искусственный тип со свойством рациональность. G>
а, ну даже если экземпляр new Sqrt(2) сможет корректно определить что он не рациональный, это вряд ли приблизит к написанию рабочей версии функции Дирихле.
Предлагаю забить на это с выводом что существование математических объектов не опровергается невозможностью реализации их на C#.
S>>Предоставить код id без сравнения ссылок я не пытался и не обещал. Обвинять меня в том что я этого не смог не надо. Но предоставить альтернативное отношение идентичности я смогу. Оно будет рабочим на C# и будет формально удовлетворять определению идентичности OOP ничуть не хуже чем идентичность от ECMA-335. Надо только заметить, что "рабочим" это не значит что FCL будет с ним корректно работать вместе со всеми коллекциями и т.п. G>Чтобы механизм был рабочим надо: G>1)Придумать как обращаться с ними в программе (ссылки, которые при этом нельзя сравнить)
Ссылки будут теми же самыми, сравнивать их можно будет, но делать выводы об идентичности отличной от ECMA-335 по этому сравнению будет очевидно нельзя. G>2)Придумать механизм отправки сообщения по ссылке
Он останется неизменным. G>3)Придумать identity, как функцию id(object)
Видишь ли, что бы придумать такую функцию, нужно будет задать область значений, отличную от множества всевозможных ссылок. Что делать с этими значениями не совсем понятно. Сравнивать их? Ну так результат сравнения мы можем получить другим способом, не определяя область значений и саму функцию id. G>4)Придумать как сравнивать identity
с помощью функции MyIdEquals. G>5)Доказать что между значением id(object) и ссылкой нет взаимно однозначного соответствия.
Для этого ведь достаточно будет показать что результаты MyIdEquals будут отличаться от ReferenceEquals G>5 пункт очень важный так как иначе нет смысла вводить искусственную функцию id. При этом помним что ссылка не есть адрес в памяти, и возможные выкрутасы с сегментацией, виртуальной памятью и подобное тому что сделано в COM не катят.
нене, ломать рантайм я не собираюсь.
S>>Я с самого начала противопоставлял различные виды идентичности, логическую и физическую. Там я так и написал, что из логической идентичности (это НЕ идентичность ECMA-335) не следует совпадение ссылок (идентичность ECMA-335). G>Ты так и не смог сказать что такое логическая идентичность, оно у тебя больше похоже на эквивалентность, которая в общем случае идентичностью не является.
Вообще говоря, хорошая идентичность будет эквивалентностью. И идентичность ECMA-335 не то что бы похожа на эквивалентность, а прямо таки удовлетворяет определению эквивалентности (бинарное + рефлексивное + транзитивное + симметричное отношение).
S>>Было бы слишком наглым бредом брать разные объекты по ECMA-335 и утверждать что они идентичны по ECMA-335. G>Нет, ты просто слишком много читал википедии и сам запутался с своих идентичностях.
Возможно. Но мне кажется что без оговорок ECMA-335 и OOP было довольно легко запутаться в них и тебе тоже. Во всяком случае с оговорками мы стали в некоторых аспектах понимать друг-друга.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Можно пошуршать в IL коде и увидеть, позволяет ли объект изменять свои поля или нет. Если позволяет — определять его идентичность по location, т.е. по ReferenceEquals. Если не нет — то по полям. Это довольно грубо, но надеюсь, что идея понятна.
G>Это противоречит определению так как ты на состояние будешь ориентироваться.
Определение не запрещает ориентироваться. Оно запрещает id изменяться вместе с состоянием объекта.
G>Это получится как раз определение эквивалентности, но не идентичности.
И эквивалентности и идентичности.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Identity в ECMA-335 — это двоичное отношение, основанное на memory location. Так?
G>Прочитал стандарт. Оказывается не так.
G>
G>8.3 Locations
G>Values are stored in locations. A location can hold only one value at a time. All locations are typed. The type
G>of the location embodies the requirements that shall be met by values that are stored in the location.
G>Ни слова про memory.
Хорошо, давай уберем memory.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
A>>Только сдается мне такому определению удовлетворит идентичность, реализованная на основе функции A>>
A>>и смысл полностью теряется, т.к. такую функцию можно реализовать вообще для чего угодно.
G>Нет.
G>
G>var a = new object();
G>var b = a;
G>var c = new object();
G>Debug.Assert(IsIdentical(a,b) != IsIdentical(a,c));
G>
G>Ассерт отвалится, с такой функцией мы не можем сказать являются ли разными два объекта или это один и тот же объект. То есть мы не можем отличить объект от других.
Ты пытаешься поднять себя за волосы, как Мюнхгаузен. Ты считаешь, что a в первой строке, во второй и последней ссылаются на один и тот же объект. Нет, в каждой точке программы мы имеем дело с новым объектом, согласно нашей реализации идентичности.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>Если некоторое свойство позволяет отличить разные объекты, то оно же позволяет определить что это один и тот же объект. G>>Иначе (доказательство от противного), если id(a) != id(b) когда a и b — один и тот же объект, то для любых id(a) и id(b) невозможно сказать это разные или одинаковые объекты. G>>Поэтому прими за данное что функция id(a) = id(b) только кода a и b — один и тот же объект и не равна в остальных случаях. S>Это тафтология, потому как именно id определяет, один и тот же объект или нет.
Нет, объекты априори бывают разные. А id позволяет это определять в программе. В определении так и написано: "id позволяет различать разные объекты", не написано что "id определяет объект".
G>>Да, все верно. НО! Знаешь ли ты еще хоть одну систему где идентичность не реализуется сравнением ссылок? S>Именно OOP систему — нет. Это имеет значение?
Да, огромное значение.
S>>>Я не понял, что такое искусственный тип со свойством рациональность. G>>
S>а, ну даже если экземпляр new Sqrt(2) сможет корректно определить что он не рациональный, это вряд ли приблизит к написанию рабочей версии функции Дирихле.
Нет, исходя из интерфейса выше функцию дирихле написать легко. И даже алгебру таких объектов посторить легко. Можно даже написать функцию Sqrt, которая вернет правильный результат. А вот логарифм, тригонометрия — уже не получится. Но ведь на функцию дирихле оно никак не повлияет.
S>>>Предоставить код id без сравнения ссылок я не пытался и не обещал. Обвинять меня в том что я этого не смог не надо. Но предоставить альтернативное отношение идентичности я смогу. Оно будет рабочим на C# и будет формально удовлетворять определению идентичности OOP ничуть не хуже чем идентичность от ECMA-335. Надо только заметить, что "рабочим" это не значит что FCL будет с ним корректно работать вместе со всеми коллекциями и т.п. G>>Чтобы механизм был рабочим надо: G>>1)Придумать как обращаться с ними в программе (ссылки, которые при этом нельзя сравнить) S>Ссылки будут теми же самыми, сравнивать их можно будет, но делать выводы об идентичности отличной от ECMA-335 по этому сравнению будет очевидно нельзя.
Тогда их сравнивать бессмысленно и можно просто запретить операцию.
G>>2)Придумать механизм отправки сообщения по ссылке S>Он останется неизменным.
Ок
G>>3)Придумать identity, как функцию id(object) S>Видишь ли, что бы придумать такую функцию, нужно будет задать область значений, отличную от множества всевозможных ссылок. Что делать с этими значениями не совсем понятно. Сравнивать их? Ну так результат сравнения мы можем получить другим способом, не определяя область значений и саму функцию id.
Вот, ты уже понимаешь что это как минимум нетривиально.
G>>4)Придумать как сравнивать identity S>с помощью функции MyIdEquals.
Так её надо написать и она должна быть вычислимой.
G>>5)Доказать что между значением id(object) и ссылкой нет взаимно однозначного соответствия. S>Для этого ведь достаточно будет показать что результаты MyIdEquals будут отличаться от ReferenceEquals
Нет, не достаточно.
Если у тебя MyIdEquals(a,b) != ReferenceEquals(a,b),
то вполне возможно существует f, такая что MyIdEquals(a,b) == MyIdEquals(f(a),f(b)) == ReferenceEquals(f(a),f(b))
На примере COM, там в качестве f будет QueryInterface(IUnknown)
S>>>Я с самого начала противопоставлял различные виды идентичности, логическую и физическую. Там я так и написал, что из логической идентичности (это НЕ идентичность ECMA-335) не следует совпадение ссылок (идентичность ECMA-335). G>>Ты так и не смог сказать что такое логическая идентичность, оно у тебя больше похоже на эквивалентность, которая в общем случае идентичностью не является. S>Вообще говоря, хорошая идентичность будет эквивалентностью.
Вообще говоря любая Даже без ООП
S>>>Было бы слишком наглым бредом брать разные объекты по ECMA-335 и утверждать что они идентичны по ECMA-335. G>>Нет, ты просто слишком много читал википедии и сам запутался с своих идентичностях. S>Возможно. Но мне кажется что без оговорок ECMA-335 и OOP было довольно легко запутаться в них и тебе тоже. Во всяком случае с оговорками мы стали в некоторых аспектах понимать друг-друга.
Я как-то с самого начала не запутался. Хотя надо было сразу прочитать Ecma-335, а не пытаться тебе доказывать очевидные вещи.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Можно пошуршать в IL коде и увидеть, позволяет ли объект изменять свои поля или нет. Если позволяет — определять его идентичность по location, т.е. по ReferenceEquals. Если не нет — то по полям. Это довольно грубо, но надеюсь, что идея понятна.
G>>Это противоречит определению так как ты на состояние будешь ориентироваться. S>Определение не запрещает ориентироваться. Оно запрещает id изменяться вместе с состоянием объекта.
Ну так оно у тебя будет меняться. Даже readonly можно поменять с помощью рефлексии, все еще оставаясь в рамках CLR.
G>>Это получится как раз определение эквивалентности, но не идентичности. S>И эквивалентности и идентичности.
Нет, не идентичности.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, artelk, Вы писали:
A>>>Только сдается мне такому определению удовлетворит идентичность, реализованная на основе функции A>>>
A>>>и смысл полностью теряется, т.к. такую функцию можно реализовать вообще для чего угодно.
G>>Нет.
G>>
G>>var a = new object();
G>>var b = a;
G>>var c = new object();
G>>Debug.Assert(IsIdentical(a,b) != IsIdentical(a,c));
G>>
G>>Ассерт отвалится, с такой функцией мы не можем сказать являются ли разными два объекта или это один и тот же объект. То есть мы не можем отличить объект от других. A>Ты пытаешься поднять себя за волосы, как Мюнхгаузен. Ты считаешь, что a в первой строке, во второй и последней ссылаются на один и тот же объект. Нет, в каждой точке программы мы имеем дело с новым объектом, согласно нашей реализации идентичности.
Нет. в Ecma-335 ясно сказано что идентичные объекты те, у которых same location. a и b — same location.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Это тафтология, потому как именно id определяет, один и тот же объект или нет. G>Нет, объекты априори бывают разные. А id позволяет это определять в программе. В определении так и написано: "id позволяет различать разные объекты", не написано что "id определяет объект".
ECMA335 определяет идентичность и тем самым устанавливает, где один объект, а где другой. Другая идентичность введет другое отношение. Почему ты ожидаешь от другой идентичности что она будет оперировать "объектами по ECMA335"? ECMA335 объект != объект по любой другой идентичности, отличающейся от ECMA335. Есть какие-то проблемы с пониманием этого?
G>>>Да, все верно. НО! Знаешь ли ты еще хоть одну систему где идентичность не реализуется сравнением ссылок? S>>Именно OOP систему — нет. Это имеет значение? G>Да, огромное значение.
G>Нет, исходя из интерфейса выше функцию дирихле написать легко. И даже алгебру таких объектов посторить легко. Можно даже написать функцию Sqrt, которая вернет правильный результат. А вот логарифм, тригонометрия — уже не получится. Но ведь на функцию дирихле оно никак не повлияет.
Функция Дирихле изоморфна задаче определения иррациональности числа. Ты предлагаешь выпихнуть эту задачу из функции. Ну да ладно, задача-то осталась не решена, хоть функция и будет написана. Я так же могу написать функцию, коллапсирующую вселенную. Давай с этим завязывать.
G>>>1)Придумать как обращаться с ними в программе (ссылки, которые при этом нельзя сравнить) S>>Ссылки будут теми же самыми, сравнивать их можно будет, но делать выводы об идентичности отличной от ECMA-335 по этому сравнению будет очевидно нельзя. G>Тогда их сравнивать бессмысленно и можно просто запретить операцию.
Зачем запрещать? Идентичность по ECMA останется. Вдруг, запретив ReferenceEquals, мы не сможем поднять рантайм?
G>>>3)Придумать identity, как функцию id(object) S>>Видишь ли, что бы придумать такую функцию, нужно будет задать область значений, отличную от множества всевозможных ссылок. Что делать с этими значениями не совсем понятно. Сравнивать их? Ну так результат сравнения мы можем получить другим способом, не определяя область значений и саму функцию id. G>Вот, ты уже понимаешь что это как минимум нетривиально.
Это лишь немного сложнее чем тривиально. Больше играет тот фактор, что это ненужно. Нам надо сравнивать и посылать. И то и другое можно будет обеспечить без такой функции.
G>>>4)Придумать как сравнивать identity S>>с помощью функции MyIdEquals. G>Так её надо написать и она должна быть вычислимой.
Если бы ты согласился с тем что алтернативная идентичность задает альтернативное отношение идентичности/эквивалентности объектов, то уже сам бы написал.
G>>>5)Доказать что между значением id(object) и ссылкой нет взаимно однозначного соответствия. S>>Для этого ведь достаточно будет показать что результаты MyIdEquals будут отличаться от ReferenceEquals G>Нет, не достаточно.
G>Если у тебя MyIdEquals(a,b) != ReferenceEquals(a,b), G>то вполне возможно существует f, такая что MyIdEquals(a,b) == MyIdEquals(f(a),f(b)) == ReferenceEquals(f(a),f(b))
G>На примере COM, там в качестве f будет QueryInterface(IUnknown)
Ты требуешь чего-то непонятного. Даже при существовании такой функции f (забудем пока про взаимную однозначность) MyIdEquals будет отличаться от ReferenceEquals
MyIdEquals(a,b) == MyIdEquals(f(a),f(b)) == ReferenceEquals(f(a),f(b)) != ReferenceEquals(a, b)
А теперь по поводу взаимной однозначности f. Если она взаимно однозначна, то существует обратная ей взаимно однозначная f' такая что f'(f(a))==a и f'(f(b))==b. Из равенства ссылок f(a)==f(b) будет следовать a==b.
Отсюда, если вдруг ReferenceEquals(a, b) == true но MyIdEquals(a,b) == false, то это будет означать нерефлексивность MyIdEquals (нарушение эквивалентности, неверный посыл).
Тепрь наоборот, MyIdEquals(a,b) == true и ReferenceEquals(a, b) == false
По твоим выкладкам
true = MyIdEquals(a,b) = MyIdEquals(f(a),f(b)) = ReferenceEquals(f(a),f(b)) = ReferenceEquals(f'(f(a)),f'(f(b))) = ReferenceEquals(a,b) = false
По-моему мы подвергли сомнению существование такой взаимнооднозначной f
G>>>Ты так и не смог сказать что такое логическая идентичность, оно у тебя больше похоже на эквивалентность, которая в общем случае идентичностью не является. S>>Вообще говоря, хорошая идентичность будет эквивалентностью. G>Вообще говоря любая Даже без ООП
Давай тогда разберемся. чем идентичность отличается от отношения эквивалентности кроме требований возможности отправки сообщения по ссылке, сохранения идентичности при смене состояния?
Что может мою идентичность сделать неидентичностью в общем смысле? Что ее отличает от идентичности ECMA — я догадываюсь
G>Я как-то с самого начала не запутался. Хотя надо было сразу прочитать Ecma-335, а не пытаться тебе доказывать очевидные вещи.
По-моему ты все еще пытаешься найти опровержение другим идентичностям, оперируюя идентичностью ECMA-335. Залез в скафандр ECMA-335 и говоришь что другие скафандры фуфло, потому как в них нельзя влезть, не снимая ECMA-335. Извини, если что.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
A>>Например, назначать коллекции стратегию сравнивания. G>Коллекция тоже не тобой написана. Счиатй что у тебя изначально нет возможности переопределит операцию сравнения. Как будет выполняться операция Collection.Remove(item)
По назначенному компареру
A>>А вообще, вопрос был не в том, с какими проблемами мы можем столкнуться в текущем проекте, если с завтрашнего дня внезапно появится запрет на вызов ReferenceEquals и всего, что его использует. G>Как минимум BCL не соберется\перестанет работать. Ты кстати скорее всего можешь сымитировать ситуацию через profile api, подменив вызов RefenceEquals, если он не intrsink какойнить.
Нет цели заставить работать BCL, нет нужды подменять вызов ReferenceEquals. Мы просто показываем, что остаемся в рамках OOP, ослабив идентичность ECMA~location. Других целей нет.
G>>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm A>>Хорошая ссылка. G>Конечно, прочитай внимательно все три определения. Все три верны и отражают разные аспекты одного и того же.
Все три допускают идентичность более слабую, чем ECMA.
G>>>Читай ECMA-335 A>>.NET — это единственная возможная реализация ООП? G>Нет, но придумай другую где идентичность не сравнением через ссылок делается.
Вот мы этим и занимаемся.
A>>Определение через locations — слишком узко. G>Для чего? Практика показывает что для CLR самое то. Ты не можешь расширить это определение (то есть получить идентичность без равенства ссылок) оставаясь в рамках ECMA-335.
Отказываясь от идентичности ECMA-335 мы уже выходим за его рамки просто по определению. Раз выходим — нет нужды в них обратно лезть.
A>>Если два объекта типа Something имеют одинаковый id, то они идентичны, независимо от того, что вернет object.ReferenceEquals. G>Это бред. Твое определение идентичности опирается на состояние, что противоречит определению идентичности. Более того два объекта не будут ни идентичны, ни эквивалентны с точки зрения ecma-335
Мы же вышли за его рамки. Какой смысл продолжать измерять объекты екмой?
G>Источник твоего "вдохновения" в этом случае — РСУБД, которая не является ОО-системой если что
Ну и что? Я не понимаю, чего ты боишься? Что вдруг окажется что альтернативная идентичность может иметь место? Тебя ведь не заставляют ее использовать вместо ECMA?
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Это тафтология, потому как именно id определяет, один и тот же объект или нет. G>>Нет, объекты априори бывают разные. А id позволяет это определять в программе. В определении так и написано: "id позволяет различать разные объекты", не написано что "id определяет объект". S>ECMA335 определяет идентичность и тем самым устанавливает, где один объект, а где другой. Другая идентичность введет другое отношение. Почему ты ожидаешь от другой идентичности что она будет оперировать "объектами по ECMA335"? ECMA335 объект != объект по любой другой идентичности, отличающейся от ECMA335. Есть какие-то проблемы с пониманием этого?
Идентичность не есть объект, это свойство объекта, читай определение. То есть объект в широком смысле может существовать и без идентичности.
Например две строки в БД без ключей. Если они совпадают, то это никак не различишь их. Но тем не менее это разные объекты.
Вот как раз ооп говорит что разные объекты должны быть различимы с помощью id.
Смотри:
var a = new object();
var b = new object();
var c = a;
a и b — разные объекты, их identity должны различаться. a и c — один и тот же объект, соответственно id, полученное из a и c будет совпадать.
Если ты id определить как структурную эквивалентность — это не будет выполняться.
G>>Нет, исходя из интерфейса выше функцию дирихле написать легко. И даже алгебру таких объектов посторить легко. Можно даже написать функцию Sqrt, которая вернет правильный результат. А вот логарифм, тригонометрия — уже не получится. Но ведь на функцию дирихле оно никак не повлияет. S>Функция Дирихле изоморфна задаче определения иррациональности числа. Ты предлагаешь выпихнуть эту задачу из функции. Ну да ладно, задача-то осталась не решена, хоть функция и будет написана. Я так же могу написать функцию, коллапсирующую вселенную. Давай с этим завязывать.
Это она в математике изоморфна, а в компьютере приходится учитывать специфику. Почитай кнута, третий том кажись, про арифметику в компьютере.
G>>>>1)Придумать как обращаться с ними в программе (ссылки, которые при этом нельзя сравнить) S>>>Ссылки будут теми же самыми, сравнивать их можно будет, но делать выводы об идентичности отличной от ECMA-335 по этому сравнению будет очевидно нельзя. G>>Тогда их сравнивать бессмысленно и можно просто запретить операцию. S>Зачем запрещать? Идентичность по ECMA останется. Вдруг, запретив ReferenceEquals, мы не сможем поднять рантайм?
Ты же предлагаешь написать что-то, что сможет заменить referenceequals.
G>>>>4)Придумать как сравнивать identity S>>>с помощью функции MyIdEquals. G>>Так её надо написать и она должна быть вычислимой. S>Если бы ты согласился с тем что алтернативная идентичность задает альтернативное отношение идентичности/эквивалентности объектов, то уже сам бы написал.
Нету альтернативной идентичности, идентичность задается определением. Могут быть разные реализации. Но ты пока не привел ни одной, которая никак не противоречит определению.
G>>>>5)Доказать что между значением id(object) и ссылкой нет взаимно однозначного соответствия. S>>>Для этого ведь достаточно будет показать что результаты MyIdEquals будут отличаться от ReferenceEquals G>>Нет, не достаточно.
G>>Если у тебя MyIdEquals(a,b) != ReferenceEquals(a,b), G>>то вполне возможно существует f, такая что MyIdEquals(a,b) == MyIdEquals(f(a),f(b)) == ReferenceEquals(f(a),f(b))
G>>На примере COM, там в качестве f будет QueryInterface(IUnknown) S>Ты требуешь чего-то непонятного. Даже при существовании такой функции f (забудем пока про взаимную однозначность) MyIdEquals будет отличаться от ReferenceEquals S>MyIdEquals(a,b) == MyIdEquals(f(a),f(b)) == ReferenceEquals(f(a),f(b)) != ReferenceEquals(a, b)
S>А теперь по поводу взаимной однозначности f. Если она взаимно однозначна, то существует обратная ей взаимно однозначная f' такая что f'(f(a))==a и f'(f(b))==b. Из равенства ссылок f(a)==f(b) будет следовать a==b....
Да, взаимной однозначности этой функции не нужно, это я сдуру написал.
Посмотри как оно работает в COM. Там ссылки на объект могут не совпадать если запрашивать разные интерфейсы, но если запрашивать IUnknown то полученные ссылки будут совпадать.
G>>>>Ты так и не смог сказать что такое логическая идентичность, оно у тебя больше похоже на эквивалентность, которая в общем случае идентичностью не является. S>>>Вообще говоря, хорошая идентичность будет эквивалентностью. G>>Вообще говоря любая Даже без ООП
S>Давай тогда разберемся. чем идентичность отличается от отношения эквивалентности кроме требований возможности отправки сообщения по ссылке, сохранения идентичности при смене состояния?
Идентичность такое отношение эквивалентности, при котором объект эквивалентен сам себе и не эквивалентен, независимо от состояния и поведения.
S>Что может мою идентичность сделать неидентичностью в общем смысле? Что ее отличает от идентичности ECMA — я догадываюсь
То что твоя идентичность будет зависеть от состояния и\или поведения.
G>>Я как-то с самого начала не запутался. Хотя надо было сразу прочитать Ecma-335, а не пытаться тебе доказывать очевидные вещи. S>По-моему ты все еще пытаешься найти опровержение другим идентичностям, оперируюя идентичностью ECMA-335. Залез в скафандр ECMA-335 и говоришь что другие скафандры фуфло, потому как в них нельзя влезть, не снимая ECMA-335. Извини, если что.
Ну я тебе говорю, предложи другую систему, где identity будет не ссылкой и не будет существовать отображения f которая сделает ссылки равными для объектов с совпадающим identity.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>Это противоречит определению так как ты на состояние будешь ориентироваться. S>>>Определение не запрещает ориентироваться. Оно запрещает id изменяться вместе с состоянием объекта.
G>>Ну так оно у тебя будет меняться. Даже readonly можно поменять с помощью рефлексии, все еще оставаясь в рамках CLR. S>Но не в рамках OOP
Причем тут ООП? В ООП есть неизменяемые поля? readonly — не более чем особенность компилятора.
G>>>>Это получится как раз определение эквивалентности, но не идентичности. S>>>И эквивалентности и идентичности. G>>Нет, не идентичности. S>Я читаю определени идентичности так: независит от состояния == сохраняется при изменении состояния.
Да, причем при любом изменении, доступном в рамках системы. Конкретно в рамках СLR.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, artelk, Вы писали:
A>>>Например, назначать коллекции стратегию сравнивания. G>>Коллекция тоже не тобой написана. Счиатй что у тебя изначально нет возможности переопределит операцию сравнения. Как будет выполняться операция Collection.Remove(item) S>По назначенному компареру
Еще раз: нет возможности переопределить операцию сравнения никак, ни компарер, ни equals, вообще никак.
A>>>А вообще, вопрос был не в том, с какими проблемами мы можем столкнуться в текущем проекте, если с завтрашнего дня внезапно появится запрет на вызов ReferenceEquals и всего, что его использует. G>>Как минимум BCL не соберется\перестанет работать. Ты кстати скорее всего можешь сымитировать ситуацию через profile api, подменив вызов RefenceEquals, если он не intrsink какойнить. S>Нет цели заставить работать BCL, нет нужды подменять вызов ReferenceEquals. Мы просто показываем, что остаемся в рамках OOP, ослабив идентичность ECMA~location. Других целей нет.
Ну показывай. Тебе это не удается.
G>>>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm A>>>Хорошая ссылка. G>>Конечно, прочитай внимательно все три определения. Все три верны и отражают разные аспекты одного и того же. S>Все три допускают идентичность более слабую, чем ECMA.
Приведи пример. Пока это не удалось никому.
A>>>Определение через locations — слишком узко. G>>Для чего? Практика показывает что для CLR самое то. Ты не можешь расширить это определение (то есть получить идентичность без равенства ссылок) оставаясь в рамках ECMA-335. S>Отказываясь от идентичности ECMA-335 мы уже выходим за его рамки просто по определению. Раз выходим — нет нужды в них обратно лезть.
То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок?
G>>Источник твоего "вдохновения" в этом случае — РСУБД, которая не является ОО-системой если что S>Ну и что? Я не понимаю, чего ты боишься? Что вдруг окажется что альтернативная идентичность может иметь место? Тебя ведь не заставляют ее использовать вместо ECMA?
Я ничего не боюсь, ты просто приводи адекватные примеры. Нас интересует идентичность в ОО системах, например реляционная алгебра не требует идентичности, там определяй или нет — твое дело.
Здравствуйте, gandjustas, Вы писали:
G>То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок?
В рамках определения понятия "идентичность", данного в ECMA-335 — конечно невозможно.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок? A>В рамках определения понятия "идентичность", данного в ECMA-335 — конечно невозможно.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
G>>>То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок? A>>В рамках определения понятия "идентичность", данного в ECMA-335 — конечно невозможно.
G>Нет в рамках определения по ссылке http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm, но чтобы работало в CLR. G>Ты же именно это пытаешься доказать уже на протяжении кучи постов.
Ага, а критерием, для выяснения того, что мне это удалось или нет, будет выступать то, на сколько оно удовлетворяет определениям из ECMA-335...
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>ECMA335 определяет идентичность и тем самым устанавливает, где один объект, а где другой. Другая идентичность введет другое отношение. Почему ты ожидаешь от другой идентичности что она будет оперировать "объектами по ECMA335"? ECMA335 объект != объект по любой другой идентичности, отличающейся от ECMA335. Есть какие-то проблемы с пониманием этого?
G>Идентичность не есть объект, это свойство объекта, читай определение. То есть объект в широком смысле может существовать и без идентичности. G>Например две строки в БД без ключей. Если они совпадают, то это никак не различишь их. Но тем не менее это разные объекты. G>Вот как раз ооп говорит что разные объекты должны быть различимы с помощью id.
G>Смотри:
G>
G>var a = new object();
G>var b = new object();
G>var c = a;
G>
G>a и b — разные объекты, их identity должны различаться. a и c — один и тот же объект, соответственно id, полученное из a и c будет совпадать. G>Если ты id определить как структурную эквивалентность — это не будет выполняться.
Хм, именно так, через структурную эквивалентность в ECMA определили identity для value type И сказали считать их идентичными. Т.е. два разных значения, в разных location, они велели считать идентичными. Ничего не смущает? Я о том и говорю, что именно идентичность говорит что считать идентичным чему.
S>>Функция Дирихле изоморфна задаче определения иррациональности числа. Ты предлагаешь выпихнуть эту задачу из функции. Ну да ладно, задача-то осталась не решена, хоть функция и будет написана. Я так же могу написать функцию, коллапсирующую вселенную. Давай с этим завязывать. G>Это она в математике изоморфна, а в компьютере приходится учитывать специфику. Почитай кнута, третий том кажись, про арифметику в компьютере.
Я не представляю, о какой специфике ты говоришь. На бумаге тоже пока никто не записал иррационального числа. До сих пор только обозначали их.
G>>>Тогда их сравнивать бессмысленно и можно просто запретить операцию. S>>Зачем запрещать? Идентичность по ECMA останется. Вдруг, запретив ReferenceEquals, мы не сможем поднять рантайм? G>Ты же предлагаешь написать что-то, что сможет заменить referenceequals.
Нет, не предлагал его заменять.
S>>Если бы ты согласился с тем что алтернативная идентичность задает альтернативное отношение идентичности/эквивалентности объектов, то уже сам бы написал. G>Нету альтернативной идентичности, идентичность задается определением. Могут быть разные реализации. Но ты пока не привел ни одной, которая никак не противоречит определению.
Синклер приводил.
G>Посмотри как оно работает в COM. Там ссылки на объект могут не совпадать если запрашивать разные интерфейсы, но если запрашивать IUnknown то полученные ссылки будут совпадать.
Ну и незачем на него смотреть. COM явно выпадает из определения идентичности в OOP если не запрашивать IUnknown, хотя бы потому как нарушена рефлексивность. Если запрашивать IUnknown и только лишь его, то COM становится ничем не интереснее обычного объекта при условии корректной реализации.
S>>Давай тогда разберемся. чем идентичность отличается от отношения эквивалентности кроме требований возможности отправки сообщения по ссылке, сохранения идентичности при смене состояния? G>Идентичность такое отношение эквивалентности, при котором объект эквивалентен сам себе и не эквивалентен, независимо от состояния и поведения.
полагаю, что "не" лишняя.
Вот как раз ECMA-335 8.2.5.1 пункт 2 задает идентичность для value types с нарушением двух пунктов. Значение эквивалентно самому себе и всем другим с подобными bit sequences. И состояние может нарушить эту идентичность.
S>>Что может мою идентичность сделать неидентичностью в общем смысле? Что ее отличает от идентичности ECMA — я догадываюсь G>То что твоя идентичность будет зависеть от состояния и\или поведения.
Не будет.
G>>>Я как-то с самого начала не запутался. Хотя надо было сразу прочитать Ecma-335, а не пытаться тебе доказывать очевидные вещи. S>>По-моему ты все еще пытаешься найти опровержение другим идентичностям, оперируюя идентичностью ECMA-335. Залез в скафандр ECMA-335 и говоришь что другие скафандры фуфло, потому как в них нельзя влезть, не снимая ECMA-335. Извини, если что. G>Ну я тебе говорю, предложи другую систему, где identity будет не ссылкой и не будет существовать отображения f которая сделает ссылки равными для объектов с совпадающим identity.
А я тебе говорю, что
1) identity это не ссылка даже по ECMA-335. По ECMA identity это бинарное отношение.
2) существование отображения — это слишком сильное требование. Допустим, по моей identity две равных (ordered) строки будут идентичны, в отличии от ECMA-335. Ты мне создаешь функцию, которая будет всегда возвращать интернированную строку, и получается что ReferenceEquals(f(a), f(b)) == true. Хотя по определению ECMA эти строки будут разными объектами, т.к. ReferenceEquals(a, b) == false. И что ты мне хочешь доказать существованием такого отображения? Что две identity эквивалентны? Нет, они не эквивалентны.
Забудь про отображение f. Ничего оно никому не дает.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Коллекция тоже не тобой написана. Счиатй что у тебя изначально нет возможности переопределит операцию сравнения. Как будет выполняться операция Collection.Remove(item) S>>По назначенному компареру G>Еще раз: нет возможности переопределить операцию сравнения никак, ни компарер, ни equals, вообще никак.
Остается задвинуть на эту досадную коллекцию. Никто не обещал совместимость альтернативной идентичности со всем написанным кодом.
S>>Нет цели заставить работать BCL, нет нужды подменять вызов ReferenceEquals. Мы просто показываем, что остаемся в рамках OOP, ослабив идентичность ECMA~location. Других целей нет. G>Ну показывай. Тебе это не удается.
G>>>Конечно, прочитай внимательно все три определения. Все три верны и отражают разные аспекты одного и того же. S>>Все три допускают идентичность более слабую, чем ECMA. G>Приведи пример. Пока это не удалось никому.
Я думаю, что никто не пытался
S>>Отказываясь от идентичности ECMA-335 мы уже выходим за его рамки просто по определению. Раз выходим — нет нужды в них обратно лезть. G>То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок?
Я не собирался определять идентичность в CLR. Я собирался показать отношение, удовлетворяющее идентичности ООП и отличное от идентичности ECMA-335. Из CLR ты можешь на него смотреть как на еще одно отношение эквивалентности.
S>>Ну и что? Я не понимаю, чего ты боишься? Что вдруг окажется что альтернативная идентичность может иметь место? Тебя ведь не заставляют ее использовать вместо ECMA? G>Я ничего не боюсь, ты просто приводи адекватные примеры. Нас интересует идентичность в ОО системах, например реляционная алгебра не требует идентичности, там определяй или нет — твое дело.
Сначала надо отвоевать позиции по определениям идентичностей. А после этого придет разочарование, т.к. ввести идентичность будет слишком тривиально, и практически нафиг не нужно.
Но вот, незадача, еще один фронт открылся — рефлексионный...
A>artelk> Приведи пример задачи, которую нельзя решить без использования object.ReferenceEquals. A>gandjustas> Хорошо, задача: нужно реализовать object.ReferenceEquals с текущим его поведением. A>
A>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы?
Да сразу же, как начнём писать.
public class Crash
{
public int A { get; set; }
public override bool Equals(object o) {??? };
}
var a = new Crash(); a.A = 1;
var b = new Crash(); b.A = 2;
var l = new List<A>();
l.Add(a); l.Add(b);
a.A = 2;
l.Remove(b);
a.A = 1;
Assert(l.IndexOf(a) >= 0);
Приведите, пожалуйста, свою перегрузку метода Equals, не использующую сравнение ссылок. Задача — в том, чтобы ассерт выполнился.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, artelk, Вы писали:
G>>>>То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок? A>>>В рамках определения понятия "идентичность", данного в ECMA-335 — конечно невозможно.
G>>Нет в рамках определения по ссылке http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm, но чтобы работало в CLR. G>>Ты же именно это пытаешься доказать уже на протяжении кучи постов.
A>Ага, а критерием, для выяснения того, что мне это удалось или нет, будет выступать то, на сколько оно удовлетворяет определениям из ECMA-335...
Нет. Надо чтобы удовлетворяло определениям по ссылке, но работало в CLR.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, artelk, Вы писали:
G>>>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm A>>>Хорошая ссылка. G>>Конечно, прочитай внимательно все три определения. Все три верны и отражают разные аспекты одного и того же. A>Кстати, а чем ты руководствуешься, утверждая, что эти определения верны, а, например, приведенные в википедии — нет; что выступает в качестве критерия их верности?
Википедии вообще не доверяю, там шлака много. Ты же сам приводил очень противоречивые цитаты оттуда.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
A>>Здравствуйте, gandjustas, Вы писали:
G>>>Здравствуйте, artelk, Вы писали:
G>>>>>http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm A>>>>Хорошая ссылка. G>>>Конечно, прочитай внимательно все три определения. Все три верны и отражают разные аспекты одного и того же. A>>Кстати, а чем ты руководствуешься, утверждая, что эти определения верны, а, например, приведенные в википедии — нет; что выступает в качестве критерия их верности?
G>Википедии вообще не доверяю, там шлака много. Ты же сам приводил очень противоречивые цитаты оттуда.
А не, это не ты приводил. Ну прочитай тему внимательно, там много чего есть.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
S>Хм, именно так, через структурную эквивалентность в ECMA определили identity для value type И сказали считать их идентичными. Т.е. два разных значения, в разных location, они велели считать идентичными. Ничего не смущает? Я о том и говорю, что именно идентичность говорит что считать идентичным чему.
Не смущает. Value-type находится за пределами ООП, там это совершенно нормально.
Мы ведь все еще про ООП говорим, не так ли?
S>>>Функция Дирихле изоморфна задаче определения иррациональности числа. Ты предлагаешь выпихнуть эту задачу из функции. Ну да ладно, задача-то осталась не решена, хоть функция и будет написана. Я так же могу написать функцию, коллапсирующую вселенную. Давай с этим завязывать. G>>Это она в математике изоморфна, а в компьютере приходится учитывать специфику. Почитай кнута, третий том кажись, про арифметику в компьютере. S>Я не представляю, о какой специфике ты говоришь. На бумаге тоже пока никто не записал иррационального числа. До сих пор только обозначали их.
Нет, на бумаге мы оперируем символьными вычислениями, а в компьютере — значениями.
G>>>>Тогда их сравнивать бессмысленно и можно просто запретить операцию. S>>>Зачем запрещать? Идентичность по ECMA останется. Вдруг, запретив ReferenceEquals, мы не сможем поднять рантайм? G>>Ты же предлагаешь написать что-то, что сможет заменить referenceequals. S>Нет, не предлагал его заменять.
Идентичность для reference-типов в CLR реализуется referenceequals, ты хотел свою идентичность написать, то есть по сути заменить этот referenceequals.
S>>>Если бы ты согласился с тем что алтернативная идентичность задает альтернативное отношение идентичности/эквивалентности объектов, то уже сам бы написал. G>>Нету альтернативной идентичности, идентичность задается определением. Могут быть разные реализации. Но ты пока не привел ни одной, которая никак не противоречит определению. S>Синклер приводил.
Ага, она очень легко сводится в сравнению ссылок.
G>>Посмотри как оно работает в COM. Там ссылки на объект могут не совпадать если запрашивать разные интерфейсы, но если запрашивать IUnknown то полученные ссылки будут совпадать. S>Ну и незачем на него смотреть. COM явно выпадает из определения идентичности в OOP если не запрашивать IUnknown, хотя бы потому как нарушена рефлексивность. Если запрашивать IUnknown и только лишь его, то COM становится ничем не интереснее обычного объекта при условии корректной реализации.
Ни разу не выпадает. У объектов есть identity, им можно отправлять сообщения. Там и наследование и полиморфизм тоже есть.
То есть формально com соответствует ООП.
S>>>Давай тогда разберемся. чем идентичность отличается от отношения эквивалентности кроме требований возможности отправки сообщения по ссылке, сохранения идентичности при смене состояния? G>>Идентичность такое отношение эквивалентности, при котором объект эквивалентен сам себе и не эквивалентен, независимо от состояния и поведения. S>полагаю, что "не" лишняя.
Нет, не написал что не эквивалентен другим объектам.
S>Вот как раз ECMA-335 8.2.5.1 пункт 2 задает идентичность для value types с нарушением двух пунктов. Значение эквивалентно самому себе и всем другим с подобными bit sequences. И состояние может нарушить эту идентичность.
Но value-types — не ооп. Там свойство идентичности, которое говорит о том что для идентичных объектов любое изменение в одном отражается на другом, не выполняется.
S>>>Что может мою идентичность сделать неидентичностью в общем смысле? Что ее отличает от идентичности ECMA — я догадываюсь G>>То что твоя идентичность будет зависеть от состояния и\или поведения. S>Не будет.
Ты же сам говоришь что она будет реализована через операцию сравнения полей (состояния).
G>>>>Я как-то с самого начала не запутался. Хотя надо было сразу прочитать Ecma-335, а не пытаться тебе доказывать очевидные вещи. S>>>По-моему ты все еще пытаешься найти опровержение другим идентичностям, оперируюя идентичностью ECMA-335. Залез в скафандр ECMA-335 и говоришь что другие скафандры фуфло, потому как в них нельзя влезть, не снимая ECMA-335. Извини, если что. G>>Ну я тебе говорю, предложи другую систему, где identity будет не ссылкой и не будет существовать отображения f которая сделает ссылки равными для объектов с совпадающим identity.
S>А я тебе говорю, что S>1) identity это не ссылка даже по ECMA-335. По ECMA identity это бинарное отношение.
Бинарное отношение в каком множестве? Видимо "ссылок".
S>2) существование отображения — это слишком сильное требование. Допустим, по моей identity две равных (ordered) строки будут идентичны, в отличии от ECMA-335. Ты мне создаешь функцию, которая будет всегда возвращать интернированную строку, и получается что ReferenceEquals(f(a), f(b)) == true. Хотя по определению ECMA эти строки будут разными объектами, т.к. ReferenceEquals(a, b) == false. И что ты мне хочешь доказать существованием такого отображения? Что две identity эквивалентны? Нет, они не эквивалентны.
Нет ты опять пытаешься опираться на поведение, определяя идентичность через некоторые свойства объекта. Для начала построй идентичность, которая будет для любого типа работать, а потом будем искать f. Если ты найдешь f для какого типа идентичность не появится
S>Забудь про отображение f. Ничего оно никому не дает.
В COM дает, ты споришь с фактами.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>Коллекция тоже не тобой написана. Счиатй что у тебя изначально нет возможности переопределит операцию сравнения. Как будет выполняться операция Collection.Remove(item) S>>>По назначенному компареру G>>Еще раз: нет возможности переопределить операцию сравнения никак, ни компарер, ни equals, вообще никак. S>Остается задвинуть на эту досадную коллекцию. Никто не обещал совместимость альтернативной идентичности со всем написанным кодом.
Тем не менее коллекция есть, объект есть, сделай так чтобы Collectio.Remove(item) работало. Ведь в CLR оно работает.
Будем считать что у тебя есть возможность сделать свою идентичность для CLR, как ты её определишь? Естественно ты тип item заранее не знаешь.
S>>>Отказываясь от идентичности ECMA-335 мы уже выходим за его рамки просто по определению. Раз выходим — нет нужды в них обратно лезть. G>>То есть ты согласен, что в clr невозможно определить идентичность не сравнением ссылок? S>Я не собирался определять идентичность в CLR. Я собирался показать отношение, удовлетворяющее идентичности ООП и отличное от идентичности ECMA-335. Из CLR ты можешь на него смотреть как на еще одно отношение эквивалентности.
Оно должно быть отношением идентичности в CLR или другой системе, которую ты придумаешь. При этом не должно существовать функции f, позволяющей свести твое отношение идентичности к сравнению "ссылок".
Такой пример уже есть. COM — формально ООП, для идентичных объектов могут ссылки не совпадать, но при QureyInterface(IUnknown) совпадают.
S>Но вот, незадача, еще один фронт открылся — рефлексионный...
Никаких фронтов. Сравнение неизменяемого состояния опирается как на само состояние (значения), так и на поведение (неизменяемость). Такая эквивалентность вдвойне неправильна а CLR позволяет быстро это доказать.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Там, где ты выделил жирным, ты описал свойство identity через понятие одинаковых и разных объектов. Я пишу что наоборот, identity определяет где разные, а где одинаковые (same) объекты. S>Теория требует, чтобы identity и, э-м-м, "самоэквивалентность" объекта были одним и тем же. Не задавая какого-то конкретного "направления" эквивалентности.
Не понял, к чему это. Под самоэквивалентностью подразумевается рефлексивность? Если да, то оно требуется отношением эквивалентности. Identity должна быть эквивалентностью. Это напрямую не требуется, но без этого все криво. Или самоэквивалентность это что-то другое?
S>Проводим простой эксперимент: определяем функцию ID(obj) == 0.
Очень интересный эксперимент
Правда,
S>Эта функция вводит вполне нормальное с точки зрения математики отношение эквивалентности. Наша идентити успешно определила все объекты, как одинаковые. Подходит ли она под определение identity из OOP или всё-таки нет?
Да, подходит. Формально подходит. Она задает идентичность таким образом, что у нас в системе существует не более одного объекта. И даже эта идентичность позволяет отличать этот объект от всех остальных, как и написано в определении. Проблема лишь в том, что остальных не будет, т.к. объектов не более одного.
S>Если не подходит, то почему?
Подходит. Бредово, но согласно моему пониманию идентичности, именно идентичность указывает где same объекты, а где нет. И identity из ECMA именно так и поступает в отношении value типов.
Да, value не объекты. Но и идентичность в ECMA задана не для объектов а для значений. И в отношении value значений она однозначно указывает что два значения надо считать идентичными при совпадении bit sequences.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, artelk, Вы писали:
S>
S>public class Crash
S>{
S> public int A { get; set; }
S> public override bool Equals(object o) {??? };
S>}
S>var a = new Crash(); a.A = 1;
S>var b = new Crash(); b.A = 2;
S>var l = new List<A>();
S>l.Add(a); l.Add(b);
S>a.A = 2;
S>l.Remove(b);
S>a.A = 1;
S>Assert(l.IndexOf(a) >= 0);
S>
S>Приведите, пожалуйста, свою перегрузку метода Equals, не использующую сравнение ссылок. Задача — в том, чтобы ассерт выполнился.
"Не использующую сравнение ссылок" — это слишком жестоко. artelk говорил о том что идентичность ECMA слишком сильная и что ее можно ослабить. Это не значит что нужно совсем отказаться от сравнения ссылок. Ослаблять идентичность ECMA опять-таки можно не где-попало. И этот пример это подтверждает.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Хм, именно так, через структурную эквивалентность в ECMA определили identity для value type И сказали считать их идентичными. Т.е. два разных значения, в разных location, они велели считать идентичными. Ничего не смущает? Я о том и говорю, что именно идентичность говорит что считать идентичным чему. G>Не смущает. Value-type находится за пределами ООП, там это совершенно нормально.
Окей, пусть Value не ООП. А COM разве не уточняет понятие идентичности? G>Мы ведь все еще про ООП говорим, не так ли?
Да.
S>>Я не представляю, о какой специфике ты говоришь. На бумаге тоже пока никто не записал иррационального числа. До сих пор только обозначали их. G>Нет, на бумаге мы оперируем символьными вычислениями, а в компьютере — значениями.
И компьютер и бумага позволяют нам использовать абстракции. В частности, создавая в ООП класс "Дробь" мы можем пользоваться не значениями а символьными вычислениями.
G>>>>>Тогда их сравнивать бессмысленно и можно просто запретить операцию. S>>>>Зачем запрещать? Идентичность по ECMA останется. Вдруг, запретив ReferenceEquals, мы не сможем поднять рантайм? G>>>Ты же предлагаешь написать что-то, что сможет заменить referenceequals. S>>Нет, не предлагал его заменять. G>Идентичность для reference-типов в CLR реализуется referenceequals, ты хотел свою идентичность написать, то есть по сути заменить этот referenceequals.
Нет, не заменить. Я хотел показать что есть другое отношение идентичности, не совпадающее со сравнением ссылок.
S>>>>Если бы ты согласился с тем что алтернативная идентичность задает альтернативное отношение идентичности/эквивалентности объектов, то уже сам бы написал. G>>>Нету альтернативной идентичности, идентичность задается определением. Могут быть разные реализации. Но ты пока не привел ни одной, которая никак не противоречит определению. S>>Синклер приводил. G>Ага, она очень легко сводится в сравнению ссылок.
Да, наверное.
G>>>Посмотри как оно работает в COM. Там ссылки на объект могут не совпадать если запрашивать разные интерфейсы, но если запрашивать IUnknown то полученные ссылки будут совпадать. S>>Ну и незачем на него смотреть. COM явно выпадает из определения идентичности в OOP если не запрашивать IUnknown, хотя бы потому как нарушена рефлексивность. Если запрашивать IUnknown и только лишь его, то COM становится ничем не интереснее обычного объекта при условии корректной реализации. G>Ни разу не выпадает. У объектов есть identity, им можно отправлять сообщения. Там и наследование и полиморфизм тоже есть. G>То есть формально com соответствует ООП.
Формально COM соответствует OOP но лишь со своим требованием к реализации объектов, которое требует same physical pointer value у реализаций IUnknown. COM identity ослабляет identity, основанное на memory location. Если это требование не выполнить, то получится каша а не OOP.
S>>>>Давай тогда разберемся. чем идентичность отличается от отношения эквивалентности кроме требований возможности отправки сообщения по ссылке, сохранения идентичности при смене состояния? G>>>Идентичность такое отношение эквивалентности, при котором объект эквивалентен сам себе и не эквивалентен, независимо от состояния и поведения. S>>полагаю, что "не" лишняя. G>Нет, не написал что не эквивалентен другим объектам.
Если не эквивалентен другим, тогда понятно. Но это неверно. Идентичность определяет где один объект, а где другой. Не хочешь смотреть на CLR value type — посмотри на COM, где для идентичности сделана оговорка про IUnknown.
S>>Вот как раз ECMA-335 8.2.5.1 пункт 2 задает идентичность для value types с нарушением двух пунктов. Значение эквивалентно самому себе и всем другим с подобными bit sequences. И состояние может нарушить эту идентичность. G>Но value-types — не ооп. Там свойство идентичности, которое говорит о том что для идентичных объектов любое изменение в одном отражается на другом, не выполняется.
А если запретить изменения в value типе? Не во всех, а в конкретном? Он станет OOP?
S>>>>Что может мою идентичность сделать неидентичностью в общем смысле? Что ее отличает от идентичности ECMA — я догадываюсь G>>>То что твоя идентичность будет зависеть от состояния и\или поведения. S>>Не будет. G>Ты же сам говоришь что она будет реализована через операцию сравнения полей (состояния).
Я уже писал что независимость идентичности от состояния означает неизменность идентичности при изменении состояния. Нигде в определениях не запрещено сравнивать состояния.
Вот тебе задачка про COM, который ООП. Есть у тебя два сырых различных указателя IUnknown*, определи, указывают ли они на один COM объект, не используя состояние и поведение Что бы не было недопонимания, эти указатели могут указывать не на IUnknown грань, а на IDispatch, например.
G>>>>>Я как-то с самого начала не запутался. Хотя надо было сразу прочитать Ecma-335, а не пытаться тебе доказывать очевидные вещи. S>>>>По-моему ты все еще пытаешься найти опровержение другим идентичностям, оперируюя идентичностью ECMA-335. Залез в скафандр ECMA-335 и говоришь что другие скафандры фуфло, потому как в них нельзя влезть, не снимая ECMA-335. Извини, если что. G>>>Ну я тебе говорю, предложи другую систему, где identity будет не ссылкой и не будет существовать отображения f которая сделает ссылки равными для объектов с совпадающим identity.
S>>А я тебе говорю, что S>>1) identity это не ссылка даже по ECMA-335. По ECMA identity это бинарное отношение. G>Бинарное отношение в каком множестве? Видимо "ссылок".
8.2.5 Identity and equality of values
There are two binary operators defined on all pairs of values: identity and equality.
S>>2) существование отображения — это слишком сильное требование. Допустим, по моей identity две равных (ordered) строки будут идентичны, в отличии от ECMA-335. Ты мне создаешь функцию, которая будет всегда возвращать интернированную строку, и получается что ReferenceEquals(f(a), f(b)) == true. Хотя по определению ECMA эти строки будут разными объектами, т.к. ReferenceEquals(a, b) == false. И что ты мне хочешь доказать существованием такого отображения? Что две identity эквивалентны? Нет, они не эквивалентны. G>Нет ты опять пытаешься опираться на поведение, определяя идентичность через некоторые свойства объекта. Для начала построй идентичность, которая будет для любого типа работать, а потом будем искать f. Если ты найдешь f для какого типа идентичность не появится
Ты приводишь в пример COM, а он нарушает твою же трактовку независимости от состояния.
Не пойму, откуда взялась такая функция и почему она будет говорить что идентичность не появится?
S>>Забудь про отображение f. Ничего оно никому не дает. G>В COM дает, ты споришь с фактами.
В COM используется состояние для сравнения ссылок. Ты тоже споришь с фактами.
Здравствуйте, samius, Вы писали:
S>>>Я не представляю, о какой специфике ты говоришь. На бумаге тоже пока никто не записал иррационального числа. До сих пор только обозначали их. G>>Нет, на бумаге мы оперируем символьными вычислениями, а в компьютере — значениями. S>И компьютер и бумага позволяют нам использовать абстракции. В частности, создавая в ООП класс "Дробь" мы можем пользоваться не значениями а символьными вычислениями.
Да, и в таком случае определить функцию дирихле будет тривиально, так как само число при этом будет знать рациональное оно или нет.
G>>Идентичность для reference-типов в CLR реализуется referenceequals, ты хотел свою идентичность написать, то есть по сути заменить этот referenceequals. S>Нет, не заменить. Я хотел показать что есть другое отношение идентичности, не совпадающее со сравнением ссылок.
Это значит что его повсеместно можно использовать вместо referenceequals без изменения результатов работы программы.
S>Формально COM соответствует OOP но лишь со своим требованием к реализации объектов, которое требует same physical pointer value у реализаций IUnknown. COM identity ослабляет identity, основанное на memory location. Если это требование не выполнить, то получится каша а не OOP.
Если это требование не выполнить, то получится не COM. То есть COM — ООП.
S>Если не эквивалентен другим, тогда понятно. Но это неверно. Идентичность определяет где один объект, а где другой.
Математически это выглядит как id(a)=id(b), когда a и b — один и тот же объект, id(a)!=id(b), когда a и b — разные объекты. Я уже это формально доказывал. Соответственно нам заранее необходимо знание о разных объектах, иначе любое отношение эквивалентности можно назвать идентичностью.
Тут нам на помощь приходят свойства
1)Независимость состояния и поведения
2)если объекты идентичны, то любое изменение в одном отражается на другом.
S>хочешь смотреть на CLR value type — посмотри на COM, где для идентичности сделана оговорка про IUnknown.
Value type в CLR — не ООП, в COM идентичность определена через QueryInterface(IUnknown). Фактически любая ссылка сводится к "инвариантной", которые уже можно сравнивать для идентичности. Это та функция f, про которую я говорил.
Соответственно тебе нет смысла доказывать что существует система с какой-то идентичностью если в ней есть такая функция, которая сведет все к сравнению ссылок, так как можно тогда любые ссылки в системе заменить на "инвариантные".
S>>>Вот как раз ECMA-335 8.2.5.1 пункт 2 задает идентичность для value types с нарушением двух пунктов. Значение эквивалентно самому себе и всем другим с подобными bit sequences. И состояние может нарушить эту идентичность. G>>Но value-types — не ооп. Там свойство идентичности, которое говорит о том что для идентичных объектов любое изменение в одном отражается на другом, не выполняется. S>А если запретить изменения в value типе? Не во всех, а в конкретном? Он станет OOP?
Нет, идентичность не может быть определена "для конкретного типа", потому что "конкретный тип" это поведение от которого идентичность не должна зависеть.
S>Вот тебе задачка про COM, который ООП. Есть у тебя два сырых различных указателя IUnknown*, определи, указывают ли они на один COM объект, не используя состояние и поведение Что бы не было недопонимания, эти указатели могут указывать не на IUnknown грань, а на IDispatch, например.
QueryInterface(IUnknown) даст равные ссылки, независимо от типа\объекта и его состояния, это требование спецификации COM. Если объект не следует спецификации, то это не COM и соответственно — не ООП.
G>>>>>>Я как-то с самого начала не запутался. Хотя надо было сразу прочитать Ecma-335, а не пытаться тебе доказывать очевидные вещи. S>>>>>По-моему ты все еще пытаешься найти опровержение другим идентичностям, оперируюя идентичностью ECMA-335. Залез в скафандр ECMA-335 и говоришь что другие скафандры фуфло, потому как в них нельзя влезть, не снимая ECMA-335. Извини, если что. G>>>>Ну я тебе говорю, предложи другую систему, где identity будет не ссылкой и не будет существовать отображения f которая сделает ссылки равными для объектов с совпадающим identity.
S>>>А я тебе говорю, что S>>>1) identity это не ссылка даже по ECMA-335. По ECMA identity это бинарное отношение. G>>Бинарное отношение в каком множестве? Видимо "ссылок". S>
S>8.2.5 Identity and equality of values
S>There are two binary operators defined on all pairs of values: identity and equality.
Мы только про reference-типы говорим, потому что value-типы — не ООП.
G>>Нет ты опять пытаешься опираться на поведение, определяя идентичность через некоторые свойства объекта. Для начала построй идентичность, которая будет для любого типа работать, а потом будем искать f. Если ты найдешь f для какого типа идентичность не появится S>Ты приводишь в пример COM, а он нарушает твою же трактовку независимости от состояния.
Нет. Потому что любой объект при QueryInterface(IUnknown) сколько угодно раз должен возвращать одно то же значение, независимо от типа и состояния.
Это и есть та самая независимость. А ты пока не можешь привести пример такой функции id, которая не будет опираться на поведение и\или состояние и при изменении одного и\или другого перестанет работать.
S>Не пойму, откуда взялась такая функция и почему она будет говорить что идентичность не появится?
Потому что ты над обычной ссылкой на объект можешь настраивать сколько угодной уровней косвенности, но в этом просто нет смысла. В com эта мера вынужденная.
S>>>Забудь про отображение f. Ничего оно никому не дает. G>>В COM дает, ты споришь с фактами. S>В COM используется состояние для сравнения ссылок. Ты тоже споришь с фактами.
Какое состояние?
Ты создай ЛЮБОЙ COM-объет. Получи две ссылки на разные интерфейсы от него. Потом для обоих вызови QueryInterface(IUnknown) и ты получишь одинаковые значения. Где тут состояние?
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
S>Речи не было о том что бы взять совершенно другую идентичность. Я хотел взять немного другую идентичность, которая для некоторых хороших типов, была бы слабже чем штатная. Для всех остальных — ReferenceEquals. Соответственно, для любого наперед неизвестного типа это было бы сравнение ссылок. Для хороших типов типа строк — сравнение значений.
"Для некоторых хороших типов" — зависит от поведения.
S>Собственно вот я все и выложил. Осталось ввернуть пару строк псевдокода: S>
S>bool MyIdentityEquals(object a, object b)
S>{
S> if (ReferenceEquals(a,b))
S> return true; // ослабить а не изменить в корне
S> if (a == null || b == null)
S> return false; // не знаю что определено в штатном порядке, пусть будет так.
S> var type = a.GetType();
S> if (type != b.GetType())
S> return false;
S> if (type == typeof(string) && StringComparer.Ordinal.Equals((string)a, (string)b))
S> return true;
S> // тут обработка хороших типов.
S> if (IsImmutable(type) && IsStructuralEquals(a, b))
S> return true;
S> return false;
S>}
S>
1)Ты явно используешь поведение, когда сравниваешь строки.
2)Ты явно используешь состояние при сравнении. reflection испортит тебе идентичность
3)Есть подозрение что immutable выходит за рамки ООП
И кстати, как ты IsStructuralEquals определишь?
[Immutable]
class A
{
public B B { get; }
}
class B //не-immutable
{
public int Prop {get; set;}
}
var a = new A { B = new B { Prop = 1 } };
var b = new A { B = new B { Prop = 1 } };
Debug.Assert(MyIdentityEquals(a,b)); //Упадет?
b.B.Prop = 1;
Debug.Assert(MyIdentityEquals(a,b)); //А тут?
S>Если это подсунуть вместо штатной ReferenceEquals и забыть про Reflection, который не ООП, то мы останемся в рамках ООП и даже возможно обеспечим некоторую совместимость с ReferenceEquals.
А почему reflection не ООП? Например в самом ООП языке — smalltalk есть рефлексия. И свовйство что изменения в одном объекте сразу отражаются на другом, если объекты идентичны, тоже не говорит какие изменения. Значит в том числе refection.
А вот кстати использование только immutable объектов в программе скорее всего выходит за рамки ООП.
S>Только не говори, что QueryInterface не использует состояние
Ты удивишься, но не использует. Это также явно в спецификации прописано. QueryInterface для объекта должна быть детерминированной функцией, то есть зависеть только от параметров.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>Да, и в таком случае определить функцию дирихле будет тривиально, так как само число при этом будет знать рациональное оно или нет.
Ты вынес задачу из тела функции. Но не значит что решил эту задачу.
G>>>Идентичность для reference-типов в CLR реализуется referenceequals, ты хотел свою идентичность написать, то есть по сути заменить этот referenceequals. S>>Нет, не заменить. Я хотел показать что есть другое отношение идентичности, не совпадающее со сравнением ссылок. G>Это значит что его повсеместно можно использовать вместо referenceequals без изменения результатов работы программы.
Нет, не значит.
S>>Формально COM соответствует OOP но лишь со своим требованием к реализации объектов, которое требует same physical pointer value у реализаций IUnknown. COM identity ослабляет identity, основанное на memory location. Если это требование не выполнить, то получится каша а не OOP. G>Если это требование не выполнить, то получится не COM. То есть COM — ООП.
С оговоркой. Ибо в определении идентичности ООП никаких QueryInterface и IUnknown нет.
S>>Если не эквивалентен другим, тогда понятно. Но это неверно. Идентичность определяет где один объект, а где другой. G>Математически это выглядит как id(a)=id(b), когда a и b — один и тот же объект, id(a)!=id(b), когда a и b — разные объекты. Я уже это формально доказывал. Соответственно нам заранее необходимо знание о разных объектах, иначе любое отношение эквивалентности можно назвать идентичностью.
Знание о разных объектах дает идентичность по определению. Она и только она определяет где идентичные объекты, а где нет. G>Тут нам на помощь приходят свойства G>1)Независимость состояния и поведения
определение G>2)если объекты идентичны, то любое изменение в одном отражается на другом.
следствие
S>>хочешь смотреть на CLR value type — посмотри на COM, где для идентичности сделана оговорка про IUnknown. G>Value type в CLR — не ООП, в COM идентичность определена через QueryInterface(IUnknown). Фактически любая ссылка сводится к "инвариантной", которые уже можно сравнивать для идентичности. Это та функция f, про которую я говорил. G>Соответственно тебе нет смысла доказывать что существует система с какой-то идентичностью если в ней есть такая функция, которая сведет все к сравнению ссылок, так как можно тогда любые ссылки в системе заменить на "инвариантные".
В определении идентичности нет ничего об инвариантности и функции f.
Ладно. Зайдем с другой стороны. Я могу предложить функцию f, которая приняв две различные строки с равным содержимым вернет "инвариантную" ссылку. Значит ли это что две различные строки с разным содержимым стали одним объектом?
S>>>>Вот как раз ECMA-335 8.2.5.1 пункт 2 задает идентичность для value types с нарушением двух пунктов. Значение эквивалентно самому себе и всем другим с подобными bit sequences. И состояние может нарушить эту идентичность. G>>>Но value-types — не ооп. Там свойство идентичности, которое говорит о том что для идентичных объектов любое изменение в одном отражается на другом, не выполняется. S>>А если запретить изменения в value типе? Не во всех, а в конкретном? Он станет OOP? G>Нет, идентичность не может быть определена "для конкретного типа", потому что "конкретный тип" это поведение от которого идентичность не должна зависеть.
Идентичность не должна изменяться с изменением состояния и поведения.
S>>Вот тебе задачка про COM, который ООП. Есть у тебя два сырых различных указателя IUnknown*, определи, указывают ли они на один COM объект, не используя состояние и поведение Что бы не было недопонимания, эти указатели могут указывать не на IUnknown грань, а на IDispatch, например. G>QueryInterface(IUnknown) даст равные ссылки, независимо от типа\объекта и его состояния, это требование спецификации COM. Если объект не следует спецификации, то это не COM и соответственно — не ООП.
У тебя два указателя, указывающих на разные места в памяти. Ты еще не знаешь что это COM. Это разные объекты? Когда ты узнаешь что это COM, то тебе оказывается нужно обращаться к поведению этих объектов что бы определить, являются ли они одним объектом. Итого, ты используешь поведение, что бы узнать идентичность.
G>>>>>Ну я тебе говорю, предложи другую систему, где identity будет не ссылкой и не будет существовать отображения f которая сделает ссылки равными для объектов с совпадающим identity.
S>>>>А я тебе говорю, что S>>>>1) identity это не ссылка даже по ECMA-335. По ECMA identity это бинарное отношение. G>>>Бинарное отношение в каком множестве? Видимо "ссылок". S>>
S>>8.2.5 Identity and equality of values
S>>There are two binary operators defined on all pairs of values: identity and equality.
G>Мы только про reference-типы говорим, потому что value-типы — не ООП.
ладно, пусть value не ООП. Но именно определение ECMA указывает, что считать одним объектом а что другим для референсов. С этим будешь спорить?
G>>>Нет ты опять пытаешься опираться на поведение, определяя идентичность через некоторые свойства объекта. Для начала построй идентичность, которая будет для любого типа работать, а потом будем искать f. Если ты найдешь f для какого типа идентичность не появится S>>Ты приводишь в пример COM, а он нарушает твою же трактовку независимости от состояния. G>Нет. Потому что любой объект при QueryInterface(IUnknown) сколько угодно раз должен возвращать одно то же значение, независимо от типа и состояния.
Что бы получить результат QueryInterface(IUnknown), нужно воспользоваться состоянием и поведением, притом полиморфным. G>Это и есть та самая независимость. А ты пока не можешь привести пример такой функции id, которая не будет опираться на поведение и\или состояние и при изменении одного и\или другого перестанет работать.
Да уж, независимость
могу
class A {}
bool MyIdEquals(a, b)
{
if (ReferenceEquals(a, b))
return true;
if (a.GetType() == typeof(A) && b.GetType() == typeof(A))
return true;
return false;
}
S>>Не пойму, откуда взялась такая функция и почему она будет говорить что идентичность не появится? G>Потому что ты над обычной ссылкой на объект можешь настраивать сколько угодной уровней косвенности, но в этом просто нет смысла. В com эта мера вынужденная.
Согласно этой логике две разные строки есть один объект. Но это противоречит identity ECMA. Выбирай, ECMA или f.
S>>>>Забудь про отображение f. Ничего оно никому не дает. G>>>В COM дает, ты споришь с фактами. S>>В COM используется состояние для сравнения ссылок. Ты тоже споришь с фактами. G>Какое состояние?
QueryInterface не из воздуха достает результат, она обращается к состоянию.
G>Ты создай ЛЮБОЙ COM-объет. Получи две ссылки на разные интерфейсы от него. Потом для обоих вызови QueryInterface(IUnknown) и ты получишь одинаковые значения. Где тут состояние?
При вызове QueryInterface используется состояние объекта за ссылкой, используется поведение QueryInterface.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>Да, и в таком случае определить функцию дирихле будет тривиально, так как само число при этом будет знать рациональное оно или нет. S>Ты вынес задачу из тела функции. Но не значит что решил эту задачу.
Ты же просил записать функцию дирихле на C# я записал. В чем вопрос?
S>>>Формально COM соответствует OOP но лишь со своим требованием к реализации объектов, которое требует same physical pointer value у реализаций IUnknown. COM identity ослабляет identity, основанное на memory location. Если это требование не выполнить, то получится каша а не OOP. G>>Если это требование не выполнить, то получится не COM. То есть COM — ООП. S>С оговоркой. Ибо в определении идентичности ООП никаких QueryInterface и IUnknown нет.
Считай что функция ID для COM выглядит как QueryIntrerface(IUnknown). Сравнение в дальнейшем работает со ссылками.
В принципе ничто не мешает при работе с COM всегда держать ссылку на IUnknown и выполнять запрос нужного интерфейса при вызове метода. Тогда идентичность сведется к простому сравнению ссылок.
Поэтому все случаи приводимости к сравнению ссылок можно считать эквивалентными.
S>>>Если не эквивалентен другим, тогда понятно. Но это неверно. Идентичность определяет где один объект, а где другой. G>>Математически это выглядит как id(a)=id(b), когда a и b — один и тот же объект, id(a)!=id(b), когда a и b — разные объекты. Я уже это формально доказывал. Соответственно нам заранее необходимо знание о разных объектах, иначе любое отношение эквивалентности можно назвать идентичностью. S>Знание о разных объектах дает идентичность по определению. Она и только она определяет где идентичные объекты, а где нет.
Нет, объекты могут быть разные, даже если ты как сторонний наблюдатель не можешь их различить. Пример — строки в БД, совпадающие по значения колонок.
Требование ООП — умения стороннему наблюдателю различать разные объекты.
Метафора из жизни: близнецы — ты как сторонний наблюдатель не можешь отличить одного от другого, но это разные люди.
S>Ладно. Зайдем с другой стороны. Я могу предложить функцию f, которая приняв две различные строки с равным содержимым вернет "инвариантную" ссылку. Значит ли это что две различные строки с разным содержимым стали одним объектом?
Нет, ты опять пытаешься искать приводимость к ссылкам до того как придумал идентичность, отличающуюся от сравнения ссылок.
Кроме того функция f, как и сама идентичность должна не опираться на состояние и поведение (конкретные типы). Что у тебя явно нарушается.
Ты вообще сам не заметил, что постоянно пытаешься "расширить" эквивалентность до идентичности, только все время приплетая состояние и\или поведение.
S>>>>>Вот как раз ECMA-335 8.2.5.1 пункт 2 задает идентичность для value types с нарушением двух пунктов. Значение эквивалентно самому себе и всем другим с подобными bit sequences. И состояние может нарушить эту идентичность. G>>>>Но value-types — не ооп. Там свойство идентичности, которое говорит о том что для идентичных объектов любое изменение в одном отражается на другом, не выполняется. S>>>А если запретить изменения в value типе? Не во всех, а в конкретном? Он станет OOP? G>>Нет, идентичность не может быть определена "для конкретного типа", потому что "конкретный тип" это поведение от которого идентичность не должна зависеть. S>Идентичность не должна изменяться с изменением состояния и поведения.
Это уже твои домыслы. В определении написано "независимо", то есть вообще никак.
S>>>Вот тебе задачка про COM, который ООП. Есть у тебя два сырых различных указателя IUnknown*, определи, указывают ли они на один COM объект, не используя состояние и поведение Что бы не было недопонимания, эти указатели могут указывать не на IUnknown грань, а на IDispatch, например. G>>QueryInterface(IUnknown) даст равные ссылки, независимо от типа\объекта и его состояния, это требование спецификации COM. Если объект не следует спецификации, то это не COM и соответственно — не ООП. S>У тебя два указателя, указывающих на разные места в памяти. Ты еще не знаешь что это COM. Это разные объекты?
А что такое объект тогда? Мы работаем в конкретной системе, будь то CLR, или COM, или что что ты сам выдумаешь. И мы заранее знаем что у нас есть "объект" в это системе. И мы заранее имеем некоторый объект, для которого хотим получить id.
Остальное — демагогия.
Ты сначала определи систему, потом идентичность в ней.
G>>>>>>Ну я тебе говорю, предложи другую систему, где identity будет не ссылкой и не будет существовать отображения f которая сделает ссылки равными для объектов с совпадающим identity.
S>>>>>А я тебе говорю, что S>>>>>1) identity это не ссылка даже по ECMA-335. По ECMA identity это бинарное отношение. G>>>>Бинарное отношение в каком множестве? Видимо "ссылок". S>>>
S>>>8.2.5 Identity and equality of values
S>>>There are two binary operators defined on all pairs of values: identity and equality.
G>>Мы только про reference-типы говорим, потому что value-типы — не ООП. S>ладно, пусть value не ООП. Но именно определение ECMA указывает, что считать одним объектом а что другим для референсов. С этим будешь спорить?
Нет. Читай его внимательно. Там не написано что такое разные объекты, там написано про идентичность и эквивалентность.
Вообще бывают разные объекты, даже если ты их не умеешь различать (то есть у них нет identity).
S>Что бы получить результат QueryInterface(IUnknown), нужно воспользоваться состоянием и поведением, притом полиморфным.
Каким состоянием? Каким поведением?
G>>Это и есть та самая независимость. А ты пока не можешь привести пример такой функции id, которая не будет опираться на поведение и\или состояние и при изменении одного и\или другого перестанет работать. S>Да уж, независимость S>могу S>
S>class A {}
S>bool MyIdEquals(a, b)
S>{
S> if (ReferenceEquals(a, b))
S> return true;
S> if (a.GetType() == typeof(A) && b.GetType() == typeof(A))
S> return true;
S> return false;
S>}
S>
Типы — поведение (или состояние, если рассматривать как ссылку на VMT). в COM QueryInterface имеет одни и те же правила работы, независимо то типа.
S>>>Не пойму, откуда взялась такая функция и почему она будет говорить что идентичность не появится? G>>Потому что ты над обычной ссылкой на объект можешь настраивать сколько угодной уровней косвенности, но в этом просто нет смысла. В com эта мера вынужденная. S>Согласно этой логике две разные строки есть один объект. Но это противоречит identity ECMA. Выбирай, ECMA или f.
В ECMA это не нужно, там уже можно ссылки сравнивать. Хотя твои размышления натолкнули на мысль что f таки должна быть обратима. Надо более точно сформулировать.
S>>>>>Забудь про отображение f. Ничего оно никому не дает. G>>>>В COM дает, ты споришь с фактами. S>>>В COM используется состояние для сравнения ссылок. Ты тоже споришь с фактами. G>>Какое состояние? S>QueryInterface не из воздуха достает результат, она обращается к состоянию.
Не обращается. QueryInterface — детерминированная функция.
G>>Ты создай ЛЮБОЙ COM-объет. Получи две ссылки на разные интерфейсы от него. Потом для обоих вызови QueryInterface(IUnknown) и ты получишь одинаковые значения. Где тут состояние? S>При вызове QueryInterface используется состояние объекта за ссылкой, используется поведение QueryInterface.
Еще раз: такое поведение у любого объекта. Это особенность самого COM. как сравнение ссылок в CLR.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Речи не было о том что бы взять совершенно другую идентичность. Я хотел взять немного другую идентичность, которая для некоторых хороших типов, была бы слабже чем штатная. Для всех остальных — ReferenceEquals. Соответственно, для любого наперед неизвестного типа это было бы сравнение ссылок. Для хороших типов типа строк — сравнение значений. G>>"Для некоторых хороших типов" — зависит от поведения. S>Как и у QueryInterface
Нет, в СOM у любого объекта так работает QueryInterface, более того это детерминированная функция.
S>>>Собственно вот я все и выложил. Осталось ввернуть пару строк псевдокода: S>>>
S>>>bool MyIdentityEquals(object a, object b)
S>>>{
S>>> if (ReferenceEquals(a,b))
S>>> return true; // ослабить а не изменить в корне
S>>> if (a == null || b == null)
S>>> return false; // не знаю что определено в штатном порядке, пусть будет так.
S>>> var type = a.GetType();
S>>> if (type != b.GetType())
S>>> return false;
S>>> if (type == typeof(string) && StringComparer.Ordinal.Equals((string)a, (string)b))
S>>> return true;
S>>> // тут обработка хороших типов.
S>>> if (IsImmutable(type) && IsStructuralEquals(a, b))
S>>> return true;
S>>> return false;
S>>>}
S>>>
G>>1)Ты явно используешь поведение, когда сравниваешь строки. S>Не беда
Но это противоречит определению.
G>>2)Ты явно используешь состояние при сравнении. reflection испортит тебе идентичность S>Рефлекшн к черту
Счегобы?
G>>3)Есть подозрение что immutable выходит за рамки ООП S>У меня нет. G>>И кстати, как ты IsStructuralEquals определишь? S>Как-нибудь, в этом нет магии.
Дьявол в деталях.
G>>
G>>[Immutable]
G>>class A
G>>{
G>> public B B { get; }
G>>}
G>>class B //не-immutable
G>>{
G>> public int Prop {get; set;}
G>>}
G>>var a = new A { B = new B { Prop = 1 } };
G>>var b = new A { B = new B { Prop = 1 } };
G>>Debug.Assert(MyIdentityEquals(a,b)); //Упадет?
G>>b.B.Prop = 1;
G>>Debug.Assert(MyIdentityEquals(a,b)); //А тут?
G>>
S>Функция не настолько тупа что бы верить атрибуту [Immutable]. Возможно она шуршит по IL коду.
Неважно, скажи как отработает в данном коде.
S>>>Если это подсунуть вместо штатной ReferenceEquals и забыть про Reflection, который не ООП, то мы останемся в рамках ООП и даже возможно обеспечим некоторую совместимость с ReferenceEquals. G>>А почему reflection не ООП? Например в самом ООП языке — smalltalk есть рефлексия. И свовйство что изменения в одном объекте сразу отражаются на другом, если объекты идентичны, тоже не говорит какие изменения. Значит в том числе refection. S>Я уже писал, что рефлексия в дотнете ломает инкапсуляцию данных.
И что? ООП — объекты с identity и передача сообщений. Пусть ломает, она при этом никак ООП не противоречит.
G>>А вот кстати использование только immutable объектов в программе скорее всего выходит за рамки ООП. S>Тогда, скорее всего, любая программа, использующая иммутабельную строку, выходит за рамки ООП
нет, иммутабельная строка не заставляет быть иммутабельными все объекты, а твоя функция IsStructuralEquals будет работать только есть объекты состоят из иммутабельных объектов. Это будет не ООП.
S>>>Только не говори, что QueryInterface не использует состояние G>>Ты удивишься, но не использует. Это также явно в спецификации прописано. QueryInterface для объекта должна быть детерминированной функцией, то есть зависеть только от параметров. S>Не поверишь, функция, сравнивающая две строки, тоже может быть детерминированной, т.е. зависеть только от параметров. По твоей же логике детерминированная функция не использует состояние. Значит сравнивать строки можно не используя состояние.
Да пусть сравнивает, причем тут идентичность?
Ты пойми что требование QueryInterface возвращать одну и ту же ссылку не зависит от того какой класс реализует.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Да, и в таком случае определить функцию дирихле будет тривиально, так как само число при этом будет знать рациональное оно или нет. S>>Ты вынес задачу из тела функции. Но не значит что решил эту задачу. G>Ты же просил записать функцию дирихле на C# я записал. В чем вопрос?
Ты просил функцию MyIdEquals, я записал.
S>>>>Формально COM соответствует OOP но лишь со своим требованием к реализации объектов, которое требует same physical pointer value у реализаций IUnknown. COM identity ослабляет identity, основанное на memory location. Если это требование не выполнить, то получится каша а не OOP. G>>>Если это требование не выполнить, то получится не COM. То есть COM — ООП. S>>С оговоркой. Ибо в определении идентичности ООП никаких QueryInterface и IUnknown нет. G>Считай что функция ID для COM выглядит как QueryIntrerface(IUnknown). Сравнение в дальнейшем работает со ссылками.
Считай что функция сравнения для строк выглядит GetInvariantString
G>В принципе ничто не мешает при работе с COM всегда держать ссылку на IUnknown и выполнять запрос нужного интерфейса при вызове метода. Тогда идентичность сведется к простому сравнению ссылок.
Ничего не мешает для строк держать ссылку на интернированную строку
G>Поэтому все случаи приводимости к сравнению ссылок можно считать эквивалентными.
Это делает разные строки идентичными по ECMA?
S>>>>Если не эквивалентен другим, тогда понятно. Но это неверно. Идентичность определяет где один объект, а где другой. G>>>Математически это выглядит как id(a)=id(b), когда a и b — один и тот же объект, id(a)!=id(b), когда a и b — разные объекты. Я уже это формально доказывал. Соответственно нам заранее необходимо знание о разных объектах, иначе любое отношение эквивалентности можно назвать идентичностью. S>>Знание о разных объектах дает идентичность по определению. Она и только она определяет где идентичные объекты, а где нет. G>Нет, объекты могут быть разные, даже если ты как сторонний наблюдатель не можешь их различить. Пример — строки в БД, совпадающие по значения колонок. G>Требование ООП — умения стороннему наблюдателю различать разные объекты.
Идентичность говорит где разные объекты, а где нет. Она так говорит в ECMA, хочешь ты того или нет. Она так говорит для COM.
G>Метафора из жизни: близнецы — ты как сторонний наблюдатель не можешь отличить одного от другого, но это разные люди.
Метафора ничего не доказывает в отношении идентичности. И COM твою метафору опровергает. Ты видишь двух разных людей IUnknown*, а они — одно целое.
S>>Ладно. Зайдем с другой стороны. Я могу предложить функцию f, которая приняв две различные строки с равным содержимым вернет "инвариантную" ссылку. Значит ли это что две различные строки с разным содержимым стали одним объектом? G>Нет, ты опять пытаешься искать приводимость к ссылкам до того как придумал идентичность, отличающуюся от сравнения ссылок. G>Кроме того функция f, как и сама идентичность должна не опираться на состояние и поведение (конкретные типы). Что у тебя явно нарушается.
реализация QueryInterface типонезависима?
G>Ты вообще сам не заметил, что постоянно пытаешься "расширить" эквивалентность до идентичности, только все время приплетая состояние и\или поведение.
Как в COM
S>>Идентичность не должна изменяться с изменением состояния и поведения. G>Это уже твои домыслы. В определении написано "независимо", то есть вообще никак.
Но в COM приходится обращаться к полиморфным функциям и ты это считаешь независимым
S>>>>Вот тебе задачка про COM, который ООП. Есть у тебя два сырых различных указателя IUnknown*, определи, указывают ли они на один COM объект, не используя состояние и поведение Что бы не было недопонимания, эти указатели могут указывать не на IUnknown грань, а на IDispatch, например. G>>>QueryInterface(IUnknown) даст равные ссылки, независимо от типа\объекта и его состояния, это требование спецификации COM. Если объект не следует спецификации, то это не COM и соответственно — не ООП. S>>У тебя два указателя, указывающих на разные места в памяти. Ты еще не знаешь что это COM. Это разные объекты? G>А что такое объект тогда? Мы работаем в конкретной системе, будь то CLR, или COM, или что что ты сам выдумаешь. И мы заранее знаем что у нас есть "объект" в это системе. И мы заранее имеем некоторый объект, для которого хотим получить id.
Ну вот, заранее кто тебе сказал что такое есть "объект" и в каком месте он отличается от других? G>Остальное — демагогия. G>Ты сначала определи систему, потом идентичность в ней.
Берем C++ и два указателя на IUnknown*. Они указывают на один объект?
G>>>Мы только про reference-типы говорим, потому что value-типы — не ООП. S>>ладно, пусть value не ООП. Но именно определение ECMA указывает, что считать одним объектом а что другим для референсов. С этим будешь спорить? G>Нет. Читай его внимательно. Там не написано что такое разные объекты, там написано про идентичность и эквивалентность.
Там написано про идентичность значений, в частности какие считать идентичными, а какие нет. Про эквивалентность не там. G>Вообще бывают разные объекты, даже если ты их не умеешь различать (то есть у них нет identity).
Слушай, если уж value-типы с identity ты назвал не ООП, то объекты без identity-то, уж наверняка не ООП? Или как?
S>>Что бы получить результат QueryInterface(IUnknown), нужно воспользоваться состоянием и поведением, притом полиморфным. G>Каким состоянием? Каким поведением?
QI это полиморфная функция. взять результат она может только обращаясь к состоянию. Обеспечить детерминированность она может только обращаясь к состоянию. Или ты знаешь другие варианты?
G>>>Это и есть та самая независимость. А ты пока не можешь привести пример такой функции id, которая не будет опираться на поведение и\или состояние и при изменении одного и\или другого перестанет работать. S>>Да уж, независимость S>>могу S>>
S>>class A {}
S>>bool MyIdEquals(a, b)
S>>{
S>> if (ReferenceEquals(a, b))
S>> return true;
S>> if (a.GetType() == typeof(A) && b.GetType() == typeof(A))
S>> return true;
S>> return false;
S>>}
S>>
G>Типы — поведение (или состояние, если рассматривать как ссылку на VMT). в COM QueryInterface имеет одни и те же правила работы, независимо то типа.
И что? Разве это где-то упомянуто в определении идентити, а я не заметил?
S>>>>Не пойму, откуда взялась такая функция и почему она будет говорить что идентичность не появится? G>>>Потому что ты над обычной ссылкой на объект можешь настраивать сколько угодной уровней косвенности, но в этом просто нет смысла. В com эта мера вынужденная. S>>Согласно этой логике две разные строки есть один объект. Но это противоречит identity ECMA. Выбирай, ECMA или f. G>В ECMA это не нужно, там уже можно ссылки сравнивать. Хотя твои размышления натолкнули на мысль что f таки должна быть обратима. Надо более точно сформулировать.
Про обратимость f я тебе уже свои размышления показывал. Они привели к противоречию существования такой обратимой f.
S>>>>>>Забудь про отображение f. Ничего оно никому не дает. G>>>>>В COM дает, ты споришь с фактами. S>>>>В COM используется состояние для сравнения ссылок. Ты тоже споришь с фактами. G>>>Какое состояние? S>>QueryInterface не из воздуха достает результат, она обращается к состоянию. G>Не обращается. QueryInterface — детерминированная функция.
StringComparer.Ordinal.Equals тоже детерминированная функция. Не пойму, куда ты клонишь? Детермизированная функция — не значит что не обращается к состоянию. Я могу написать детерминированную функцию, которая мало что обращается, так и изменяет его:
public int callCount;
public int Add(int x, int y)
{
callCount++;
return x + y;
}
G>>>Ты создай ЛЮБОЙ COM-объет. Получи две ссылки на разные интерфейсы от него. Потом для обоих вызови QueryInterface(IUnknown) и ты получишь одинаковые значения. Где тут состояние? S>>При вызове QueryInterface используется состояние объекта за ссылкой, используется поведение QueryInterface. G>Еще раз: такое поведение у любого объекта. Это особенность самого COM. как сравнение ссылок в CLR.
Ну и что? MyIdEquals определяет identity для любого объекта. Это особенность MyIdEquals.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>>>Речи не было о том что бы взять совершенно другую идентичность. Я хотел взять немного другую идентичность, которая для некоторых хороших типов, была бы слабже чем штатная. Для всех остальных — ReferenceEquals. Соответственно, для любого наперед неизвестного типа это было бы сравнение ссылок. Для хороших типов типа строк — сравнение значений. G>>>"Для некоторых хороших типов" — зависит от поведения. S>>Как и у QueryInterface G>Нет, в СOM у любого объекта так работает QueryInterface, более того это детерминированная функция.
Уже отвечал. Детерминированность не означает не обращения к состоянию и поведению.
S>>>>Собственно вот я все и выложил. Осталось ввернуть пару строк псевдокода: S>>>>
S>>>>bool MyIdentityEquals(object a, object b)
S>>>>{
S>>>> if (ReferenceEquals(a,b))
S>>>> return true; // ослабить а не изменить в корне
S>>>> if (a == null || b == null)
S>>>> return false; // не знаю что определено в штатном порядке, пусть будет так.
S>>>> var type = a.GetType();
S>>>> if (type != b.GetType())
S>>>> return false;
S>>>> if (type == typeof(string) && StringComparer.Ordinal.Equals((string)a, (string)b))
S>>>> return true;
S>>>> // тут обработка хороших типов.
S>>>> if (IsImmutable(type) && IsStructuralEquals(a, b))
S>>>> return true;
S>>>> return false;
S>>>>}
S>>>>
G>>>1)Ты явно используешь поведение, когда сравниваешь строки. S>>Не беда G>Но это противоречит определению.
QueryInterface тоже
G>>>2)Ты явно используешь состояние при сравнении. reflection испортит тебе идентичность S>>Рефлекшн к черту G>Счегобы?
Я утверждаю что это не ООП инструмент.
G>>>3)Есть подозрение что immutable выходит за рамки ООП S>>У меня нет. G>>>И кстати, как ты IsStructuralEquals определишь? S>>Как-нибудь, в этом нет магии. G>Дьявол в деталях.
Я думаю что это неважно. Пусть хоть рефлексией по полям или через memcmp.
G>>>
G>>>[Immutable]
G>>>class A
G>>>{
G>>> public B B { get; }
G>>>}
G>>>class B //не-immutable
G>>>{
G>>> public int Prop {get; set;}
G>>>}
G>>>var a = new A { B = new B { Prop = 1 } };
G>>>var b = new A { B = new B { Prop = 1 } };
G>>>Debug.Assert(MyIdentityEquals(a,b)); //Упадет?
G>>>b.B.Prop = 1;
G>>>Debug.Assert(MyIdentityEquals(a,b)); //А тут?
G>>>
S>>Функция не настолько тупа что бы верить атрибуту [Immutable]. Возможно она шуршит по IL коду. G>Неважно, скажи как отработает в данном коде.
В идеале она посчитает что объекты мутабельны и вернет false.
S>>>>Если это подсунуть вместо штатной ReferenceEquals и забыть про Reflection, который не ООП, то мы останемся в рамках ООП и даже возможно обеспечим некоторую совместимость с ReferenceEquals. G>>>А почему reflection не ООП? Например в самом ООП языке — smalltalk есть рефлексия. И свовйство что изменения в одном объекте сразу отражаются на другом, если объекты идентичны, тоже не говорит какие изменения. Значит в том числе refection. S>>Я уже писал, что рефлексия в дотнете ломает инкапсуляцию данных. G>И что? ООП — объекты с identity и передача сообщений. Пусть ломает, она при этом никак ООП не противоречит.
Хм, слушай, я возьму в руки рефлексию и окажется что твои объекты вообще сообщений не получали, и даже не тех типов, что ты о них думал когда создавал. Или окажется что один из объектов лежит внутри памяти другого объекта и чутко реагирует на сообщения внешнего. Вот будет веселуха, а не ООП
G>>>А вот кстати использование только immutable объектов в программе скорее всего выходит за рамки ООП. S>>Тогда, скорее всего, любая программа, использующая иммутабельную строку, выходит за рамки ООП G>нет, иммутабельная строка не заставляет быть иммутабельными все объекты, а твоя функция IsStructuralEquals будет работать только есть объекты состоят из иммутабельных объектов. Это будет не ООП.
На каком основании? Где написано что иммутабельный объект не объект?
S>>>>Только не говори, что QueryInterface не использует состояние G>>>Ты удивишься, но не использует. Это также явно в спецификации прописано. QueryInterface для объекта должна быть детерминированной функцией, то есть зависеть только от параметров. S>>Не поверишь, функция, сравнивающая две строки, тоже может быть детерминированной, т.е. зависеть только от параметров. По твоей же логике детерминированная функция не использует состояние. Значит сравнивать строки можно не используя состояние. G>Да пусть сравнивает, причем тут идентичность? G>Ты пойми что требование QueryInterface возвращать одну и ту же ссылку не зависит от того какой класс реализует.
Причем тут это? QI использует состояние. Это был твой аргумент против сравнения объектов. Оказалось что QI использовать состояние можно, а при сравнении строк — нельзя.
Здравствуйте, samius, Вы писали:
S>Ты просил функцию MyIdEquals, я записал.
Она не является она не выполняет сравнение identity ни в одной известной мне ООП системе.
G>>Считай что функция ID для COM выглядит как QueryIntrerface(IUnknown). Сравнение в дальнейшем работает со ссылками. S>Считай что функция сравнения для строк выглядит GetInvariantString
Ты определяешь функцию только для строки (опираешься на поведение), а QueryIntrerface(IUnknown) работает для любого COM-объекта.
G>>В принципе ничто не мешает при работе с COM всегда держать ссылку на IUnknown и выполнять запрос нужного интерфейса при вызове метода. Тогда идентичность сведется к простому сравнению ссылок. S>Ничего не мешает для строк держать ссылку на интернированную строку
да, и тогда сравнение строк всегда можно заменить сравнением ссылок. Но так не делают по соображениям быстродействия.
G>>Поэтому все случаи приводимости к сравнению ссылок можно считать эквивалентными. S>Это делает разные строки идентичными по ECMA?
Нет. Потому что идентичность в ECMA уже определена по-другому. Хотя если на уровне реализации сделать интернирование каждой строки, то таки да, любые эквивалентные строки будут идентичными.
G>>Требование ООП — умения стороннему наблюдателю различать разные объекты. S>Идентичность говорит где разные объекты, а где нет.
Она позволяет стороннему наблюдателю различить разные объекты. Но не является критерием разных объектов.
То есть чтобы объекты были разными достаточно разных identity, но это не является необходимым условием.
G>>Метафора из жизни: близнецы — ты как сторонний наблюдатель не можешь отличить одного от другого, но это разные люди. S>Метафора ничего не доказывает в отношении идентичности. И COM твою метафору опровергает. Ты видишь двух разных людей IUnknown*, а они — одно целое.
Наоборот, если ты видишь два объекта у которых QueryIntrerface(IUnknown) совпадают, то это один объект, не совпадают — разные. COM как раз подтверждает.
Ты видишь двух людей (не одновременно), спрашиваешь у них СНИЛС\SSN — не совпадают, значит люди разные, а совпадают — это один человек.
S>>>Ладно. Зайдем с другой стороны. Я могу предложить функцию f, которая приняв две различные строки с равным содержимым вернет "инвариантную" ссылку. Значит ли это что две различные строки с разным содержимым стали одним объектом? G>>Нет, ты опять пытаешься искать приводимость к ссылкам до того как придумал идентичность, отличающуюся от сравнения ссылок. G>>Кроме того функция f, как и сама идентичность должна не опираться на состояние и поведение (конкретные типы). Что у тебя явно нарушается. S>реализация QueryInterface типонезависима?
Это зависит от самого компонента, но поведение, то есть то что ты можешь видеть снаружи — да, не зависит от типа.
G>>Ты вообще сам не заметил, что постоянно пытаешься "расширить" эквивалентность до идентичности, только все время приплетая состояние и\или поведение. S>Как в COM
Нет, там таких проблем нет.
Return a pointer within this object instance that implements the indicated interface. Answer NULL if the receiver does not contain an implementation of the interface.
It is required that any query for the specific interface IUnknown always returns the same
actual pointer value, no matter through which interface derived from IUnknown it is called.
This enables the following identity test algorithm to determine whether two pointers in
fact point to the same object: call QueryInterface(IID_IUnknown, ...) on both and compare the results.
... This requirement isthe basis for what is called COM identity.
Явно черным по английскому сказано что это и есть identity.
S>>>Идентичность не должна изменяться с изменением состояния и поведения. G>>Это уже твои домыслы. В определении написано "независимо", то есть вообще никак. S>Но в COM приходится обращаться к полиморфным функциям и ты это считаешь независимым
Наблюдаемое поведение не зависит от конкретного типа.
S>Берем C++ и два указателя на IUnknown*. Они указывают на один объект?
Если не совпадают, то нет.
G>>>>Мы только про reference-типы говорим, потому что value-типы — не ООП. S>>>ладно, пусть value не ООП. Но именно определение ECMA указывает, что считать одним объектом а что другим для референсов. С этим будешь спорить? G>>Нет. Читай его внимательно. Там не написано что такое разные объекты, там написано про идентичность и эквивалентность. S>Там написано про идентичность значений, в частности какие считать идентичными, а какие нет. Про эквивалентность не там. G>>Вообще бывают разные объекты, даже если ты их не умеешь различать (то есть у них нет identity). S>Слушай, если уж value-типы с identity ты назвал не ООП, то объекты без identity-то, уж наверняка не ООП? Или как?
Да, требование ООП чтобы у разных объектов были разные identity. Про разные объекты см выше.
S>>>Что бы получить результат QueryInterface(IUnknown), нужно воспользоваться состоянием и поведением, притом полиморфным. G>>Каким состоянием? Каким поведением? S>QI это полиморфная функция. взять результат она может только обращаясь к состоянию. Обеспечить детерминированность она может только обращаясь к состоянию. Или ты знаешь другие варианты?
Реализация не важна (ты же по сути не знаешь что внутри делает object.ReferenceEquals), важно наблюдаемое снаружи поведение, так во оно в случае QueryInterface(IUnknown) совпадает у всех COM объектов.
G>>>>Это и есть та самая независимость. А ты пока не можешь привести пример такой функции id, которая не будет опираться на поведение и\или состояние и при изменении одного и\или другого перестанет работать. S>>>Да уж, независимость S>>>могу S>>>
S>>>class A {}
S>>>bool MyIdEquals(a, b)
S>>>{
S>>> if (ReferenceEquals(a, b))
S>>> return true;
S>>> if (a.GetType() == typeof(A) && b.GetType() == typeof(A))
S>>> return true;
S>>> return false;
S>>>}
S>>>
G>>Типы — поведение (или состояние, если рассматривать как ссылку на VMT). в COM QueryInterface имеет одни и те же правила работы, независимо то типа. S>И что? Разве это где-то упомянуто в определении идентити, а я не заметил?
Типы — поведение (или состояние, если рассматривать как ссылку на VMT\type), ты именно их используешь в своем коде/
S>>>>>Не пойму, откуда взялась такая функция и почему она будет говорить что идентичность не появится? G>>>>Потому что ты над обычной ссылкой на объект можешь настраивать сколько угодной уровней косвенности, но в этом просто нет смысла. В com эта мера вынужденная. S>>>Согласно этой логике две разные строки есть один объект. Но это противоречит identity ECMA. Выбирай, ECMA или f. G>>В ECMA это не нужно, там уже можно ссылки сравнивать. Хотя твои размышления натолкнули на мысль что f таки должна быть обратима. Надо более точно сформулировать. S>Про обратимость f я тебе уже свои размышления показывал. Они привели к противоречию существования такой обратимой f.
Я еще не сформулировал в каком смысле нужна обратимость.
G>>>>Ты создай ЛЮБОЙ COM-объет. Получи две ссылки на разные интерфейсы от него. Потом для обоих вызови QueryInterface(IUnknown) и ты получишь одинаковые значения. Где тут состояние? S>>>При вызове QueryInterface используется состояние объекта за ссылкой, используется поведение QueryInterface. G>>Еще раз: такое поведение у любого объекта. Это особенность самого COM. как сравнение ссылок в CLR. S>Ну и что? MyIdEquals определяет identity для любого объекта. Это особенность MyIdEquals.
Нет, внутрь MyIdEquals заложено знание о конкретных классах, в отличие от QueryInterface.
Здравствуйте, samius, Вы писали:
G>>>>1)Ты явно используешь поведение, когда сравниваешь строки. S>>>Не беда G>>Но это противоречит определению. S>QueryInterface тоже
Не-а. http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf
Пункт 3.3.1.1
G>>>>2)Ты явно используешь состояние при сравнении. reflection испортит тебе идентичность S>>>Рефлекшн к черту G>>Счегобы? S>Я утверждаю что это не ООП инструмент.
Утверждай дальше, но это не так. Reflecton нигде не противоречит OOP.
Даже Алан Кей, создатель ООП и языка SmallTalk включил туда reflection.
Можешь найти хоть одно авторитетное мнение, совпадающее с твоим?
G>>>>
G>>>>[Immutable]
G>>>>class A
G>>>>{
G>>>> public B B { get; }
G>>>>}
G>>>>class B //не-immutable
G>>>>{
G>>>> public int Prop {get; set;}
G>>>>}
G>>>>var a = new A { B = new B { Prop = 1 } };
G>>>>var b = new A { B = new B { Prop = 1 } };
G>>>>Debug.Assert(MyIdentityEquals(a,b)); //Упадет?
G>>>>b.B.Prop = 1;
G>>>>Debug.Assert(MyIdentityEquals(a,b)); //А тут?
G>>>>
S>>>Функция не настолько тупа что бы верить атрибуту [Immutable]. Возможно она шуршит по IL коду. G>>Неважно, скажи как отработает в данном коде. S>В идеале она посчитает что объекты мутабельны и вернет false.
Отлично, то есть чтобы MyIdentityEquals возвращало true требуется "глубокая" immutability. Это будет не ооп.
G>>>>А вот кстати использование только immutable объектов в программе скорее всего выходит за рамки ООП. S>>>Тогда, скорее всего, любая программа, использующая иммутабельную строку, выходит за рамки ООП G>>нет, иммутабельная строка не заставляет быть иммутабельными все объекты, а твоя функция IsStructuralEquals будет работать только есть объекты состоят из иммутабельных объектов. Это будет не ООП. S>На каком основании? Где написано что иммутабельный объект не объект?
Нигде, но на глубокой иммутабельности у тебя не получится ООП.
S>Причем тут это? QI использует состояние.
Не использует.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>1)Ты явно используешь поведение, когда сравниваешь строки. S>>>>Не беда G>>>Но это противоречит определению. S>>QueryInterface тоже G>Не-а. G>http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf G>Пункт 3.3.1.1
Погоди, ты мне говорил что именно определение идентити ООП запрещает опираться на поведение и состояние. Спека COM официально одобрила использование поведения и состояния для вычисления ID. Это противоречит твоей трактовке идентити ООП.
Короче, или можно использовать состояние, тогда можно сравнивать строки в MyIdEquals. Или нельзя, тогда QI нарушает это правило. Твой выбор?
S>>Я утверждаю что это не ООП инструмент. G>Утверждай дальше, но это не так. Reflecton нигде не противоречит OOP. G>Даже Алан Кей, создатель ООП и языка SmallTalk включил туда reflection. G>Можешь найти хоть одно авторитетное мнение, совпадающее с твоим? http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html
Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP.
S>>>>Функция не настолько тупа что бы верить атрибуту [Immutable]. Возможно она шуршит по IL коду. G>>>Неважно, скажи как отработает в данном коде. S>>В идеале она посчитает что объекты мутабельны и вернет false. G>Отлично, то есть чтобы MyIdentityEquals возвращало true требуется "глубокая" immutability. Это будет не ооп.
В чем это будет не ООП? По каким признакам?
G>>>>>А вот кстати использование только immutable объектов в программе скорее всего выходит за рамки ООП. S>>>>Тогда, скорее всего, любая программа, использующая иммутабельную строку, выходит за рамки ООП G>>>нет, иммутабельная строка не заставляет быть иммутабельными все объекты, а твоя функция IsStructuralEquals будет работать только есть объекты состоят из иммутабельных объектов. Это будет не ООП. S>>На каком основании? Где написано что иммутабельный объект не объект? G>Нигде, но на глубокой иммутабельности у тебя не получится ООП.
Т.е. потому что ты так решил?
Что будет если у меня будут не только immutable объекты?
S>>Причем тут это? QI использует состояние. G>Не использует.
class MyIDispatchFace : public IDispatch
{
public:
IUnknown* QI(IID iid)
{
case IID_IUnknown:
...
}
};
Добавь плиз набросок реализации для случая когда грань IDispatch распологается отдельно от грани IUnknown. А я посмотрю, откуда ты материализуешь результат для QI.
Здравствуйте, samius, Вы писали:
G>>http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf G>>Пункт 3.3.1.1 S>Погоди, ты мне говорил что именно определение идентити ООП запрещает опираться на поведение и состояние. Спека COM официально одобрила использование поведения и состояния для вычисления ID. Это противоречит твоей трактовке идентити ООП.
Где ты там состояние увидел?
S>>>Я утверждаю что это не ООП инструмент. G>>Утверждай дальше, но это не так. Reflecton нигде не противоречит OOP. G>>Даже Алан Кей, создатель ООП и языка SmallTalk включил туда reflection. G>>Можешь найти хоть одно авторитетное мнение, совпадающее с твоим? S>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html S>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP.
Тем не менее она не противоречит ООП, также как immutable string не противоречит.
А вот если все будет immutable, тогда совсем друга система получится.
S>>>>>Функция не настолько тупа что бы верить атрибуту [Immutable]. Возможно она шуршит по IL коду. G>>>>Неважно, скажи как отработает в данном коде. S>>>В идеале она посчитает что объекты мутабельны и вернет false. G>>Отлично, то есть чтобы MyIdentityEquals возвращало true требуется "глубокая" immutability. Это будет не ооп. S>В чем это будет не ООП? По каким признакам?
По формальным может быть даже получится ООП. Но по сути превратится в ФП.
G>>>>>>А вот кстати использование только immutable объектов в программе скорее всего выходит за рамки ООП. S>>>>>Тогда, скорее всего, любая программа, использующая иммутабельную строку, выходит за рамки ООП G>>>>нет, иммутабельная строка не заставляет быть иммутабельными все объекты, а твоя функция IsStructuralEquals будет работать только есть объекты состоят из иммутабельных объектов. Это будет не ООП. S>>>На каком основании? Где написано что иммутабельный объект не объект? G>>Нигде, но на глубокой иммутабельности у тебя не получится ООП. S>Т.е. потому что ты так решил? S>Что будет если у меня будут не только immutable объекты?
Тогда у тебя MyEquals будет практически бесполезной функцией.
S>>>Причем тут это? QI использует состояние. G>>Не использует.
S>
S>Добавь плиз набросок реализации для случая когда грань IDispatch распологается отдельно от грани IUnknown. А я посмотрю, откуда ты материализуешь результат для QI.
Такого быть не может, IDispatch наследуется от IUnknown.
Так что с точки зрения C++ код всегда будет
class MyIDispatchFace : public IDispatch
{
public:
IUnknown* QI(IID iid)
{
case IID_IUnknown:
return this;
...
}
};
G>>>Фаулер опирается на заблуждение ANS>>Это не заблуждение, это примитивизация. G>Нет, это именно заблужение. До буча с мейером никто не говорил что объекты — данные+методы, обязательно вместе. Откуда это они взяли — неизвестно.
Это rule of thumb. Ситуация, когда состояние общее и шарится между разными категориями мутаторов может и имеет право на жизнь, но не в случае anemic.
G>Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния.
Здравствуйте, Sinclair, Вы писали:
ANS>>Извини, я до этого места статью был не дочитал Я остановился на втором абзаце. И сходу вопрос, почему "Transaction Script" это "чисто процедурное овно"? S>А ты нажми на ссылку "Transaction Script", которую он приводит.
Здравствуйте, gandjustas, Вы писали:
G>Яж говорю, фаулер устарел. Он до сих пор "продает" то что было актуально 10 лет назад, а сейчас уже стало нормальным и перекочевало из разряда новшеств в разряд инструментов.
"Устарел" != "в корне не прав". btw, когда выложили архивы "Smalltalk Report" — я был разочарован тем, что прогресс за более чем за 10 лет никуда не сдвинулся. Что за последние 5 лет что-то принципиально изменилось? Сомневаюсь.
Здесь нет иррациональных числел Sqrt это функция которая всегда возвращает рациональное число Более того, любая другая функция тоже вернет рациональное число. Более того, любое число, которое может быть представлено в конкретном компьютере, будет рациональным.
Необходимое и достаточное условие для представления иррациональных чисел это возможность представить бесконечнечную непериодическую дробь.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>Яж говорю, фаулер устарел. Он до сих пор "продает" то что было актуально 10 лет назад, а сейчас уже стало нормальным и перекочевало из разряда новшеств в разряд инструментов.
ANS>"Устарел" != "в корне не прав".
Неправ в том что продолжает популяризировать старые идеи. Большинство из которых потеряли актуальность.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, samius, Вы писали:
I>>>И давно C# научили работать с иррациональными числами ? S>>Как давно на C# запретили писать следующее: S>>
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf G>>>Пункт 3.3.1.1 S>>Погоди, ты мне говорил что именно определение идентити ООП запрещает опираться на поведение и состояние. Спека COM официально одобрила использование поведения и состояния для вычисления ID. Это противоречит твоей трактовке идентити ООП. G>Где ты там состояние увидел?
А как без состояния взять указатель на нужную реализацию IUnknown?
S>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html S>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP. G>Тем не менее она не противоречит ООП, также как immutable string не противоречит. G>А вот если все будет immutable, тогда совсем друга система получится.
Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП.
G>>>Отлично, то есть чтобы MyIdentityEquals возвращало true требуется "глубокая" immutability. Это будет не ооп. S>>В чем это будет не ООП? По каким признакам? G>По формальным может быть даже получится ООП. Но по сути превратится в ФП.
Вот выделенное имеет значение.
G>>>Нигде, но на глубокой иммутабельности у тебя не получится ООП. S>>Т.е. потому что ты так решил? S>>Что будет если у меня будут не только immutable объекты? G>Тогда у тебя MyEquals будет практически бесполезной функцией.
Весь этот флейм не имеет никакой практической пользы.
S>>>>Причем тут это? QI использует состояние. G>>>Не использует.
S>>
S>>Добавь плиз набросок реализации для случая когда грань IDispatch распологается отдельно от грани IUnknown. А я посмотрю, откуда ты материализуешь результат для QI. G>Такого быть не может, IDispatch наследуется от IUnknown.
Все интерфейсы COM наследуются от IUnknown
G>Так что с точки зрения C++ код всегда будет G>
Если бы это всегда было так, то COM-у не требовалось бы уточнять identity через QI(IID_IUnknown).
Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так".
Здравствуйте, gandjustas, Вы писали:
ANS>>"Устарел" != "в корне не прав". G>Неправ в том что продолжает популяризировать старые идеи. Большинство из которых потеряли актуальность.
Фаулер написал свою книгу давным давно, когда еще не было современных инструментов.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf G>>>>Пункт 3.3.1.1 S>>>Погоди, ты мне говорил что именно определение идентити ООП запрещает опираться на поведение и состояние. Спека COM официально одобрила использование поведения и состояния для вычисления ID. Это противоречит твоей трактовке идентити ООП. G>>Где ты там состояние увидел? S>А как без состояния взять указатель на нужную реализацию IUnknown?
Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку.
Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.
Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния.
S>>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html S>>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP. G>>Тем не менее она не противоречит ООП, также как immutable string не противоречит. G>>А вот если все будет immutable, тогда совсем друга система получится. S>Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП.
"Злом" и "не относящимся к ООП" не связаны между собой.
G>>>>Отлично, то есть чтобы MyIdentityEquals возвращало true требуется "глубокая" immutability. Это будет не ооп. S>>>В чем это будет не ООП? По каким признакам? G>>По формальным может быть даже получится ООП. Но по сути превратится в ФП. S>Вот выделенное имеет значение.
Тогда придем к разговору о том чем ФП не соотвествует ООП и наоборот.
S>>>>>Причем тут это? QI использует состояние. G>>>>Не использует.
S>>>
S>>>Добавь плиз набросок реализации для случая когда грань IDispatch распологается отдельно от грани IUnknown. А я посмотрю, откуда ты материализуешь результат для QI. G>>Такого быть не может, IDispatch наследуется от IUnknown. S>Все интерфейсы COM наследуются от IUnknown
Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown.
G>>Так что с точки зрения C++ код всегда будет G>>
S>Если бы это всегда было так, то COM-у не требовалось бы уточнять identity через QI(IID_IUnknown).
С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM.
S>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так".
Все так, если рассматривать C++.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
G>>>>Фаулер опирается на заблуждение ANS>>>Это не заблуждение, это примитивизация. G>>Нет, это именно заблужение. До буча с мейером никто не говорил что объекты — данные+методы, обязательно вместе. Откуда это они взяли — неизвестно.
ANS>Это rule of thumb. Ситуация, когда состояние общее и шарится между разными категориями мутаторов может и имеет право на жизнь, но не в случае anemic.
Ниче не понял.
G>>Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния. ANS>Если бы я хотел так придираться к словам, как ты, то сказал бы, что объект всегда имеет состояние
Придираться к словам иногда очень важно. Только так можно понять смысл некоторых фраз.
В данном случае методы без данных за объекты не считают по непонятной совершенно причине. При выдумывании ООП никто даже близко такого не говорил.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Где ты там состояние увидел? S>>А как без состояния взять указатель на нужную реализацию IUnknown? G>Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку. G>Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.
G>Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния.
Ты что-то в COM явно не догоняешь. Объекты в COM могут быть многогранными (не знаю, какой термин используется конкретно в COM, я взял термин у Элджера (Face)).
Вот ты создал объект через CreateInstance, получил IUnknown* pUnk. Что бы запросить у него IDispatch ты должен выполнить pUnk->QI(IID_IDispatch) и получить void* pDisp. В общем случае pUnk != pDisp. Но pDisp должен реализовывать методы интерфейса IDispatch, так же как и IUnknown, т.к. IDispatch расширяет IUnknown, как и все остальные интерфейсы COM.
Т.е. pDisp поддерживает вызов методов IUnknown, а значит его можно привести к IUnknown* и получить pUnk2
pUnk != pUnk2 в общем случае.
Что бы проверить идентичность, COM требует выполнить QI(IID_IUnknown) для обоих указателей.
Так вот, pUnk2 в общем случае может не указывать туда же куда и pUnk. Соответственно, this в реализации его QI будет несовпадать с pUnk. Но у тебя есть задача согласно спеке COM в pUnk2->QI(IID_IUnknown) вернуть значение, совпадающее с pUnk.
Именно это я и попросил тебя сделать в реализации того метода QI.
S>>>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html S>>>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP. G>>>Тем не менее она не противоречит ООП, также как immutable string не противоречит. G>>>А вот если все будет immutable, тогда совсем друга система получится. S>>Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП. G>"Злом" и "не относящимся к ООП" не связаны между собой.
Связаны. Иначе нафига в ООП инкапсуляция нужна?
G>>>По формальным может быть даже получится ООП. Но по сути превратится в ФП. S>>Вот выделенное имеет значение. G>Тогда придем к разговору о том чем ФП не соотвествует ООП и наоборот.
Надеюсь что не придем. Мы ведь обсуждаем формальные требования ООП.
S>>Все интерфейсы COM наследуются от IUnknown G>Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown.
Нет, не достаточно. Речь об объектах с различными гранями.
G>>>Так что с точки зрения C++ код всегда будет G>>>
S>>Если бы это всегда было так, то COM-у не требовалось бы уточнять identity через QI(IID_IUnknown). G>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM.
Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме.
S>>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так". G>Все так, если рассматривать C++.
Я описал случай когда return this не удовлетворит идентичности COM. Код я просил именно к этому случаю.
ANS>>Это rule of thumb. Ситуация, когда состояние общее и шарится между разными категориями мутаторов может и имеет право на жизнь, но не в случае anemic. G>Ниче не понял.
У тебя есть состояние (одна enity с которой работают разные наборы методов (сервисов). Это тот самый случай когда identity разные, а фактический объект один и тот же.
G>>>Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния. ANS>>Если бы я хотел так придираться к словам, как ты, то сказал бы, что объект всегда имеет состояние
G>Придираться к словам иногда очень важно. Только так можно понять смысл некоторых фраз. G>В данном случае методы без данных за объекты не считают по непонятной совершенно причине. При выдумывании ООП никто даже близко такого не говорил.
Ну, придирка не к тому, что есть методы без данных, а к тому, что одновременно есть и методы-без-данных, и данные-без-методов, и, ужас ужас, методы-без-данных манипулируют данными-без-методов.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, artelk, Вы писали:
A>>Здравствуйте, gandjustas, Вы писали:
G>>>Здравствуйте, artelk, Вы писали:
A>>>>Только сдается мне такому определению удовлетворит идентичность, реализованная на основе функции A>>>>
A>>>>и смысл полностью теряется, т.к. такую функцию можно реализовать вообще для чего угодно.
G>>>Нет.
G>>>
G>>>var a = new object();
G>>>var b = a;
G>>>var c = new object();
G>>>Debug.Assert(IsIdentical(a,b) != IsIdentical(a,c));
G>>>
G>>>Ассерт отвалится, с такой функцией мы не можем сказать являются ли разными два объекта или это один и тот же объект. То есть мы не можем отличить объект от других. A>>Ты пытаешься поднять себя за волосы, как Мюнхгаузен. Ты считаешь, что a в первой строке, во второй и последней ссылаются на один и тот же объект. Нет, в каждой точке программы мы имеем дело с новым объектом, согласно нашей реализации идентичности.
На замом деле, такая реализация идентичности не позволяет сослаться на объект, что противоречит определению.
G>Нет. в Ecma-335 ясно сказано что идентичные объекты те, у которых same location. a и b — same location.
А причем тут Ecma-335? Наверху описывался гипотетический язык, не C#.
Здравствуйте, Sinclair, Вы писали:
A>>artelk> Приведи пример задачи, которую нельзя решить без использования object.ReferenceEquals. A>>gandjustas> Хорошо, задача: нужно реализовать object.ReferenceEquals с текущим его поведением. A>>
A>>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы? S>Да сразу же, как начнём писать.
S>
S>public class Crash
S>{
S> public int A { get; set; }
S> public override bool Equals(object o) {??? };
S>}
S>var a = new Crash(); a.A = 1;
S>var b = new Crash(); b.A = 2;
S>var l = new List<A>();
S>l.Add(a); l.Add(b);
S>a.A = 2;
S>l.Remove(b);
S>a.A = 1;
S>Assert(l.IndexOf(a) >= 0);
S>
S>Приведите, пожалуйста, свою перегрузку метода Equals, не использующую сравнение ссылок. Задача — в том, чтобы ассерт выполнился.
Например, добавить в Crash "private readonly Guid id = Guid.NewGuid();", реализовать Equals через него.
В чем подвох? Решение перестанет быть ООП?
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, Sinclair, Вы писали:
A>>>artelk> Приведи пример задачи, которую нельзя решить без использования object.ReferenceEquals. A>>>gandjustas> Хорошо, задача: нужно реализовать object.ReferenceEquals с текущим его поведением. A>>>
A>>>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы? S>>Да сразу же, как начнём писать.
S>>
S>>public class Crash
S>>{
S>> public int A { get; set; }
S>> public override bool Equals(object o) {??? };
S>>}
S>>var a = new Crash(); a.A = 1;
S>>var b = new Crash(); b.A = 2;
S>>var l = new List<A>();
S>>l.Add(a); l.Add(b);
S>>a.A = 2;
S>>l.Remove(b);
S>>a.A = 1;
S>>Assert(l.IndexOf(a) >= 0);
S>>
S>>Приведите, пожалуйста, свою перегрузку метода Equals, не использующую сравнение ссылок. Задача — в том, чтобы ассерт выполнился. A>Например, добавить в Crash "private readonly Guid id = Guid.NewGuid();", реализовать Equals через него. A>В чем подвох? Решение перестанет быть ООП?
Сам себе отвечу. Да, equals так определять не комильфо — определить, что два разных объекта равны так не получится, согласен.
Очевидно, метод List<T>.Remove(T item) реализовать не получится. Можно реализовать разве что RemoveWhere(Func<T, bool> predicate), плюс у нас остается старый добрый RemoveAt(index).
Метод List<T>.Add(T item) остается как есть, т.к. уникальность по identity он не делает (в отличие от HashSet).
И как с ООП, мы его теряем при этом?
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>Где ты там состояние увидел? S>>>А как без состояния взять указатель на нужную реализацию IUnknown? G>>Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку. G>>Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.
G>>Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния. S>Ты что-то в COM явно не догоняешь. Объекты в COM могут быть многогранными (не знаю, какой термин используется конкретно в COM, я взял термин у Элджера (Face)). S>Вот ты создал объект через CreateInstance, получил IUnknown* pUnk. Что бы запросить у него IDispatch ты должен выполнить pUnk->QI(IID_IDispatch) и получить void* pDisp. В общем случае pUnk != pDisp. Но pDisp должен реализовывать методы интерфейса IDispatch, так же как и IUnknown, т.к. IDispatch расширяет IUnknown, как и все остальные интерфейсы COM.
И?
S>Т.е. pDisp поддерживает вызов методов IUnknown, а значит его можно привести к IUnknown* и получить pUnk2
А, понял. В COM нет приведения типов, вместо него QueryInterface. COM — бинарный стандарт, он проектировался так чтобы не быть привязанным к конкретному языку.
То что ты говоришь — плод интерференции C++ и COM. Только это не является COM.
S>pUnk != pUnk2 в общем случае.
Это будет не COM. Читай спецификацию.
S>>>>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html S>>>>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP. G>>>>Тем не менее она не противоречит ООП, также как immutable string не противоречит. G>>>>А вот если все будет immutable, тогда совсем друга система получится. S>>>Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП. G>>"Злом" и "не относящимся к ООП" не связаны между собой. S>Связаны. Иначе нафига в ООП инкапсуляция нужна?
Инкапсуляция поведения. Если рассматривать инкапсуляцию состояния, то она становится не нужна при immutable.
S>>>Все интерфейсы COM наследуются от IUnknown G>>Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown. S>Нет, не достаточно. Речь об объектах с различными гранями.
Это плод интерференции С++ и COM. оставаясь в COM приведение типов выполняется с помощью QueryInterface.
G>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM. S>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме.
Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет.
S>>>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так". G>>Все так, если рассматривать C++. S>Я описал случай когда return this не удовлетворит идентичности COM. Код я просил именно к этому случаю.
Ну ты ССЗБ. Сам придумал случай, сам делай так чтобы оно было COM.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, gandjustas, Вы писали:
ANS>>>Это rule of thumb. Ситуация, когда состояние общее и шарится между разными категориями мутаторов может и имеет право на жизнь, но не в случае anemic. G>>Ниче не понял.
ANS>У тебя есть состояние (одна enity с которой работают разные наборы методов (сервисов). Это тот самый случай когда identity разные, а фактический объект один и тот же.
Что значит "фактический объект"? Как ты понимаешь "Объект" в данном случае?
G>>>>Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния. ANS>>>Если бы я хотел так придираться к словам, как ты, то сказал бы, что объект всегда имеет состояние
G>>Придираться к словам иногда очень важно. Только так можно понять смысл некоторых фраз. G>>В данном случае методы без данных за объекты не считают по непонятной совершенно причине. При выдумывании ООП никто даже близко такого не говорил.
ANS>Ну, придирка не к тому, что есть методы без данных, а к тому, что одновременно есть и методы-без-данных, и данные-без-методов, и, ужас ужас, методы-без-данных манипулируют данными-без-методов.
А еще бывают случаи когда методы-без-данных вызывают другие методы-без-данных, которые вообще расположены на другой машине и передают им данные-без-методов, которые нормально при этом сериализуются\десериализуются и не вызывают ошибок. Причем такие случаи в современном ПО гораздо более распространены, чем данные-с-методами, которые оперируют только другими данными-с-методами.
Здравствуйте, artelk, Вы писали:
A>На замом деле, такая реализация идентичности не позволяет сослаться на объект, что противоречит определению.
Прочитай внимательно определение, там identity не говорит об операции "сослаться" (dereferencing). Эта операция доступна для "ссылки" (не адреса в памяти). Ссылка имеет некоторое числовое значение, даже если ссылки на один объект не будут совпадать, то есть некоторое инвариантное значение ссылки, которое будет совпадать для одного объекта.
Вот теперь вопрос, всегда ли на практике ссылка (инвариантная) может служить identity?
Ты утверждал что нет.
G>>Нет. в Ecma-335 ясно сказано что идентичные объекты те, у которых same location. a и b — same location. A>А причем тут Ecma-335? Наверху описывался гипотетический язык, не C#.
Так опиши эту гипотетическую систему, а потом функции в ней. Вот samius попытался, но у него немного не ООП получилось.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, artelk, Вы писали:
A>>Только сдается мне такому определению удовлетворит идентичность, реализованная на основе функции A>>
A>>и смысл полностью теряется, т.к. такую функцию можно реализовать вообще для чего угодно. S>Сначала нужно проверить результат IsIdentical(a, a).
А если у нас в языке нет возможности передать значения по ссылке? В IsIdentical придут две разные копии объекта.
Давай издалека:
struct A
{
public int X;
}
var a = new A();
a.X = 21;
a.X = a.X + a.X;
Debug.Assert(a.X == 42);
Я утверждаю, что именно идентичность, реализованная в языке, позволяет нам иметь гарантии, что в последних 3х строчках мы имеем дело с одним и тем же объектом.
Кроме того, идентичностью называется именно возможность иметь такие гарантии.
В языках со ссылочной прозрачностью идентичности не требуется.
let x = 21 * cos(0.0)
let y = x * 2 //y = 42
Инедтификаторы тут — просто alias-ы выражений (а не ссылки на созданные "объекты") и могут быть просто заинлайнены:
let y = (21 * cos(0.0)) + (21 * cos(0.0)) //y = 42
Идентичность нужна, прежде всего, для обеспечения возможности такой вещи как само состояние (а конкретно, изменяемое состояние), как понятия языка.
И именно поэтому идентичность не может быть функцией состояния — без него самого состояния быть не может.
Согласен ли ты с этим?
.
Ты всё сводишь к техническому моменту. Данные лежат в массиве? В массиве? Массив — это объект? Объект. Значит есть ОО. А потом приходят функциональщики и говорят "а зачем это всё?
".
Хотя ОО позволяет делать тот самый "рекурсивный" дизайн, когда объекты и в верху и в низу, ты оставляя объекты внизу системы отказываешься от них на верху.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>Где ты там состояние увидел? S>>>>А как без состояния взять указатель на нужную реализацию IUnknown? G>>>Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку. G>>>Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.
G>>>Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния. S>>Ты что-то в COM явно не догоняешь. Объекты в COM могут быть многогранными (не знаю, какой термин используется конкретно в COM, я взял термин у Элджера (Face)). S>>Вот ты создал объект через CreateInstance, получил IUnknown* pUnk. Что бы запросить у него IDispatch ты должен выполнить pUnk->QI(IID_IDispatch) и получить void* pDisp. В общем случае pUnk != pDisp. Но pDisp должен реализовывать методы интерфейса IDispatch, так же как и IUnknown, т.к. IDispatch расширяет IUnknown, как и все остальные интерфейсы COM. G>И?
S>>Т.е. pDisp поддерживает вызов методов IUnknown, а значит его можно привести к IUnknown* и получить pUnk2 G>А, понял. В COM нет приведения типов, вместо него QueryInterface. COM — бинарный стандарт, он проектировался так чтобы не быть привязанным к конкретному языку. G>То что ты говоришь — плод интерференции C++ и COM. Только это не является COM.
S>>pUnk != pUnk2 в общем случае. G>Это будет не COM. Читай спецификацию.
Читай ты. 2.1.4, 2.1.4.1, 2.1.4.2 того документа что ты давал ссылку.
Это основа COM. То что я назвал Face-ами у них называется интерфейсами. QI- это способ навигации множественными интерфейсами объекта. Он возвращает this лишь в тривиальных случаях. И C++ тут непричем.
S>>>>Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП. G>>>"Злом" и "не относящимся к ООП" не связаны между собой. S>>Связаны. Иначе нафига в ООП инкапсуляция нужна? G>Инкапсуляция поведения. Если рассматривать инкапсуляцию состояния, то она становится не нужна при immutable.
Проблема в том, что immutable становится лишь условностью, когда в руках программиста рефлекшн.
S>>>>Все интерфейсы COM наследуются от IUnknown G>>>Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown. S>>Нет, не достаточно. Речь об объектах с различными гранями. G>Это плод интерференции С++ и COM. оставаясь в COM приведение типов выполняется с помощью QueryInterface.
Не приведение типов, а навигация между интерфейсами. Нет никакого плода интерференции. То, о чем я говорю — это основа Object Reusability через aggregation (1.3.3.2, 2.4). И требования идентичности COM обеспечивают то что такие агрегаты с множеством интерфейсов являются самостоятельным объектом притом что каждый интерфейс имеет свой memory location с различными указателями.
G>>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM. S>>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме. G>Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет.
Я не говорил о получении IUnknown из вообще любого участка памяти. Я чисто об multiple interface navigation, который невозможен без использования состояния.
S>>>>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так". G>>>Все так, если рассматривать C++. S>>Я описал случай когда return this не удовлетворит идентичности COM. Код я просил именно к этому случаю. G>Ну ты ССЗБ. Сам придумал случай, сам делай так чтобы оно было COM.
multiple interface navigation в COM не я придумал
Здравствуйте, samius, Вы писали:
G>>>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM. S>>>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме. G>>Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет. S>Я не говорил о получении IUnknown из вообще любого участка памяти. Я чисто об multiple interface navigation, который невозможен без использования состояния.
Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта.
Это не получится также, как иметь разные ссылки на один объект в CLR. Ты по второму кругу попадаешь в одну и ту же ошибку.
Здравствуйте, artelk, Вы писали: A>А если у нас в языке нет возможности передать значения по ссылке? В IsIdentical придут две разные копии объекта.
Как бы то ни было, требования к идентичности функция не выполняет. Она таки обязана вернуть true при передаче в неё одного и того же объекта. A>Я утверждаю, что именно идентичность, реализованная в языке, позволяет нам иметь гарантии, что в последних 3х строчках мы имеем дело с одним и тем же объектом.
А я утверждаю, что по определению идентичность в ООП требует возможности различать объекты независимо от их состояния и поведения.
A>Идентичность нужна, прежде всего, для обеспечения возможности такой вещи как само состояние (а конкретно, изменяемое состояние), как понятия языка. A>И именно поэтому идентичность не может быть функцией состояния — без него самого состояния быть не может. A>Согласен ли ты с этим?
Да, согласен.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, artelk, Вы писали: A>Например, добавить в Crash "private readonly Guid id = Guid.NewGuid();", реализовать Equals через него. A>В чем подвох? Решение перестанет быть ООП?
Нет. В таком варианте — не перестанет
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Andrei N.Sobchuck, Вы писали: S>>А ты нажми на ссылку "Transaction Script", которую он приводит. ANS>Нажал. Всё равно пока не понимаю.
Я что, забыл написать "прочитай то, что написано по ссылке"?
Прошу прощения.
A Transaction Script organizes all this logic primarily as a single procedure, making calls directly to the database or through a thin database wrapper. Each transaction will have its own Transaction Script, although common subtasks can be broken into subprocedures.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM. S>>>>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме. G>>>Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет. S>>Я не говорил о получении IUnknown из вообще любого участка памяти. Я чисто об multiple interface navigation, который невозможен без использования состояния. G>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта.
Обращение к QI может вернуть другой указатель, чем указатель, по которому к нему обратились. Так как любой интерфейс COM (даже еще не объявленный) расширяет IUnknown, то любой указатель, вернувшийся из QI является указателем на IUnknown. G>Это не получится также, как иметь разные ссылки на один объект в CLR. Ты по второму кругу попадаешь в одну и ту же ошибку.
Интерфейс IUnknown будет в объекте COM единственным с точностью до указателя. А указателей на интерфейсы может быть очень дофига. При этом каждый из них будет указывать на реализацию IUnknown.
Тут мы походу запутались. Рассмотрим выражение "указатель на IUnknown". Его можно понимать как тип указателя (IUnknown*), который может указывать на все что угодно, что имеет совместимость с IUnknown. и я его понимаю именно так. Кстати, я добавлял IUnknown* на всякий случай. А можно понимать как "указатель на COM интерфейс IUnknown" в смысле (p->QueryInterface(IID_IUnknown, &pUnknown)).
Так вот, по спеке два указателя на IUnknown интерфейс одного и того же объекта должны быть равны. Но два (IUnknown*) указателя на разные интерфейсы одного объекта равны быть не должны.
Напиши все-таки код QI, разрешающий навигацию между интерфейсами и не использующий состояние. Или все-таки признай, что COM identity test использует состояние.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM. S>>>>>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме. G>>>>Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет. S>>>Я не говорил о получении IUnknown из вообще любого участка памяти. Я чисто об multiple interface navigation, который невозможен без использования состояния. G>>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта. S>Обращение к QI может вернуть другой указатель, чем указатель, по которому к нему обратились. Так как любой интерфейс COM (даже еще не объявленный) расширяет IUnknown, то любой указатель, вернувшийся из QI является указателем на IUnknown.
Что значит "является указателем IUnknown" ? Тут ты говоришь в терминах ООП в С++. С точки зрения COM единственный способ получения IUnknown — выполнить QUeryInterface. Я и говорю. что ты рассматриваешь какую-то смесь COM и C++, которая COM не является.
S>Напиши все-таки код QI, разрешающий навигацию между интерфейсами и не использующий состояние. Или все-таки признай, что COM identity test использует состояние.
Ты же сам писал что если наблюдаемое поведение не зависит от состояния, то значит совсем не зависит. В случае COM это выполняется. Если нужна реализация, то пусть возвращается всегда первый face.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта. S>>Обращение к QI может вернуть другой указатель, чем указатель, по которому к нему обратились. Так как любой интерфейс COM (даже еще не объявленный) расширяет IUnknown, то любой указатель, вернувшийся из QI является указателем на IUnknown. G>Что значит "является указателем IUnknown" ? Тут ты говоришь в терминах ООП в С++. С точки зрения COM единственный способ получения IUnknown — выполнить QUeryInterface. Я и говорю. что ты рассматриваешь какую-то смесь COM и C++, которая COM не является.
All interfaces in COM are polymorphic with IUnknown, that is, if you look at the first three functions in any interface you see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
all other interfaces inherit.
Посему указатель на любой интерфейс любого COM объекта есть указатель на IUnknown.
S>>Напиши все-таки код QI, разрешающий навигацию между интерфейсами и не использующий состояние. Или все-таки признай, что COM identity test использует состояние. G>Ты же сам писал что если наблюдаемое поведение не зависит от состояния, то значит совсем не зависит.
Ты же был там со мной категорически несогласен. А тут ссылаешься на меня?
G>В случае COM это выполняется.
Нет. Нигде не написано что QI не может изменять состояние объекта. Более того, оно именно это и делает, согласно многим сценариям COM. QI не является детерминированной в общем случае. Потому тут нельзя так легко отречься от использования состояния.
G>Если нужна реализация, то пусть возвращается всегда первый face.
Я не понял, что такое первый face, откуда он берется, и почему он должен быть именно IUnknown гранью.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
G>>>>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта. S>>>Обращение к QI может вернуть другой указатель, чем указатель, по которому к нему обратились. Так как любой интерфейс COM (даже еще не объявленный) расширяет IUnknown, то любой указатель, вернувшийся из QI является указателем на IUnknown. G>>Что значит "является указателем IUnknown" ? Тут ты говоришь в терминах ООП в С++. С точки зрения COM единственный способ получения IUnknown — выполнить QUeryInterface. Я и говорю. что ты рассматриваешь какую-то смесь COM и C++, которая COM не является. S>
S>All interfaces in COM are polymorphic with IUnknown, that is, if you look at the first three functions in any interface you see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
S>all other interfaces inherit.
S>Посему указатель на любой интерфейс любого COM объекта есть указатель на IUnknown.
И? Приведение типа в смысле C++ не является корректной операцией в COM. Для этого надо делать QueryInterface.
S>>>Напиши все-таки код QI, разрешающий навигацию между интерфейсами и не использующий состояние. Или все-таки признай, что COM identity test использует состояние. G>>Ты же сам писал что если наблюдаемое поведение не зависит от состояния, то значит совсем не зависит. S>Ты же был там со мной категорически несогласен. А тут ссылаешься на меня?
Нет, я лишь сказал что вычисления можно заменить константой если они вычисляют одно и то же значение.
G>>В случае COM это выполняется. S>Нет. Нигде не написано что QI не может изменять состояние объекта. Более того, оно именно это и делает, согласно многим сценариям COM.
Покажи пример чтоли.
S>QI не является детерминированной в общем случае.
Для IUnknown — является. Этого достаточно.
G>>Если нужна реализация, то пусть возвращается всегда первый face. S>Я не понял, что такое первый face, откуда он берется, и почему он должен быть именно IUnknown гранью.
Первый по порядку (любому).
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта. S>>>>Обращение к QI может вернуть другой указатель, чем указатель, по которому к нему обратились. Так как любой интерфейс COM (даже еще не объявленный) расширяет IUnknown, то любой указатель, вернувшийся из QI является указателем на IUnknown. G>>>Что значит "является указателем IUnknown" ? Тут ты говоришь в терминах ООП в С++. С точки зрения COM единственный способ получения IUnknown — выполнить QUeryInterface. Я и говорю. что ты рассматриваешь какую-то смесь COM и C++, которая COM не является. S>>
S>>All interfaces in COM are polymorphic with IUnknown, that is, if you look at the first three functions in any interface you see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
S>>all other interfaces inherit.
S>>Посему указатель на любой интерфейс любого COM объекта есть указатель на IUnknown. G>И? Приведение типа в смысле C++ не является корректной операцией в COM. Для этого надо делать QueryInterface.
Предлагаю отказаться от бесполезной полемики о легальности кода
Бесполезная она потому как не приведет ни к чему.
Предлагаю рассмотреть следующий пример:
IXXX *pXXX;
IYYY *pYYY;
pUnk->QueryInterface(IID_IXXX, &pXXX);
pUnk->QueryInterface(IID_IYYY, &pYYY);
// HRESULT-ы корректные, в pXXX и pYYY не NULL-ы, pXXX != pYYY
Для того что бы узнать, указывают ли pXXX и pYYY на интерфейсы одного COM объекта, по спеке нужно у pXXX и pYYY вызвать QI(IID_IUnknown, &tmp) и сравнить вернувшиеся указатели.
Вопрос, существует ли способ реализовать QI БЕЗ ИСПОЛЬЗОВАНИЯ СОСТОЯНИЯ корректным образом (в соответствии со спекой), что бы он в случе различных pXXX и pYYY вернул одинаковый результат?
S>>>>Напиши все-таки код QI, разрешающий навигацию между интерфейсами и не использующий состояние. Или все-таки признай, что COM identity test использует состояние. G>>>Ты же сам писал что если наблюдаемое поведение не зависит от состояния, то значит совсем не зависит. S>>Ты же был там со мной категорически несогласен. А тут ссылаешься на меня? G>Нет, я лишь сказал что вычисления можно заменить константой если они вычисляют одно и то же значение.
Ой, что я проглядел-то (смотрю на выделенное)!
Давай разберемся. QI — это такая функция, которая формально множество идентификаторов отображает на множество указателей
QI: GUID -> void*
Так вот, QI(IID_IUnknown) должна возвращать указатель на IUnknown грань. В нетривиальных случаях, когда объект имеет multiple interface, результат QI(IID_IUnknown) должен где-то хранитсья. Подозреваю что в состоянии, а никак не в константе. И QI должна будет взять указатель из состояния и вернуть его. И ты называешь это независимостью от состояния? Я ничего не попутал?
G>>>В случае COM это выполняется. S>>Нет. Нигде не написано что QI не может изменять состояние объекта. Более того, оно именно это и делает, согласно многим сценариям COM. G>Покажи пример чтоли.
Вот пример такого сценария из спеки (3.3.1.1)
In contrast, queries for interfaces other than IUnknown are not required to return the same
actual pointer value each time a QueryInterface returning one of them is called. This, among
other things, enables sophisticated object implementors to free individual interfaces on
their objects when they are not being used, recreating them on demand (reference
counting is a per-interface notion, as is explained further below).
S>>QI не является детерминированной в общем случае. G>Для IUnknown — является. Этого достаточно.
Этого недостаточно что бы считать QI независящей от состояния даже в случае IUnknown.
G>>>Если нужна реализация, то пусть возвращается всегда первый face. S>>Я не понял, что такое первый face, откуда он берется, и почему он должен быть именно IUnknown гранью. G>Первый по порядку (любому).
Первый face по любому порядку не обязан быть IUnknown фэйсом, о чем ты?
Здравствуйте, Sinclair, Вы писали: S>Здравствуйте, artelk, Вы писали: A>>Я утверждаю, что именно идентичность, реализованная в языке, позволяет нам иметь гарантии, что в последних 3х строчках мы имеем дело с одним и тем же объектом. S>А я утверждаю, что по определению идентичность в ООП требует возможности различать объекты независимо от их состояния и поведения.
Да, мы можем различать объекты независимо от их состояния и поведения, например:
class A { public int X; }
var a1 = new A();
var a2 = new A();
a1.X = 1;
Debug.Assert(a1.X == 1);
a2.X = 1;
Debug.Assert(a2.X == 1);
a2.X = 2;
Debug.Assert(a2.X == 2);
Debug.Assert(a1.X == 1);//все ещеvar b1 = a1;
b1.X = 3;
Debug.Assert(b1.X == 3);
Debug.Assert(a1.X == 3);//поскольку a1 ≡ b1
Debug.Assert(a2.X == 2);//все еще
Все assert-ы верны. Ссылки a1 и a2 ссылаются на различные объекты. Ссылки a1 и b1 — на идентичные.
И это должно гарантироваться языком. И это называется identity.
Здравствуйте, artelk, Вы писали:
A>Все assert-ы верны. Ссылки a1 и a2 ссылаются на различные объекты. Ссылки a1 и b1 — на идентичные.
Я не вижу здесь различения объектов независимо от их состояния и поведения.
Все проверки делаются на основе исключительно поведения объектов.
Предположение об идентичности объектов проверяется путём сравнения переходов состояний.
В то же время, как мы тут выяснили среди сотен сообщений в этом топике, из синхронности поведения объектов нельзя делать вывод об их идентичности.
Наоборот — можно.
A>И это должно гарантироваться языком. И это называется identity.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
G>>Если рассматривать ООП с точки зрения Кея, то и erlang с процессами более чем соответствует. ANS>Это упрощение. Ты из акцента на messaging (подразумевается наличие чего-то еще), оставил *только* messaging. А ведь была еще и концепция "только объект", которая подразумевает "рекурсивный дизайн", когда объекты состоят из объектов на макро и микро уровне. В Erlang процессы (как единица хранения состояния) и сообщения есть только на макро уровне.
Так Эрланг и есть ОО с т.з. Кея именно на таком уровне. Точно так же если спуститься на уровень битов, то любой язык резко перестанет быть ОО
Здравствуйте, samius, Вы писали:
S>Для того что бы узнать, указывают ли pXXX и pYYY на интерфейсы одного COM объекта, по спеке нужно у pXXX и pYYY вызвать QI(IID_IUnknown, &tmp) и сравнить вернувшиеся указатели. S>Вопрос, существует ли способ реализовать QI БЕЗ ИСПОЛЬЗОВАНИЯ СОСТОЯНИЯ корректным образом (в соответствии со спекой), что бы он в случе различных pXXX и pYYY вернул одинаковый результат?
Да сортируешь все интерфейсы по значению GIUD, выбираешь первый, приводишь всегда к нему. Где тут состояние? Любое честное или неочень изменение объекта не нарушит данное поведение.
Можно добавить еще одну "грань" к которой приводить. И снова любое честное и неочень изменение состояния не нарушит поведение, специфицированное COM.
S>Так вот, QI(IID_IUnknown) должна возвращать указатель на IUnknown грань. В нетривиальных случаях, когда объект имеет multiple interface, результат QI(IID_IUnknown) должен где-то хранитсья.
Это будет еще одна грань напрмиер.
S>Подозреваю что в состоянии, а никак не в константе.
Ниугадал.
S>И QI должна будет взять указатель из состояния и вернуть его. И ты называешь это независимостью от состояния? Я ничего не попутал?
Никто ниоткуда ниче не должен брать. Это работает на уровне реализации наследования в языке и никакое состояние руками создавать не надо. А в .NET вообще есть interface map, там проблем таких в принципе нет.
Вообще странно что ты не можешь придумать как сделать множественное наследование интерфейсов, которое работает только через this. Эта задача уже многократно реализована.
S>>>QI не является детерминированной в общем случае. G>>Для IUnknown — является. Этого достаточно. S>Этого недостаточно что бы считать QI независящей от состояния даже в случае IUnknown.
А что тогда считать "независимостью от состояния"? Тогда любой из твоих ранее приведенных примеров идентичности зависит от состояния.
Независимость от состояния обозначает ровно одно — результат функции не меняется при любом (честно или нет) изменении состояния объекта.
В COM всегда можно сделать реализацию identity, которая при любом изменении состояния, не нарушающим целостность объекта, не будет зависеть от состояния.
G>>>>Если нужна реализация, то пусть возвращается всегда первый face. S>>>Я не понял, что такое первый face, откуда он берется, и почему он должен быть именно IUnknown гранью. G>>Первый по порядку (любому). S>Первый face по любому порядку не обязан быть IUnknown фэйсом, о чем ты?
Ты и сам говорил что любой интерфейс наследуется от IUnknown и сам хотел делать приведения. Так вот предлагаю делать эти приведения внутри QueryInterface.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, artelk, Вы писали: A>>Например, добавить в Crash "private readonly Guid id = Guid.NewGuid();", реализовать Equals через него. A>>В чем подвох? Решение перестанет быть ООП? S>Нет. В таком варианте — не перестанет
Т.е. object.ReferenceEquals не является обязательным. Если нам требуется уникальность объектов в коллекции, мы можем добиться этого имеющимися средствами, так?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, gandjustas, Вы писали: G>>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта. S> Что, нетривиальная штука — COM? S>Это всё сделано на случай агрегации. G>>Это не получится также, как иметь разные ссылки на один объект в CLR. Ты по второму кругу попадаешь в одну и ту же ошибку. S>Увы — получится. Надо просто отличать два понятия: S>1. Просто указатель на IUnknown — любой указатель в COM является также и указателем на IUnknown. По причине наследования интерфейсов. S>2. Указатель на IUnknown, полученный в ответ на QI(IID_IUnknown).
Да, но "приведение типов" с точки зрения com не совсем законная операция. Чтобы получить указатель на конкретный интерфейс надо обяpательно выполнять QI.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>Для того что бы узнать, указывают ли pXXX и pYYY на интерфейсы одного COM объекта, по спеке нужно у pXXX и pYYY вызвать QI(IID_IUnknown, &tmp) и сравнить вернувшиеся указатели. S>>Вопрос, существует ли способ реализовать QI БЕЗ ИСПОЛЬЗОВАНИЯ СОСТОЯНИЯ корректным образом (в соответствии со спекой), что бы он в случе различных pXXX и pYYY вернул одинаковый результат? G>Да сортируешь все интерфейсы по значению GIUD, выбираешь первый, приводишь всегда к нему. Где тут состояние? Любое честное или неочень изменение объекта не нарушит данное поведение.
Где предлагаешь хранить коллекцию интерфейсов, если не в состоянии?
G>Можно добавить еще одну "грань" к которой приводить. И снова любое честное и неочень изменение состояния не нарушит поведение, специфицированное COM.
Где хранить указатель на грань?
S>>Так вот, QI(IID_IUnknown) должна возвращать указатель на IUnknown грань. В нетривиальных случаях, когда объект имеет multiple interface, результат QI(IID_IUnknown) должен где-то хранитсья. G>Это будет еще одна грань напрмиер.
Так где будем хранить указатель?
S>>Подозреваю что в состоянии, а никак не в константе. G>Ниугадал.
покажи код
S>>И QI должна будет взять указатель из состояния и вернуть его. И ты называешь это независимостью от состояния? Я ничего не попутал? G>Никто ниоткуда ниче не должен брать. Это работает на уровне реализации наследования в языке и никакое состояние руками создавать не надо. А в .NET вообще есть interface map, там проблем таких в принципе нет.
Реализация наследования в каком-то языке не покрывает сценарии использования СOM. В дотнет тем более.
G>Вообще странно что ты не можешь придумать как сделать множественное наследование интерфейсов, которое работает только через this. Эта задача уже многократно реализована.
Демагогия детектед.
Не по адресу — спеку COM писал не я.
Не вовремя — спеку писали очень давно и уже успели налабать толпу кода, так что предложение запоздало.
Не в кассу — разработчики COM знали про множественное наследование, просто они COM разрабатывали не под языки со множественным наследованием и предполагали сценарии реюза объектов отличные от множественного наследования и composition/delegation, в том числе cross-language сценарии реюза и расширения.
S>>>>QI не является детерминированной в общем случае. G>>>Для IUnknown — является. Этого достаточно. S>>Этого недостаточно что бы считать QI независящей от состояния даже в случае IUnknown. G>А что тогда считать "независимостью от состояния"? Тогда любой из твоих ранее приведенных примеров идентичности зависит от состояния. G>Независимость от состояния обозначает ровно одно — результат функции не меняется при любом (честно или нет) изменении состояния объекта.
Об этом не очень спортивно говорить, когда ты берешь состояние и возвращаешь его в качестве результата.
G>В COM всегда можно сделать реализацию identity, которая при любом изменении состояния, не нарушающим целостность объекта, не будет зависеть от состояния.
Что бы оперировать такими аргументами, ты должен согласиться с ними сперва. Ты же мне говорил что "опираться на состояние" не по правилам вычисления identity.
G>>>>>Если нужна реализация, то пусть возвращается всегда первый face. S>>>>Я не понял, что такое первый face, откуда он берется, и почему он должен быть именно IUnknown гранью. G>>>Первый по порядку (любому). S>>Первый face по любому порядку не обязан быть IUnknown фэйсом, о чем ты? G>Ты и сам говорил что любой интерфейс наследуется от IUnknown и сам хотел делать приведения. Так вот предлагаю делать эти приведения внутри QueryInterface.
Предлагаешь выкинуть сценарии расширения COM объектов? Мне? Я не копенгаген решать такие вопросы.
И вообще, QI придумали именно для того, что бы обрулить сценарии расширения и реюза. Он такой именно поэтому. И идентичность в COM определена через QI именно для этих целей. В своем маленьком объекте, не предназначенном для расширения, ты можешь так и сделать. Но мы говорим об идентичности в COM, а не идентичности COM объекта написанного на C++ и не предполагающего расширение.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Для того что бы узнать, указывают ли pXXX и pYYY на интерфейсы одного COM объекта, по спеке нужно у pXXX и pYYY вызвать QI(IID_IUnknown, &tmp) и сравнить вернувшиеся указатели. S>>>Вопрос, существует ли способ реализовать QI БЕЗ ИСПОЛЬЗОВАНИЯ СОСТОЯНИЯ корректным образом (в соответствии со спекой), что бы он в случе различных pXXX и pYYY вернул одинаковый результат? G>>Да сортируешь все интерфейсы по значению GIUD, выбираешь первый, приводишь всегда к нему. Где тут состояние? Любое честное или неочень изменение объекта не нарушит данное поведение. S>Где предлагаешь хранить коллекцию интерфейсов, если не в состоянии?
Его не надо хранить. Ты заранее выбери один интерфейс, к которому будет приводиться.
G>>Можно добавить еще одну "грань" к которой приводить. И снова любое честное и неочень изменение состояния не нарушит поведение, специфицированное COM. S>Где хранить указатель на грань?
Его не надо хранить, его надо возвращать. Можно прямо в том case, который ты ранее рисовал.
S>>>Подозреваю что в состоянии, а никак не в константе. G>>Ниугадал. S>покажи код
return (IUnknown*)this;
S>>>И QI должна будет взять указатель из состояния и вернуть его. И ты называешь это независимостью от состояния? Я ничего не попутал? G>>Никто ниоткуда ниче не должен брать. Это работает на уровне реализации наследования в языке и никакое состояние руками создавать не надо. А в .NET вообще есть interface map, там проблем таких в принципе нет. S>Реализация наследования в каком-то языке не покрывает сценарии использования СOM. В дотнет тем более.
Не все сценарии, но основные вполне, для которых COM создавался — вполне. Некоторые фичи com по-моему вообще в дикой природе не встретишь.
G>>>>>>Если нужна реализация, то пусть возвращается всегда первый face. S>>>>>Я не понял, что такое первый face, откуда он берется, и почему он должен быть именно IUnknown гранью. G>>>>Первый по порядку (любому). S>>>Первый face по любому порядку не обязан быть IUnknown фэйсом, о чем ты? G>>Ты и сам говорил что любой интерфейс наследуется от IUnknown и сам хотел делать приведения. Так вот предлагаю делать эти приведения внутри QueryInterface. S>Предлагаешь выкинуть сценарии расширения COM объектов? Мне? Я не копенгаген решать такие вопросы.
Я предлагаю решение для сценария, который ты сам придумал. Ведь можно и другой сценарий придумать, который будет не менее рабочий, и не менее COM.
S>И вообще, QI придумали именно для того, что бы обрулить сценарии расширения и реюза. Он такой именно поэтому. И идентичность в COM определена через QI именно для этих целей. В своем маленьком объекте, не предназначенном для расширения, ты можешь так и сделать. Но мы говорим об идентичности в COM, а не идентичности COM объекта написанного на C++ и не предполагающего расширение.
Без разницы, главное чтобы QueryInterface(IUnknown) возвращал всегда одно значение, независимо от состояния и поведения.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>>>Для того что бы узнать, указывают ли pXXX и pYYY на интерфейсы одного COM объекта, по спеке нужно у pXXX и pYYY вызвать QI(IID_IUnknown, &tmp) и сравнить вернувшиеся указатели. S>>>>Вопрос, существует ли способ реализовать QI БЕЗ ИСПОЛЬЗОВАНИЯ СОСТОЯНИЯ корректным образом (в соответствии со спекой), что бы он в случе различных pXXX и pYYY вернул одинаковый результат? G>>>Да сортируешь все интерфейсы по значению GIUD, выбираешь первый, приводишь всегда к нему. Где тут состояние? Любое честное или неочень изменение объекта не нарушит данное поведение. S>>Где предлагаешь хранить коллекцию интерфейсов, если не в состоянии? G>Его не надо хранить. Ты заранее выбери один интерфейс, к которому будет приводиться.
Интерфейсы pXXX и pYYY лежат в разных местах. Нужна навигация между ними. Приведением навигацию не обеспечить.
G>>>Можно добавить еще одну "грань" к которой приводить. И снова любое честное и неочень изменение состояния не нарушит поведение, специфицированное COM. S>>Где хранить указатель на грань? G>Его не надо хранить, его надо возвращать. Можно прямо в том case, который ты ранее рисовал.
S>>>>Подозреваю что в состоянии, а никак не в константе. G>>>Ниугадал. S>>покажи код
G>
G>return (IUnknown*)this;
G>
this указывает на грань, отличную от IID_IUnknown. Как быть?
S>>>>И QI должна будет взять указатель из состояния и вернуть его. И ты называешь это независимостью от состояния? Я ничего не попутал? G>>>Никто ниоткуда ниче не должен брать. Это работает на уровне реализации наследования в языке и никакое состояние руками создавать не надо. А в .NET вообще есть interface map, там проблем таких в принципе нет. S>>Реализация наследования в каком-то языке не покрывает сценарии использования СOM. В дотнет тем более. G>Не все сценарии, но основные вполне, для которых COM создавался — вполне. Некоторые фичи com по-моему вообще в дикой природе не встретишь.
Так ты предлагаешь отказаться от сценариев, где требуется состояние для реализации QI для того что бы убедить меня в том, что разработчики спеки не подразумевали использование состояния в QI при вычислении identity?
G>>>>>Первый по порядку (любому). S>>>>Первый face по любому порядку не обязан быть IUnknown фэйсом, о чем ты? G>>>Ты и сам говорил что любой интерфейс наследуется от IUnknown и сам хотел делать приведения. Так вот предлагаю делать эти приведения внутри QueryInterface. S>>Предлагаешь выкинуть сценарии расширения COM объектов? Мне? Я не копенгаген решать такие вопросы. G>Я предлагаю решение для сценария, который ты сам придумал. Ведь можно и другой сценарий придумать, который будет не менее рабочий, и не менее COM.
Сценарий multiple interface navigation придумал не я. Это довольно типичный сценарий в COM уровня чуть глубже букварного. В спеке он упоминается неоднократно, даже с примерами реализации.
S>>И вообще, QI придумали именно для того, что бы обрулить сценарии расширения и реюза. Он такой именно поэтому. И идентичность в COM определена через QI именно для этих целей. В своем маленьком объекте, не предназначенном для расширения, ты можешь так и сделать. Но мы говорим об идентичности в COM, а не идентичности COM объекта написанного на C++ и не предполагающего расширение. G>Без разницы, главное чтобы QueryInterface(IUnknown) возвращал всегда одно значение, независимо от состояния и поведения.
Не без разницы. Я тебе указываю на те случаи, когда результат QI нужно хранить в состоянии грани. Ты их упорно игнорируешь.
Я все жду, какой сценарий ты предпочтешь...
а) COM использует состояние в вычислении ID, значит незазорно использовать данные строки при сравнении двух строк.
б) COM не использует состояние в вычислении ID, значит сравнение строк не использует состояние.
Здравствуйте, artelk, Вы писали: A>Т.е. object.ReferenceEquals не является обязательным. Если нам требуется уникальность объектов в коллекции, мы можем добиться этого имеющимися средствами, так?
В том случае, если у нас есть альтернативный механизм identity — да.
Вы только что его ввели. Если identity нет, то мы огребаем.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
G>Да, но "приведение типов" с точки зрения com не совсем законная операция. Чтобы получить указатель на конкретный интерфейс надо обяpательно выполнять QI.
Вот в этом я не уверен. Беглый просмотр интернетов не дал ответа на вопрос, обязан ли я перезапрашивать интерфейс-предок, или таки нет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>>>Для того что бы узнать, указывают ли pXXX и pYYY на интерфейсы одного COM объекта, по спеке нужно у pXXX и pYYY вызвать QI(IID_IUnknown, &tmp) и сравнить вернувшиеся указатели. S>>>>>Вопрос, существует ли способ реализовать QI БЕЗ ИСПОЛЬЗОВАНИЯ СОСТОЯНИЯ корректным образом (в соответствии со спекой), что бы он в случе различных pXXX и pYYY вернул одинаковый результат? G>>>>Да сортируешь все интерфейсы по значению GIUD, выбираешь первый, приводишь всегда к нему. Где тут состояние? Любое честное или неочень изменение объекта не нарушит данное поведение. S>>>Где предлагаешь хранить коллекцию интерфейсов, если не в состоянии? G>>Его не надо хранить. Ты заранее выбери один интерфейс, к которому будет приводиться. S>Интерфейсы pXXX и pYYY лежат в разных местах. Нужна навигация между ними. Приведением навигацию не обеспечить.
Да без разницы, нам только надо возвращать всегда одинаковую ссылку на QueryInterface(IUnknown), остальное не интересует.
G>>
G>>return (IUnknown*)this;
G>>
S>this указывает на грань, отличную от IID_IUnknown. Как быть?
Пусть указывает, ведь каждый интерфейс является всегда IUnknown и при данной реализации всегда будет возвращать одно значение.
Или ты что-то другое имеешь ввиду?
S>>>>>И QI должна будет взять указатель из состояния и вернуть его. И ты называешь это независимостью от состояния? Я ничего не попутал? G>>>>Никто ниоткуда ниче не должен брать. Это работает на уровне реализации наследования в языке и никакое состояние руками создавать не надо. А в .NET вообще есть interface map, там проблем таких в принципе нет. S>>>Реализация наследования в каком-то языке не покрывает сценарии использования СOM. В дотнет тем более. G>>Не все сценарии, но основные вполне, для которых COM создавался — вполне. Некоторые фичи com по-моему вообще в дикой природе не встретишь. S>Так ты предлагаешь отказаться от сценариев, где требуется состояние для реализации QI для того что бы убедить меня в том, что разработчики спеки не подразумевали использование состояния в QI при вычислении identity?
Нет, я лишь говорю что если ты придумываешь сложности — ты их и решай. Но принципиальных проблем обеспечить независимость от состояния QueryInterface(IUnknown) я не вижу.
G>>>>>>Первый по порядку (любому). S>>>>>Первый face по любому порядку не обязан быть IUnknown фэйсом, о чем ты? G>>>>Ты и сам говорил что любой интерфейс наследуется от IUnknown и сам хотел делать приведения. Так вот предлагаю делать эти приведения внутри QueryInterface. S>>>Предлагаешь выкинуть сценарии расширения COM объектов? Мне? Я не копенгаген решать такие вопросы. G>>Я предлагаю решение для сценария, который ты сам придумал. Ведь можно и другой сценарий придумать, который будет не менее рабочий, и не менее COM. S>Сценарий multiple interface navigation придумал не я. Это довольно типичный сценарий в COM уровня чуть глубже букварного. В спеке он упоминается неоднократно, даже с примерами реализации.
А пример такого в компонентах есть?
S>>>И вообще, QI придумали именно для того, что бы обрулить сценарии расширения и реюза. Он такой именно поэтому. И идентичность в COM определена через QI именно для этих целей. В своем маленьком объекте, не предназначенном для расширения, ты можешь так и сделать. Но мы говорим об идентичности в COM, а не идентичности COM объекта написанного на C++ и не предполагающего расширение. G>>Без разницы, главное чтобы QueryInterface(IUnknown) возвращал всегда одно значение, независимо от состояния и поведения. S>Не без разницы. Я тебе указываю на те случаи, когда результат QI нужно хранить в состоянии грани. Ты их упорно игнорируешь.
Если ты сделал такую реализацию что надо хранить, то ССЗБ. Не делай такую реализацию. Я же тебе говорил что можно почти все сделать через механизмы множественного наследования, которые уже давно работают в разных языках.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Да, но "приведение типов" с точки зрения com не совсем законная операция. Чтобы получить указатель на конкретный интерфейс надо обяpательно выполнять QI. S>Вот в этом я не уверен. Беглый просмотр интернетов не дал ответа на вопрос, обязан ли я перезапрашивать интерфейс-предок, или таки нет.
ровно по той же причине по которой надо запрашивать QueryInterface(IUnknown) надо запрашивать и другие интерфейсы. Иначе просто не создавали бы эту функцию.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Да, но "приведение типов" с точки зрения com не совсем законная операция. Чтобы получить указатель на конкретный интерфейс надо обяpательно выполнять QI. S>Вот в этом я не уверен. Беглый просмотр интернетов не дал ответа на вопрос, обязан ли я перезапрашивать интерфейс-предок, или таки нет.
Мне тоже этот вопрос до конца не ясен в общем случае. Думаю, что любая навигация между интерфейсами должна производиться через QI. Но для того что бы переключиться, надо обратиться к методу QI интерфейса IUnknown (без IID). Вот к этому методу мы можем обращаться не вызывая QI(IID_IUnknown) (здесь IID не случайно), т.к. все интерфейсы одного объекта обязаны возвращать согласованные результаты QI. Отсюда следует, что любой интерфейс может быть использован как IUnknown без запроса QI(IID_IUnknown).
Здравствуйте, samius, Вы писали:
S>Мне тоже этот вопрос до конца не ясен в общем случае. Думаю, что любая навигация между интерфейсами должна производиться через QI. Но для того что бы переключиться, надо обратиться к методу QI интерфейса IUnknown (без IID). Вот к этому методу мы можем обращаться не вызывая QI(IID_IUnknown) (здесь IID не случайно), т.к. все интерфейсы одного объекта обязаны возвращать согласованные результаты QI. Отсюда следует, что любой интерфейс может быть использован как IUnknown без запроса QI(IID_IUnknown).
Полагаю, вы правы. Согласованность результатов QI при обращении через разные интерфейсы гарантирована стандартом.
А вот то, что IWebBrowser2 можно пользоваться так же, как и IWebBrowser, не гарантирована ничем
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
G>>>>Не все сценарии, но основные вполне, для которых COM создавался — вполне. Некоторые фичи com по-моему вообще в дикой природе не встретишь. S>>>Так ты предлагаешь отказаться от сценариев, где требуется состояние для реализации QI для того что бы убедить меня в том, что разработчики спеки не подразумевали использование состояния в QI при вычислении identity? G>>Нет, я лишь говорю что если ты придумываешь сложности — ты их и решай. Но принципиальных проблем обеспечить независимость от состояния QueryInterface(IUnknown) я не вижу. S>Это не мои сложности и я не вижу, как выполнить QI в общем случае без того что бы вернуть значение, хранящееся в состояние.
Как раз кроме отдельных извращенных случаев, которые нельзя свести множественному наследованию, можно без состояния. Ты же сам приводишь реализацию с состоянием и говоришь что там identity без состояния нельзя. Конечно нельзя, ты же сам сделал там состояние.
[]
S>Увы — получится. Надо просто отличать два понятия: S>1. Просто указатель на IUnknown — любой указатель в COM является также и указателем на IUnknown. По причине наследования интерфейсов.
Разве COM говорит что-то про наследование? Что есть наследование, если объект реализован на Делфи а используется в С?
Говорить о "наследовании", афаик, можно только в терминах QI.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
G>>>>>Не все сценарии, но основные вполне, для которых COM создавался — вполне. Некоторые фичи com по-моему вообще в дикой природе не встретишь. S>>>>Так ты предлагаешь отказаться от сценариев, где требуется состояние для реализации QI для того что бы убедить меня в том, что разработчики спеки не подразумевали использование состояния в QI при вычислении identity? G>>>Нет, я лишь говорю что если ты придумываешь сложности — ты их и решай. Но принципиальных проблем обеспечить независимость от состояния QueryInterface(IUnknown) я не вижу. S>>Это не мои сложности и я не вижу, как выполнить QI в общем случае без того что бы вернуть значение, хранящееся в состояние. G>Как раз кроме отдельных извращенных случаев, которые нельзя свести множественному наследованию, можно без состояния. Ты же сам приводишь реализацию с состоянием и говоришь что там identity без состояния нельзя. Конечно нельзя, ты же сам сделал там состояние.
Отдельные извращенные случаи — это то что в COM считается официальным способом расширения объектов не ограничиваясь отдельными языками и платформами, поддерживающими множественное наследование.
То что в частных тривиальных случаях QI может быть реализован без состояния не значит что identity COM в общем случае не использует состояния. Особенно в свете того, что QI в identity вызывается именно для совместимости с "отдельными извращенными случаями". Если бы не эти отдельные случаи, то требование вызова QI при определении identity было бы излишним. Не находишь?
L>> Более того, очень многими неглупыми людьми ставится под сомнение его полезность. М>про все ооп не скажу, но вот никак не могу понять -- действительно ли язык программирования должен быть таким сложным, как плюсы? говорят, что плюсы обеспечивают высокую производительность. и где же она?
для того чтобы получить высокую производительность, нужно проектировать для высокой производительности. Производительность не может быть поздней идеей, так же как и безопасность.
Программа не станет автоматичски быстрой если ее просто писать на плюсах, или безопасной — если писать на .нет\жабе
М>вот я и думаю -- а что мне дадут плюсы, если их выучить?
тебе — скорее всего ничего. Ты сам много раз говорил что ты не разработчик, а реверсер.
М>у плюсов же -- производительность только в теории, на практике оно тормозит и отжирает память
ты вообще-то рассуждаешь о том чего не знаешь
Здравствуйте, rm822, Вы писали:
М>>у плюсов же -- производительность только в теории, на практике оно тормозит и отжирает память R>ты вообще-то рассуждаешь о том чего не знаешь
для того, чтобы разбираться в устрицах не обязательно их готовить. достаточно их есть.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
М>для того, чтобы разбираться в устрицах не обязательно их готовить. достаточно их есть.
ну конечно, попользовался несколькими продуктами и однозначно сделал вывод и достоинствах языка на котором он написан
S>Это не определение. Это чушь, которой забивают мозг неопытным разработчикам. Потом их очень трудно лечить от заблуждений. S>Для начала, нужно твёрдо усвоить, что ООП — оно целиком про поведение. А не про структуру полей и методов.
А что в твоем понимании есть ооп? (Гугл выдал нерелевантные запросы на алана кея и определение ооп)
В моем понимании OOP — есть просто следствие OOD(esign). Т.е. если софт следует OOD принципам, таким как SOLID — програмирование можно считать ОО, независимо от того если в языке такие инструменты как классы, наследование или полиморфное поведение.
Здравствуйте, VladD2, Вы писали:
VD>А так тема очень широкая, так как методы метапрограммирования и DSL-естроения очень разнообразны. От строковой конкатинации и T4, до Nemerle и Lisp.
Ви ест имели в виду m4 ?
Просто, мне, как человеку, ежедневно использующему, режет глаз.
Здравствуйте, borisman3, Вы писали:
B>Здравствуйте, VladD2, Вы писали:
VD>>А так тема очень широкая, так как методы метапрограммирования и DSL-естроения очень разнообразны. От строковой конкатинации и T4, до Nemerle и Lisp.
B>Ви ест имели в виду m4 ? http://en.wikipedia.org/wiki/Text_Template_Transformation_Toolkit
B>Просто, мне, как человеку, ежедневно использующему, режет глаз.
Здравствуйте, borisman3, Вы писали:
VD>>А так тема очень широкая, так как методы метапрограммирования и DSL-естроения очень разнообразны. От строковой конкатинации и T4, до Nemerle и Lisp.
B>Ви ест имели в виду m4 ?
Не, M16, конечно еже .
B>Просто, мне, как человеку, ежедневно использующему, режет глаз.
Ежедневно использующему что? Lisp, Nemerle или T4?
Я, вообще-то, говорил о текстуальном шаблонизаторе T4. Это, конечно же, очень убогий тул. Но за не имением прекрасной горничной, как говорится, имеют старого дворника.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, Sinclair, Вы писали:
P>[]
S>>Увы — получится. Надо просто отличать два понятия: S>>1. Просто указатель на IUnknown — любой указатель в COM является также и указателем на IUnknown. По причине наследования интерфейсов.
P>Разве COM говорит что-то про наследование? Что есть наследование, если объект реализован на Делфи а используется в С?
COM определяет двоичный стандарт, потому возможность самого вызова COM объекта — это забота производителя компилятора, не говоря уже о наследовании. P>Говорить о "наследовании", афаик, можно только в терминах QI.
3.3 The IUnknown Interface
This specification has already mentioned the IUnknown interface many times. It is the fun-
damental interface in COM that contains basic operations of not only all objects, but all
interfaces as well: reference counting and QueryInterface. All interfaces in COM are poly-
morphic with IUnknown, that is, if you look at the first three functions in any interface you
see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
all other interfaces inherit.
Здравствуйте, Patalog, Вы писали:
P>Можно развернуть? Имеется в виду P>?
Нет. Не надо усложнять. COM говорит о том, что интерфейсы могут наследоваться друг от друга, но любой интерфейс, явно или неявно, обязан наследоваться от IUnknown. Что именно вам непонятно?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lloyd, Вы писали:
I>>>Это слишком общая формулировка. Разве здесь сказано, что "все структуры данных должны иметь хотя бы один метод для работы с этими данными" ?
L>>Конечно общая. ООП — это вообще довольно мутное понятие.
L>Ну что, господа, наставившие минусов, количество сообщений в теме еще не убедило вас в правоте отквоченной фразы?
В огороде бузина а в киеве дядька. Вот если бы твоя мессага содержала только одно выделеное сообщение, то ты бы гарантировано получил на один минус меньше. Чувствуешь направление ?
[]
S>Нет. Не надо усложнять. COM говорит о том, что интерфейсы могут наследоваться друг от друга, но любой интерфейс, явно или неявно, обязан наследоваться от IUnknown.
Что есть наследование в данном случае? Возможность вызова методов IUnknown от любого интерфейса?
S>Что именно вам непонятно?
Вот —
Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта.
Афаик, финты типа
IUnknown* u1 = QI(...)
IUnknown* u2 = (IUnknown*)some_iface_ptr;
не корректны с точки зрения COM, поскольку identity определяется через QI.
S>3.3 The IUnknown Interface
S>This specification has already mentioned the IUnknown interface many times. It is the fun-
S>damental interface in COM that contains basic operations of not only all objects, but all
S>interfaces as well: reference counting and QueryInterface. All interfaces in COM are poly-
S>morphic with IUnknown, that is, if you look at the first three functions in any interface you
S>see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
S>all other interfaces inherit.
Ну и? Тут как раз и говориться, про то, что от любого интерфейса можно вызвать методы IUnknown.
Меня интересует
Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта.
P>Что есть наследование в данном случае? Возможность вызова методов IUnknown от любого интерфейса?
В данном случае наследование означает, что любой, реализующий методы интерфейса IWebBrowser3, автоматически обязан реализовать методы интерфейса IWebBrowser2.
S>>Что именно вам непонятно?
P>Вот — P>
P>Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта.
P>Афаик, финты типа P>не корректны с точки зрения COM, поскольку identity определяется через QI.
Я продолжаю непонимать, что вам непонятно.
Да, есть способ получить два разных указателя на IUnknown для одного объекта, оставаясь в рамках стандарта. Да, identity определяется через QI(IID_IUnknown). Эти два факта тесно связаны между собой, как равенство нулю массы покоя фотона и отсутствие продольной составляющей у электромагнитных колебаний.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
хъ
P>>Что есть наследование в данном случае? Возможность вызова методов IUnknown от любого интерфейса?
S>В данном случае наследование означает, что любой, реализующий методы интерфейса IWebBrowser3, автоматически обязан реализовать методы интерфейса IWebBrowser2.
Афаик, стандарт говорит про обязательность такого наследования только для IUnknown. Разве для произвольных интерфейсов (IWebBrowser3<-IWebBrowser2)
такое требование есть? То, что оно в реальности так разве не следствие того, что нельзя менять опубликованные интерфейсы?
хъ
S>Я продолжаю непонимать, что вам непонятно. S>Да, есть способ получить два разных указателя на IUnknown для одного объекта, оставаясь в рамках стандарта.
Как? Откастив? Ком ничего не знает про приведения типов. Легальный способ получить IUnknown у объекта — это QI.
Каким образом получить два разных указателя на IUnknown через QI, при условии что компонент не нарушает правила кома — мне не понятно.
S>>>3.3 The IUnknown Interface
S>>>This specification has already mentioned the IUnknown interface many times. It is the fun-
S>>>damental interface in COM that contains basic operations of not only all objects, but all
S>>>interfaces as well: reference counting and QueryInterface. All interfaces in COM are poly-
S>>>morphic with IUnknown, that is, if you look at the first three functions in any interface you
S>>>see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
S>>>all other interfaces inherit.
S>Из того что все интерфейсы полиморфны IUnknown, следует, что полученный pUnk2 является легальным указателем на IUnknown. Способ его получения легален, хоть и не гарантирует получения отличного указателя.
Полученный указатель является легальным указателем на ISomeInterface.
В приведенной цитате стандарта не просто так говориться про наследование поведения.
Откуда следует, что "полиморфен IUnknown" (т.е. reference counting and QueryInterface) означает "легальным указателем на IUnknown"?
По принципу duck typing что-ли?
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, samius, Вы писали:
P>хъ
S>>>>
S>>>>interfaces as well: reference counting and QueryInterface. All interfaces in COM are poly-
S>>>>morphic with IUnknown, that is, if you look at the first three functions in any interface you
S>>>>see QueryInterface, AddRef, and Release. In other words, IUnknown is base interface from which
S>>>>all other interfaces inherit.
S>>Из того что все интерфейсы полиморфны IUnknown, следует, что полученный pUnk2 является легальным указателем на IUnknown. Способ его получения легален, хоть и не гарантирует получения отличного указателя.
P>Полученный указатель является легальным указателем на ISomeInterface. P>В приведенной цитате стандарта не просто так говориться про наследование поведения. P>Откуда следует, что "полиморфен IUnknown" (т.е. reference counting and QueryInterface) означает "легальным указателем на IUnknown"?
Из спецификации следует и по двоичному стандарту тоже. P>По принципу duck typing что-ли?
По принципу устройства vtbl. duck typing там тоже имеет место и его обеспечивает IDispatch. Но речь именно о vtbl.
2.1.2 Interfaces and Inheritance
COM separates class hierarchy (or indeed any other implementation technology) from
interface hierarchy and both of those from any implementation hierarchy. Therefore,
interface inheritance is only applied to reuse the definition of the contract associated
with the base interface. There is no selective inheritance in COM: if one interface inher-
its from another, it includes all the functions that the other interface defines, for the
same reason than an object must implement all interface functions it inherits.
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, Sinclair, Вы писали:
P>хъ
S>>В данном случае наследование означает, что любой, реализующий методы интерфейса IWebBrowser3, автоматически обязан реализовать методы интерфейса IWebBrowser2.
P>Афаик, стандарт говорит про обязательность такого наследования только для IUnknown. Разве для произвольных интерфейсов (IWebBrowser3<-IWebBrowser2)
При условии объявления того что IWebBrowser3 наследуется от IWebBrowser2. (но IWebBrowser2 не имеет родственных связей с IWebBrowser теснее чем через общих предков IDispatch, IUnknown) P>такое требование есть? То, что оно в реальности так разве не следствие того, что нельзя менять опубликованные интерфейсы?
Есть такое требование (2.1.2)
А то что нельзя менять опубликованные интерфейсы — это для обеспечения совместимости.
P>хъ
S>>Я продолжаю непонимать, что вам непонятно. S>>Да, есть способ получить два разных указателя на IUnknown для одного объекта, оставаясь в рамках стандарта.
P>Как? Откастив? Ком ничего не знает про приведения типов. Легальный способ получить IUnknown у объекта — это QI.
Ком знает про полиморфизм любого интерфейса с IUnknown P>Каким образом получить два разных указателя на IUnknown через QI, при условии что компонент не нарушает правила кома — мне не понятно.
Где в правилах COM написано что нельзя приводить указатель на интерфейс к IUnknown* ? Можно цитату?
[]
S>Где в правилах COM написано что нельзя приводить указатель на интерфейс к IUnknown* ? Можно цитату?
Я не знаток стандарта ком, так что цитату не дам.
И хочу уточнить, если ты не заметил — я с вами (с тобой и Синклером) вообще говоря не спорю, просто хочу разобраться.
Афаик, ком не может говорить ничего такого, поскольку он ничего не знает ни про какие приведения типов. "Приведение типов" там ровно одно — QI.
Вообще говоря, спор в этом топике крутился вокруг IUnknown & identity. Правильно ли я понимаю, что ведя речь про то, что комовская идентичность опирается на состояние объекта, имеется в виду агрегация и ссылка на внешний объект в агрегате?
[]
S>Из спецификации следует и по двоичному стандарту тоже.
P>>По принципу duck typing что-ли?
S>По принципу устройства vtbl. duck typing там тоже имеет место и его обеспечивает IDispatch. Но речь именно о vtbl. S>
S>2.1.2 Interfaces and Inheritance
S>COM separates class hierarchy (or indeed any other implementation technology) from
S>interface hierarchy and both of those from any implementation hierarchy. Therefore,
S>interface inheritance is only applied to reuse the definition of the contract associated
S>with the base interface. There is no selective inheritance in COM: if one interface inher-
S>its from another, it includes all the functions that the other interface defines, for the
S>same reason than an object must implement all interface functions it inherits.
Спасибо за цитату, это как раз то, про что я говорил — наследуется поведение (контракт). Наследования в понимании того же С++, когда class B : pulic A означает B is A и B* ptr является также указателем на A — в случае интерфейсов кома нет.
Т.е. —
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, samius, Вы писали:
P>[]
S>>Из спецификации следует и по двоичному стандарту тоже.
P>>>По принципу duck typing что-ли?
S>>По принципу устройства vtbl. duck typing там тоже имеет место и его обеспечивает IDispatch. Но речь именно о vtbl. S>>
S>>2.1.2 Interfaces and Inheritance
S>>COM separates class hierarchy (or indeed any other implementation technology) from
S>>interface hierarchy and both of those from any implementation hierarchy. Therefore,
S>>interface inheritance is only applied to reuse the definition of the contract associated
S>>with the base interface. There is no selective inheritance in COM: if one interface inher-
S>>its from another, it includes all the functions that the other interface defines, for the
S>>same reason than an object must implement all interface functions it inherits.
P>Спасибо за цитату, это как раз то, про что я говорил — наследуется поведение (контракт). Наследования в понимании того же С++, когда class B : pulic A означает B is A и B* ptr является также указателем на A — в случае интерфейсов кома нет.
Есть. Это наследование обеспечено двоичным стандартом vtbl.
P>Т.е. — P>
P>Наследует ли данный интерфейс IUnknown в терминах кома? Имхо — да. Является ли указатель на данный интерфейс указателем на IUnknown? Имхо — нет.
Если здесь описан корректный интерфейс в отношении двоичного стандарта vtbl COM, то указатель на данный интерфейс будет указателем на IUnknown. Если двоичный стандарт vtbl нарушен, тогда — не будет являться. Но в этом случае это будет и не COM.
В спеке есть параграф
3.1.4 C vs C++ vs...
В нем как раз описывается как на C сделать объект, удовлетворяющий стандарту vtbl. Корректно собранный такой объект позволит обращаться к себе через указатель на интерфейс IUnknown в терминах C++.
Здравствуйте, Patalog, Вы писали:
P>Афаик, стандарт говорит про обязательность такого наследования только для IUnknown. Разве для произвольных интерфейсов (IWebBrowser3<-IWebBrowser2) P>такое требование есть? То, что оно в реальности так разве не следствие того, что нельзя менять опубликованные интерфейсы?
Inheritance in COM does not mean code reuse. Because no implementations are associated with interfaces, interface inheritance does not mean code inheritance. It means only that the contract associated with an interface is inherited in a C++ pure-virtual base-class fashion and modified — either by adding new methods or by further qualifying the allowed usage of methods. There is no selective inheritance in COM. If one interface inherits from another, it includes all the methods that the other interface defines.
здесь
P>Как? Откастив? Ком ничего не знает про приведения типов.
Простите, COM знает всё про приведения типов. Это бинарный стандарт на устройство VMT. P>Легальный способ получить IUnknown у объекта — это QI.
C точки зрения совместимости типов, указатель на любой интерфейс является также и указателем на IUnknown. P>Каким образом получить два разных указателя на IUnknown через QI, при условии что компонент не нарушает правила кома — мне не понятно.
Это расстраивает.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
[]
S>C точки зрения совместимости типов, указатель на любой интерфейс является также и указателем на IUnknown.
P>>Каким образом получить два разных указателя на IUnknown через QI, при условии что компонент не нарушает правила кома — мне не понятно.
S>Это расстраивает.
Диссонанс у меня возник по поводу того, что приведя любой интерфейс к IUnknown мы получим валидный указатель.
Точнее я не вижу в этом смысла, поскольку использовать такой указатель для identity все равно нельзя (а контекст топика именно об этом), а вызвать методы IUnknown можно и без всякого приведения.
Здравствуйте, Patalog, Вы писали:
P>Диссонанс у меня возник по поводу того, что приведя любой интерфейс к IUnknown мы получим валидный указатель. P>Точнее я не вижу в этом смысла, поскольку использовать такой указатель для identity все равно нельзя (а контекст топика именно об этом), а вызвать методы IUnknown можно и без всякого приведения.
Это всё объясняется в книг Дона Бокса "Essential COM". Как раз из за всяких delegation, aggregation нельзя использоть любой IUnkwon* для идентити.
[]
I>Это всё объясняется в книг Дона Бокса "Essential COM". Как раз из за всяких delegation, aggregation нельзя использоть любой IUnkwon* для идентити.