Re[36]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 12.01.07 18:40
Оценка:
Здравствуйте, GlebZ, Вы писали:

IT>>Я не задавал этот вопрос. Мой вопрос был являются ли DTO частью бизнес логики или нет.

GZ>Ты сам дал ответ.

Бизнес логика в моём понимании — это часть системы, которая занимается реализацией функциональных требований.

GZ>DTO — это обеспечение operation requirement.

Только что ты говорил, что DTO — это:

Без изобретения есть функциональные требования, а есть нефункциональные требования. Генерация DTO — обеспечение нефункциональных требований.



IT>>Впрочем, твой ответ, если внимательно посмотреть, лишь подтверждает мои слова

GZ>Какие?

Я теперь даже и сам не знаю. Ещё раз переспрошу, DTO относится к функциональным или нефункциональным требованиям?

Глеб, давай определяйся уже наконец, а то весь этот трёп уже начал утомлять
Если нам не помогут, то мы тоже никого не пощадим.
Re[37]: DTO внутри BusinessObject
От: GlebZ Россия  
Дата: 12.01.07 19:09
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Я не задавал этот вопрос. Мой вопрос был являются ли DTO частью бизнес логики или нет.

GZ>>Ты сам дал ответ.

Бизнес логика в моём понимании — это часть системы, которая занимается реализацией функциональных требований.

GZ>>DTO — это обеспечение operation requirement.

IT>Только что ты говорил, что DTO — это:

IT>

Без изобретения есть функциональные требования, а есть нефункциональные требования. Генерация DTO — обеспечение нефункциональных требований.

IT>
Вообще-то всегда был уверен что нефункциональные требования — являются переводом operation requirement

IT>Я теперь даже и сам не знаю. Ещё раз переспрошу, DTO относится к функциональным или нефункциональным требованиям?

IT>Глеб, давай определяйся уже наконец, а то весь этот трёп уже начал утомлять
Второе. Вроде и не утверждал обратного.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[24]: DTO внутри BusinessObject
От: Mika Soukhov Stock#
Дата: 12.01.07 20:57
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Здравствуйте, Mika Soukhov, Вы писали:


MS>>Количество продуктов узнается перед тем, как делать запрос по выборке этих самых продуктов. Тот же paging работает по схожему методу.

GZ>Это смотря с какой стороны посмотреть. В случае 3-х звенки лучше сразу заказывать количество возвращаемых данных, и чтобы запрос вместе со страницей возвращал общее количество объектов. Потому как иначе нужно будет думать как поведет себя визуалка если между получением количества и получением последней страницы будет вставлен/удален какой-то объект.

IList<Items> GetItems(long ownerId, int pageNumber, int itemsPerPage, out totalCount)


Где здесь DTO и где возникнет ошибка?
Re[32]: DTO внутри BusinessObject
От: akasoft Россия  
Дата: 13.01.07 10:03
Оценка: +1
Здравствуйте, IT, Вы писали:

IT>Дело не в одинаковости моделей. Мы здесь спорим не об этом. Мы пытаемся понять необходимость DTO для переноса данных из одного приложения в другое.


Тогла в Янусе те самые датасеты и есть DTO почти в чистом виде. Наверняка они из чего-то другого собираются на сервере, конечно с учтом параметров, переданных Янусом, и затем по получении в нём переносятся в ЛБД с добавлениями. Напрямую они практически не используются, хотя люську я и прицепил к ним, но это также можно рассматривать как "перенос в ЛБД".

В чём подлог, почему я не с той стороны смотрю и не вижу дыры в архитектуре? Ну да, датасеты можно было заменить коллекциями или массивами, что вроде и попробовали сделать.

Получается, что DTO сделало сайт и Янус менее связными, что позволило развивать их почти независимо друг от дружки. В этом, наверное, смысл. То, что на сервере можно вычислить запросом и не кешировать в Янусе для повышения производительности стали кешировать, как то списки тем. И т.п.
... << RSDN@Home 1.2.0 alpha rev. 672>> SQL Express 2005
Re[33]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 13.01.07 19:30
Оценка: 8 (1)
Здравствуйте, akasoft, Вы писали:

A>Тогла в Янусе те самые датасеты и есть DTO почти в чистом виде.


Датасеты передаются через веб-сервис как xml-структура, которая не опысана в WSDL. Это делает их неприменимыми из других платформ кроме .NET.

A>В чём подлог, почему я не с той стороны смотрю и не вижу дыры в архитектуре? Ну да, датасеты можно было заменить коллекциями или массивами, что вроде и попробовали сделать.


Что значит дыры? Речь идёт о том, что дизайн и имплеинтация сервиса для януса мог бы быть значительно лучше, если бы это учитывалось изначально при разработке сайта. Но в 2000 году об офлай клиенте речи вообще не было. Для нас тогда даже форумы имели второстепенное значение, соответственно и появились они лишь бы было.

A>Получается, что DTO сделало сайт и Янус менее связными, что позволило развивать их почти независимо друг от дружки. В этом, наверное, смысл. То, что на сервере можно вычислить запросом и не кешировать в Янусе для повышения производительности стали кешировать, как то списки тем. И т.п.


Менее связными понятие очень относительное. Например, в несколько таблиц на сервере было добавлены поля timestamp исключительно для поддержки януса. Была добавлена таблица, которая отслеживала изменения/удаления топиков. Без этого нормальная синхронизация януса невозможна. При этом работа с этой таблицой делается в местах, не имеющих к янусу прямого отношения. И как это расценивать, как большую связность или как маленькую?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[38]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 14.01.07 21:03
Оценка: 1 (1)
Здравствуйте, GlebZ, Вы писали:

GZ>Второе. Вроде и не утверждал обратного.


Т.е. необходимость в DTO диктуется нефункциональными требованиями. Другими словами с помощью DTO уменьшается трафик и количество обращений к серверу. Другой пользы от DTO нет.

Но дело в том, что без этой "пользы" легко обойтись, а вместе с "пользой" и без вреда. Например, как выяснилось MaximVK называл DTO классы своей объектной модели клиента. Т.е. он совершенно безболезненно исключил DTO, но продолжил так называть то, что уже DTO не является. DTO как паттерн появился в джаве в бинах из-за каких то там проблем сериализации. Из-за пробем, которых в .NET никогда не было. Фаулер об этом паттерне расказал, забыв при этом упомянуть реальные проблемы, и вот уже все благодарные читатели пихают DTO куда ни попадя или же называют так всё, что уходит за пределы сервера.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[39]: DTO внутри BusinessObject
От: GlebZ Россия  
Дата: 14.01.07 22:18
Оценка:
Здравствуйте, IT, Вы писали:

IT>Т.е. необходимость в DTO диктуется нефункциональными требованиями. Другими словами с помощью DTO уменьшается трафик и количество обращений к серверу. Другой пользы от DTO нет.

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

IT>Но дело в том, что без этой "пользы" легко обойтись, а вместе с "пользой" и без вреда.

Мало того. У меня есть смутное подозрение что в большинстве приложений бизнес-логика так проста, что понятие BE избыточно. А работают с "совокупностью данных заказываемых/полученных клиентом".
IT>Например, как выяснилось MaximVK называл DTO классы своей объектной модели клиента. Т.е. он совершенно безболезненно исключил DTO, но продолжил так называть то, что уже DTO не является.
Честно говоря я сам грешен. Сам из так иногда называю. Не могу подобрать нормального термина под объекты пришедшие с сервера чтобы не путаться.
IT>DTO как паттерн появился в джаве в бинах из-за каких то там проблем сериализации. Из-за пробем, которых в .NET никогда не было.
Не уверен что нету.
IT>Фаулер об этом паттерне расказал, забыв при этом упомянуть реальные проблемы, и вот уже все благодарные читатели пихают DTO куда ни попадя
+1
IT> или же называют так всё, что уходит за пределы сервера.
Мне стыдно, и я промолчу.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[29]: DTO внутри BusinessObject
От: MaximVK Россия  
Дата: 15.01.07 04:02
Оценка: 16 (3)
Здравствуйте, IT, Вы писали:

IT>Ну тогда послушай, что тебе говорят. Все твои опасения напрасны. Минусы у такого подхода конечно есть, но они мизрны по сравнению с теми плюсами, которые он даёт.

Мои опасения — результат практического опыта. Основная проблема таких ошибок — они трудно уловимы, т.к. ислючение не вылетит, а поломается бизнес-логика. Т.к. частично проинициализированный объект ничем не отличается от объекта с такими же пустыми полями. Особенно активно такие ошибки вылазят в процессе поддержки приложения. Когда тут надо что-то подкрутить, там подправить, здесь учесть еще одно требование. Когда программист добавляет один маленький if по какому-то полю в одном из бизнес-компонентов, а потом выясняется, что это поле в 1% случаев бывает непроинициализированным. Твой аргумент "минусы мизерны по сравнению с плюсами" — ну никак не отвечает на вопрос, т.к. неизмерим. А на практике выясняется, что "плюсы" — это быстрое снятие 1% нагрузки на сервер, а "мизерные минусы" — это несколько баг репортов, затертые поля в базе, 3 дня работы саппорта и пара ушедших клиентов. Резюмируя:

1. Ошибки которые влечет такой подход трудно обнаружимы и не покрываются юнит-тестами.
2. Снижается универсальность бизнес-компонент в системе. Т.к. если при условии выполнения правила "все поля проинициализированы" предусловие контракта компонента выглядит как "дайте мне на вход экземпляр класса MyBE", то в случае отказа от этого правила выглядит как "дайте мне на вход экземпляр класса MyBE с проинициализированными полями p1,...pn". Думаю, не нужно пояснять, что контролировать выполнение такого контракта значительно труднее.
3. Снижается устойчивость кода к модификации, т.к. изменения совершаемые на уровне оперирования объектами должны учитывать более низкоуровневые сущности (поля объектов).
4. Попустительствование ошибкам в дизайне, связанным с удовлетворением такого нефункционального требования к системе, как производительность.
5. Усложняется паралельная разработка кода, т.к. увеличивается количество неявных условий, которые должны быть учтены программистом.
6. Усложняется процесс введения в проект новых людей, тоже по причине названной в пункте пять.

IT>Дать определение большого проекта не затруднит?

Большой проект термин, конечно, относительный. Поэтому определения не дам. Я опишу проект в котором эта проблема сказалась. Проект занял 4 года, коллектив рос от 5 до 12 человек(я считаю только программистов). Количество BE в проекте превышает 1000, не считая сторонних SDK, база состоит где-то из 500 таблиц, все это дело крутиться на 9 серверах. Большим проект назвать, конечно, трудно, а маленьким язык тоже не поворачивается.

IT>Тогда вернёмся на несколько постов назад. По-твоему, если у тебя есть объект из 30 полей, но тебе нужно только 5, то ты создаш новый объект. Если же тебе понадобились 6 полей, то ещё один объект, если 6, но других, то по объекту на каждую комбинацию, если 7, то все возможные комбинации и так далее. Я тебя правильно понимаю?


Нет, не правильно. Это крайность, которая, как и любая другая, популярна, потому что избавляет от необходимости думать, утверждая: делай всегда так и будет тебе счастье.
Для принятия правильного решения в твоем примере недостаточно информации. Для полноты картины нужно знать:
1. Процент таких случаев от общего числа использования объекта или более полно — статистика использования полей объекта на достаточно протяженном интервале работы системы.
2. Контекст использования объекта(см. мой пример с гридом).
3. Статистика распределения данных по полям объекта. Упрощенно говоря, может выясниться, что в 99% случаев использования объекта нужно поле, вес которого составляет 99% от всех данных в объекте.
Но, даже обладая такой информацией у тебя не будет формализованного механизма принятия решения(хотя его можно значительно упростить). Нахождение удачного решения — задача проектировщика и насколько успешно он с ней справиться зависит от его опыта и таланта.

Я отмечу несколько полезных, с моей точки зрения, моментов/правил при разработке классов BE которые я учитываю:
1. Есть такой эмпирический факт, что в подавляющем большинстве случаев 90% данных находяться в 10% полей класса.
2. На этапе проектирования можно выделять особо жирные поля в отдельные классы. Например, в классах часто встречается поле Description, которое весит в десятки или сотни раз больше чем все остальные поля класса вместе взятые. Скорее всего, этот самый Descrption будет востребован лишь когда его будет редактировать/просматривать пользователь. Создайте отдельный класс для таких desciption-ов и вместо поля string в BE используйте его.
3. По возможности избегать создания классов с большим количеством полей.
4. Если есть плоский класс с большим количеством полей, то имеет смысл его отрефакторить и сделать композитным. Наиболее часто используемые поля оставить в самом классе, а остальные поля разбить на группы и вынести в другие классы.
5. Используйте или напишите средство профилирования, которое позволит оценить как часто и какие группы полей используются для каждой BE. В каком контексте они используются. Эти данные позволяют обоснованно(sic!) принять решение о необходимости рефакторинга кода.
6. Ну и уже заезженное правило, не оптимизировать пока не появиться в этом необходимость.


IT>Так в чём проблема? Если речь идёт о большом проекте, то сопроводи свой метод спецификаций.

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

IT>Блин, ну вот опять начинается Как же они не принимают участие во внутренних процессах, если задача внутренных процессов как раз и заключается в том, чтобы создать структуру из таких объектов и вернуть её клиенту. Это и есть работа этих самых внутренных процессов.

IT>Эти изменения прежде всего неразрывно связаны с изменением логики работы сервера.

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

IT>И почему же они тогда не разделены?

Где они не разделены?


P.S. Напоследок позволю себе небольшую аналогию, раз уж в топике поднялся вопрос о функциональных и нефункциональных требованиях. Я думаю, многим доводилось крутить в руках деталь какого-нибудь хитрого механизма. Эта деталь может иметь какую-нибудь загогулистую форму, а ее назначение, скажем, хитро передавать вращательный момент. "Хитро передавать вращательный момент" — это функциональные требования к этой детали и ее форма определяется именно им. Если расмотреть деталь поближе, то выясняется что она композитна и состоит из каких-то дополнительных втулок, хомутов и т.д. На первый взгляд, необходимости в этих сложностях нет, можно было отлить все единой загогулиной. Но если присмотреться, то выясняется, что эти самые втулки, хомуты, прокладки находяться в местах повышенного трения или усиленной нагрузки. Сделано это с целью удовлетворения уже нефункциональных требований: износостойкость, ремонтопригодность, надежность. Замечу, что необходимость многих этих втулок выяснилась уже в ходе эксплуатации механизма, т.к. при первичном проектировании все учесть крайне тяжело. В проектировании классов наших BE фактически все тоже самое. Первоначально класс появляется в результате анализа функциональных требований. Это может быть обыкновенный плоский класс из 20 полей. В дальнейшем этот класс может быть разбит на несколько классов, у него появяться дополнительные поля, а некоторые поля будут сгруппированы в новые классы. Все эти изменения произойдут с целью удовлетворения нефункциональных требований и необходимость многих из них выяснится только в ходе эксплуатации системы.
Re[30]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 15.01.07 05:53
Оценка:
Здравствуйте, MaximVK, Вы писали:

MVK> Мои опасения — результат практического опыта. Основная проблема таких ошибок — они трудно уловимы, т.к. ислючение не вылетит, а поломается бизнес-логика. Т.к. частично проинициализированный объект ничем не отличается от объекта с такими же пустыми полями. Особенно активно такие ошибки вылазят в процессе поддержки приложения. Когда тут надо что-то подкрутить, там подправить, здесь учесть еще одно требование. Когда программист добавляет один маленький if по какому-то полю в одном из бизнес-компонентов, а потом выясняется, что это поле в 1% случаев бывает непроинициализированным. Твой аргумент "минусы мизерны по сравнению с плюсами" — ну никак не отвечает на вопрос, т.к. неизмерим. А на практике выясняется, что "плюсы" — это быстрое снятие 1% нагрузки на сервер,


1% нагрузки, даже 5% лично меня вообще не волнуют. Если бороться, то за минимум за 20. Плюсы — это maintenance. Если у меня одно представление данных, то мне нужно сопровождать ровно одно, если у меня их пять, то работы будет в пять раз больше.

MVK>а "мизерные минусы" — это несколько баг репортов, затертые поля в базе, 3 дня работы саппорта и пара ушедших клиентов.


Давай я тебе другую страшилку расскажу. Предположим у тебя не одно представление данных, а несколько. В процессе разработки поменялся тип, имя поля, размерность, правило валидации или что-то ещё. Изменение должен сделать программист, которые не очень осведомлён о всех представлениях одной и той же сущности. А теперь страшилка:

Мои опасения — результат практического опыта. Основная проблема таких ошибок — они трудно уловимы, т.к. ислючение не вылетит, а поломается бизнес-логика. Т.к. частично проинициализированный объект ничем не отличается от объекта с такими же пустыми полями. Особенно активно такие ошибки вылазят в процессе поддержки приложения. Когда тут надо что-то подкрутить, там подправить, здесь учесть еще одно требование. Когда программист добавляет один маленький if по какому-то полю в одном из бизнес-компонентов, а потом выясняется, что это поле в 1% случаев бывает непроинициализированным.

Твои слова один в один применимы к данной ситуации.

Забытый класс гораздо труднее найти, особенно, если он писался не тобой. В этом случае ты фактически вообще без понятия есть ли ещё какие-либо представления тех же самых данных в программе. На сегодняшний день мы имеем два места в коде, где у нас полностью отсутствует типизация и можно полагаться только на себя — это DAL и баиндинг типов на формы. Первое возможно в скором времени можно будет решить с помощью метапрограммирования, со вторым пока сложнее. Так вот, увеличивая количество типов в программе, связанных с этими вещами ты пропорционально увеличиваешь проблемы при сопровождении.

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

MVK>Резюмируя:


MVK>1. Ошибки которые влечет такой подход трудно обнаружимы и не покрываются юнит-тестами.


Обнаруживаются элементарно даже если тестируются сценарии.

MVK>2. Снижается универсальность бизнес-компонент в системе. Т.к. если при условии выполнения правила "все поля проинициализированы" предусловие контракта компонента выглядит как "дайте мне на вход экземпляр класса MyBE", то в случае отказа от этого правила выглядит как "дайте мне на вход экземпляр класса MyBE с проинициализированными полями p1,...pn". Думаю, не нужно пояснять, что контролировать выполнение такого контракта значительно труднее.


Это выглядит как дайте мне данные и никак иначе. Добавление нового и изменение старого функционала должно вообще-то хотя бы как-нибудь тестироваться. Проблемы, о которых ты говоришь вылезут моментально. Но скорее всего ничего не случится, т.к. добавление нового поля в сущность не ломает старого кода.

MVK>3. Снижается устойчивость кода к модификации, т.к. изменения совершаемые на уровне оперирования объектами должны учитывать более низкоуровневые сущности (поля объектов).


Этого утверждения не понял.

MVK>4. Попустительствование ошибкам в дизайне, связанным с удовлетворением такого нефункционального требования к системе, как производительность.


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

MVK>5. Усложняется паралельная разработка кода, т.к. увеличивается количество неявных условий, которые должны быть учтены программистом.

MVK>6. Усложняется процесс введения в проект новых людей, тоже по причине названной в пункте пять.

Это всё ерунда, по сравнению с введением новых типов на каждый чих.

IT>>Тогда вернёмся на несколько постов назад. По-твоему, если у тебя есть объект из 30 полей, но тебе нужно только 5, то ты создаш новый объект. Если же тебе понадобились 6 полей, то ещё один объект, если 6, но других, то по объекту на каждую комбинацию, если 7, то все возможные комбинации и так далее. Я тебя правильно понимаю?


MVK>Нет, не правильно. Это крайность, которая, как и любая другая, популярна, потому что избавляет от необходимости думать, утверждая: делай всегда так и будет тебе счастье.


Т.е. в некоторых случаях ты всё же добавишь поле вместо создания нового типа

MVK>Для принятия правильного решения в твоем примере недостаточно информации. Для полноты картины нужно знать:

MVK>1. Процент таких случаев от общего числа использования объекта или более полно — статистика использования полей объекта на достаточно протяженном интервале работы системы.

Случаи всегда возникают по одному. Второй всегда возникает после первого, третий после второго. Сколько их будет никому заранее не известно. А если бы было известно, то это надо бы было заранее учитывать в дизайне.

MVK>2. Контекст использования объекта(см. мой пример с гридом).

MVK>3. Статистика распределения данных по полям объекта. Упрощенно говоря, может выясниться, что в 99% случаев использования объекта нужно поле, вес которого составляет 99% от всех данных в объекте.
MVK>Но, даже обладая такой информацией у тебя не будет формализованного механизма принятия решения(хотя его можно значительно упростить). Нахождение удачного решения — задача проектировщика и насколько успешно он с ней справиться зависит от его опыта и таланта.

Проектировщик не всегда обладает всей информацией. Точнее почти всегда ей не обладает. Дизайн системы не только должен удовлетворять текущим функциональным требованиям, но и быть готовым к добавлению новых и изменению существующих. Обилие типов в системе вовсе не способствует этому требованию.

MVK>Я отмечу несколько полезных, с моей точки зрения, моментов/правил при разработке классов BE которые я учитываю:

MVK>1. Есть такой эмпирический факт, что в подавляющем большинстве случаев 90% данных находяться в 10% полей класса.
MVK>2. На этапе проектирования можно выделять особо жирные поля в отдельные классы. Например, в классах часто встречается поле Description, которое весит в десятки или сотни раз больше чем все остальные поля класса вместе взятые. Скорее всего, этот самый Descrption будет востребован лишь когда его будет редактировать/просматривать пользователь. Создайте отдельный класс для таких desciption-ов и вместо поля string в BE используйте его.
MVK>3. По возможности избегать создания классов с большим количеством полей.
MVK>4. Если есть плоский класс с большим количеством полей, то имеет смысл его отрефакторить и сделать композитным. Наиболее часто используемые поля оставить в самом классе, а остальные поля разбить на группы и вынести в другие классы.
MVK>5. Используйте или напишите средство профилирования, которое позволит оценить как часто и какие группы полей используются для каждой BE. В каком контексте они используются. Эти данные позволяют обоснованно(sic!) принять решение о необходимости рефакторинга кода.
MVK>6. Ну и уже заезженное правило, не оптимизировать пока не появиться в этом необходимость.

Всё это лишь способстует увеличению количества типов в системе, что само по себе есть зло. Да и не понимаю я, зачем мне разбивать сущность на три типа, если они никогда не используются раздельно. Глупости это всё. Хотя если вам платят за строчки кода, то why бы и not.

IT>>Так в чём проблема? Если речь идёт о большом проекте, то сопроводи свой метод спецификаций.

MVK>Если мы говорим о внешнем API — то это само-собой разумеющийся факт. А вот для кода внутри системы — это ничего не даст, все равно придется анализировать цепочку возможных вызовов. Я правлю какой-нить метод бизнес логики который получает на вход BE. В результате правки в методе используется на одно поле этой BE больше. Следуя твоей логике, я должен просмотреть все цепочки вызовов этого метода от момента создания и инициализации BE. После чего прочитать спецификацию по методам инициализации.

Ну откуда я знаю? Приводи код будем разбираться что с ним делать.

IT>>Блин, ну вот опять начинается Как же они не принимают участие во внутренних процессах, если задача внутренных процессов как раз и заключается в том, чтобы создать структуру из таких объектов и вернуть её клиенту. Это и есть работа этих самых внутренных процессов.

IT>>Эти изменения прежде всего неразрывно связаны с изменением логики работы сервера.

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


И в чём проблема?

IT>>И почему же они тогда не разделены?

MVK>Где они не разделены?

Да, где?

MVK>В проектировании классов наших BE фактически все тоже самое. Первоначально класс появляется в результате анализа функциональных требований. Это может быть обыкновенный плоский класс из 20 полей. В дальнейшем этот класс может быть разбит на несколько классов, у него появяться дополнительные поля, а некоторые поля будут сгруппированы в новые классы. Все эти изменения произойдут с целью удовлетворения нефункциональных требований и необходимость многих из них выяснится только в ходе эксплуатации системы.


Такая необходимость возникает крайне редко и связана она в основном, простите за каламбур, со связями внутри объекта, которые пораждаются обилием и разнообразием типов в приложении. Меньше типов — меньше связности. Добавление одного поля — это детский сад по сравнению с добавлением новго типа.

ЗЫ. Впрочем, мы уже отвлеклись от заданной темы. DTO к этому отношения не имеет. Добавление поля vs. добавление типа это уже совсем другая история. И если я категорически против DTO, то добавление нового типа, в случае необходимости, не считаю жутким преступлением.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[34]: DTO внутри BusinessObject
От: Blazkowicz Россия  
Дата: 15.01.07 10:38
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Нет. И к тому же это чаще просто невозможно сделать. Зависимости всегда остаются. Вызовы только с одной стороны можно сделать. Но изменение кода на одном слое могут выливаться изменения на соседних слоях.


Зависимости остаются, но они должны быть односторонними. Ты же выше сказал "зависят друг от друга", что подразумевает двухстороннюю зависимость и не есть хорошо.
Re[31]: DTO внутри BusinessObject
От: MaximVK Россия  
Дата: 15.01.07 12:15
Оценка:
Здравствуйте, IT, Вы писали:

Видимо происходит некоторое непонимание. Есть единственный случай, когда я считаю разумным дублирование полей в новых сущностях — это опять же мой пример с гридом. Т.е. классов, которые, фактически, эквиваленты view в базе данных. Я против создания классов вида MyClassView1, MyClassView2 и т.д. которые будут описывать разные наборы полей одного и того же класса MyClass — т.к. это действительно увеличивает сложность. Я утверждаю, что при грамотном подходе частичной загрузки объекта можно избежать через разбиение (а не создание различных представлений) класса на несколько и использовании композита. Т.е. был MyClass с 30 полями, а стал скажем класс MyClass c 12 полями из которых два MyClassPart1 и MyClassPart2 содержат остальные поля. Более того, частичная загрузка до того простой механизм, что им пользуются даже не особо задумываясь — даст ли это хоть какое-то преимущество.

IT>Давай я тебе другую страшилку расскажу. Предположим у тебя не одно представление данных, а несколько. В процессе разработки поменялся тип, имя поля, размерность, правило валидации или что-то ещё. Изменение должен сделать программист, которые не очень осведомлён о всех представлениях одной и той же сущности. А теперь страшилка:


Как я говорил выше, я против нескольких представлений одной и той же сущности. Исключение составляет опять же случай с гридом. В случае создания такого класса на него налагаются достаточно строгие ограничения, в частности для него нет стандартного набора CRUD операций в DAL, его можно только прочитать.

IT>Твои сопровождения тоже справедливы, но они не так страшны. Попробуй добавить ещё одно поле в любой из своих типов и ты увидишь, что не изменилось ровным счётом ничего. Вообще ничего. А теперь попробуй переименовать одно поле в базе данных и сравни количество работы, необходимой для корректировки этого изменения по всему коду для одного типа данных и, например, для пяти.

Опять же в свете сказанного выше такая проблема не возникнет.

IT>Обнаруживаются элементарно даже если тестируются сценарии.

IT>Это выглядит как дайте мне данные и никак иначе. Добавление нового и изменение старого функционала должно вообще-то хотя бы как-нибудь тестироваться. Проблемы, о которых ты говоришь вылезут моментально. Но скорее всего ничего не случится, т.к. добавление нового поля в сущность не ломает старого кода.

Определенно, такой код сложнее поддается тестированию.

MVK>>3. Снижается устойчивость кода к модификации, т.к. изменения совершаемые на уровне оперирования объектами должны учитывать более низкоуровневые сущности (поля объектов).

IT>Этого утверждения не понял.
Следуя правилу "все поля объекта должны быть загружены" я могу оперировать объектами, забыв о полях. А ты фактически оперируешь группами полей, хотя передаешь везде объекты.

IT>При чём тут производительность тоже не понял.

Частичная загрузка объектов призвана снизить нагрузку на сервер с целью увеличения производительности. Необходимость частичной загрузки может быть вызвана кривизной дизайна класса (ну скажем, в классе Order поля отвечающие за доставку заказа не выделены в отдельный класс), но вместо того чтобы правильно перепроектировать класс мы заткнем проблему частичной загрузкой.

IT>Т.е. в некоторых случаях ты всё же добавишь поле вместо создания нового типа

Разумеется.

IT>Случаи всегда возникают по одному. Второй всегда возникает после первого, третий после второго. Сколько их будет никому заранее не известно. А если бы было известно, то это надо бы было заранее учитывать в дизайне.

Это верно и для частичной загрузки класса за исключением дизайна.

IT>Проектировщик не всегда обладает всей информацией. Точнее почти всегда ей не обладает. Дизайн системы не только должен удовлетворять текущим функциональным требованиям, но и быть готовым к добавлению новых и изменению существующих. Обилие типов в системе вовсе не способствует этому требованию.


На самом деле количество типов в системе не так сильно увеличивается. Ну было 100, стало 120-130. Наиболее жирные классы представлены как композиты. Для наиболее жирных полей(аля Description) определены свои типы и унифицированы механизмы работы с такими типами. При этом выделения нескольких полей класса ClassA в новый класс ClassB приводит лишь к появлению связи класса ClassB с классом ClassA.

IT>Всё это лишь способстует увеличению количества типов в системе, что само по себе есть зло. Да и не понимаю я, зачем мне разбивать сущность на три типа, если они никогда не используются раздельно. Глупости это всё. Хотя если вам платят за строчки кода, то why бы и not.

Если никогда не используется раздельно — то и не надо

IT>Такая необходимость возникает крайне редко и связана она в основном, простите за каламбур, со связями внутри объекта, которые пораждаются обилием и разнообразием типов в приложении. Меньше типов — меньше связности. Добавление одного поля — это детский сад по сравнению с добавлением новго типа.

Я не согласен с "меньше типов лучше". Мы же разносим по каким-то загадочным причинам тип Address и тип Order, создавая в Order-e поле ShippingAddress типа Address. Появление нового типа должно быть обоснованным. Я считаю, что первичное выделение типов основывается на анализе функциональных требований к системе и предметной области, а затем еще раз, но уже основанное на анализе нефункциональных требований.


IT>ЗЫ. Впрочем, мы уже отвлеклись от заданной темы. DTO к этому отношения не имеет. Добавление поля vs. добавление типа это уже совсем другая история. И если я категорически против DTO, то добавление нового типа, в случае необходимости, не считаю жутким преступлением.


Да, согласен. Тем не менее беседа получилась для меня познавательная
Re[35]: DTO внутри BusinessObject
От: GlebZ Россия  
Дата: 15.01.07 13:27
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Зависимости остаются, но они должны быть односторонними. Ты же выше сказал "зависят друг от друга", что подразумевает двухстороннюю зависимость и не есть хорошо.

Хоть не всегда получается как хотелось бы, но в принципе ты прав.
Re[34]: DTO внутри BusinessObject
От: akasoft Россия  
Дата: 15.01.07 19:06
Оценка:
Здравствуйте, IT, Вы писали:

IT>Датасеты передаются через веб-сервис как xml-структура, которая не опысана в WSDL. Это делает их неприменимыми из других платформ кроме .NET.


Почему? Можно же парсить вручную. Впрочем, это не та тема.

IT>Что значит дыры?


Ну, я так понял, что ты утверждаешь
Автор: IT
Дата: 09.01.07
, что ДТО обычно используется для затыкания дыр в архитектуре. Вот, я её не вижу. Потому интересуюсь, куда глядеть, чтобы увидеть то же, что и ты.

IT> Речь идёт о том, что дизайн и имплеинтация сервиса для януса мог бы быть значительно лучше, если бы это учитывалось изначально при разработке сайта. Но в 2000 году об офлай клиенте речи вообще не было.


Это понятно.

IT>Менее связными понятие очень относительное. Например, в несколько таблиц на сервере было добавлены поля timestamp исключительно для поддержки януса. Была добавлена таблица, которая отслеживала изменения/удаления топиков. Без этого нормальная синхронизация януса невозможна. При этом работа с этой таблицой делается в местах, не имеющих к янусу прямого отношения.


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

Ну и кроме того, разве система отслеживания изменений в сообщениях не нужна для вебинтерфейса и, в частности, для модерирования/администрирования? Ведь без надлежащего учёта будет бардак.

IT> И как это расценивать, как большую связность или как маленькую?


Есть система со своим движком форумов. Она предоставляет вебслужбу (контракт) для удалёного взимодействия с собой. Есть Янус, который этот контракт использует. Развитие обоих взаимодействующих по контракту частей может идти и без учёта друг дружки, но при условии соблюдения контракта.

Связность имеет место быть. Сильная она или слабая? А вот шут его. Я ещё путаюсь в терминологии. Хотел с твоей помощью разобраться.

Если при изменениях (сервера, Януса) не затрагивается контракт, то зависимость слабая. Если же изменения требуют больших затрат на приведение кода в соответсвие контрату, то зависимость сильная.

У меня логическое (или терминологическое) противоречие. Помоги разрешить.
... << RSDN@Home 1.2.0 alpha rev. 672>> SQL Express 2005
Re[35]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 16.01.07 01:22
Оценка: 94 (8)
Здравствуйте, akasoft, Вы писали:

IT>>Датасеты передаются через веб-сервис как xml-структура, которая не опысана в WSDL. Это делает их неприменимыми из других платформ кроме .NET.

A>Почему? Можно же парсить вручную. Впрочем, это не та тема.

Как минимум это косяк.

IT>>Что значит дыры?


A>Ну, я так понял, что ты утверждаешь
Автор: IT
Дата: 09.01.07
, что ДТО обычно используется для затыкания дыр в архитектуре. Вот, я её не вижу. Потому интересуюсь, куда глядеть, чтобы увидеть то же, что и ты.


В этом смысле? Насколько мне известно, в янусе используются нетипизированные датасеты, что уже само по себе дырка в дизайне. На сервере сервис не следует простейшим правилам разбиения на слои, маппинг делается в ручную. На клиенте маппинг тоже делается в ручную. Но всё это, ещё раз повторяю, ни в коем случае не умоляет заслуг разработчиков. Просто это всё писалось давным давно. А сегодня вполне можно было бы задизайнить всё так, что бы и на сервере и на клиенте код методов сервиса и сохранение этого дела на клиенте занимало бы по паре строк.

A>Ты мне расказываешь про развитие, как принято говорить, "движка форума". Само собой появившияся Янус потребовал учитывать свой собственный минимальный набор, при котором ещё возможно его функционирование. Но ведь Янус не мог появится без этого минимума в принципе. А в пределах контракта сервер и клиент (Янус) могли развиваться неортогонально друг другу.


Против это никто не возражает, пусть себе развиваются. Только вот без изменения сервера работа януса была бы не возможна в принципе. Т.е. любая независимость весьма условная вещь. А раз так, то нет никакого смысла бороться за эту независимость изо всех сил. Если что-то проще и эффективнее сделать для януса на сервере, то это надо делать на сервере. Об этом я и говорю.

A>Ну и кроме того, разве система отслеживания изменений в сообщениях не нужна для вебинтерфейса и, в частности, для модерирования/администрирования? Ведь без надлежащего учёта будет бардак.


В существующей архитектуре не нужна. Зато для веба нужен пейджинг почти для всех методов. Для януса не нужен, а для веба нужен. Это опять к слову о независимости клиентов от сервера.

IT>> И как это расценивать, как большую связность или как маленькую?


A>Есть система со своим движком форумов. Она предоставляет вебслужбу (контракт) для удалёного взимодействия с собой. Есть Янус, который этот контракт использует. Развитие обоих взаимодействующих по контракту частей может идти и без учёта друг дружки, но при условии соблюдения контракта.


У нас не стоит задачи предоставить вебслужбу (контракт) для удалённого взаимодействия с собой. У нас стоит задача обеспечить соответствующими сервисами янус, веб и NNTP клиентов. Контракт — это очень здорово, это позволяет максимально изолировать различные части системы друг от друга. Мне это всё очень нравится как правильный паттерн и хороший инструмент для достижения обеспечения более простого сопровождения. Но при всём при этом это всего лишь инструмент и относится к нему нужно соответственно.

A>Связность имеет место быть. Сильная она или слабая? А вот шут его. Я ещё путаюсь в терминологии. Хотел с твоей помощью разобраться.


A>Если при изменениях (сервера, Януса) не затрагивается контракт, то зависимость слабая. Если же изменения требуют больших затрат на приведение кода в соответсвие контрату, то зависимость сильная.


A>У меня логическое (или терминологическое) противоречие. Помоги разрешить.


Я думаю, что у тебя наблюдается некоторая путаница с системой твоих приоритетов. Это потребует некоторого объяснения. Я уже много раз об этом безуспешно говорил, например, здесь
Автор: IT
Дата: 10.11.05
, здесь
Автор: IT
Дата: 21.08.06
, здесь
Автор: IT
Дата: 07.05.05
. Но можно попробовать ещё раз

Итак, проблема в том, что нам постоянно, решая те или иные задачи, приходится выбирать между двумя или более решениями. Чаще всего этот выбор тривиален, иногда довольно труден, а порой вообще невозможно спрогнозировать к чему приведёт то или иное решение. Всё это усугубляется ещё и тем, что одно и тоже решение в разных ситуациях может оказаться как плохим так и хорошим. Однажды мне всё это надоело и я разработал для себя набор простых правил, которые в 99% случаев позволяют быстро принять более менее адекватное решение. А так же уже после принятия какого-либо решения при изменении определённых условий с чистой совестью "поступиться принципами", отменить ранее принятое решение и принять другое.

Базируется это хозяйство на очень простой системе приоритетов и разрешения противоречий. Список приоритетов у меня такой:

1. Функциональные требования.
2. Нефункциональные требования.
3. Сопровождаемость системы.

Это наши цели. Всё остальное должно быть подчинено достижению этих целей. Заметь, у меня нет в этом списке паттернов, контрактов, строгости объектной модели и прочего. Нет, потому что это не является целью, это всего лишь инструменты достижения наших целей. А инструментов, чем их больше и они разнообразнее, тем всегда лучше. Но они никогда не должны становится выше целей. Это очень важное правило и очень важно его понимать.

Противоречия разрешаются очень просто. Если решение не противоречит первому пункту, то проверяется непротиворечивасть со вторым. Если решение не противоречит второму, то должно строго следовать третьему. Неудовлетворение первого пункта может быть обусловлено только соображениями нецелесообразности. В этом случае вообще ничего не делается.

Что это значит? Это значит, что наша главная задача — это реализация функционала. Не создание объектной модели, не определение контракта, не использование паттернов, а реализация функционала. Если у нас есть какой-то контракт и для добавления нового функционала его нужно изменить или переделать, то его нужно изменить или переделать. Вообще, неследование этому правилу очень часто наблюдается у молодёжи. Зачастую паттерны, polymorphic behaviour, контракты, структура базы данных или объектной модели и т.п. ставятся выше главных целей, выше разработки функциональности системы. В результате функционал начинает подгоняться под контракты и модели, что в свою очередь ведёт к краху. Типичная подмена целей и приоритетов.

Наша вторая задача — обеспечение приемлемой работоспособности системы. Т.е., если для реализации нового функционала наш контракт можно не менять и не переделывать, но система будет работать существенно медленнее, то контракт нужно изменить или переделать. Справедливо и обратное. Если добавление фичи на скорость не влияет, то не надо заниматься ненужной оптимизацией. Это практически в ста процентах случаев повредит следующему пункту.

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

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

Возникает вопрос, а бывают ли исключения? Нет, исключений не бывает. Бывает переход задач в категорию функциональных / нефункциональных требований. Например, в некоторых системах публичный контракт является тем, для чего собственно сама система и делается. Тогда контракт со всеми вытекающими последствиями переводится в разряд функциональных требований и ему начинает подчиняться всё остальное. Бывает, когда чистота и непротиворечивость объектной модели становятся так же функциональным требованием. Возьмём к примеру .NET Framework или любые другие публичные библиотеки. В таких случаях, к объектным моделям и интрефейсам предъявляются особые требованмя. Например, для обеспечения согласованности объектной модели в .NET в своё время в MS была организована целая группа, главной задачей которой была разработка рекомендаций и обеспечение надзора за соблюдением требованмй к публичным интерфейсам.

Очевидно, что в твоём случае ты не можешь определиться с тем, как ты позиционируешь для себя веб-сервис януса. Является ли он для тебя чем-то вроде функциональных требований или нет. Лично для меня он таковым не является. Для меня это всего лишь инструмент для достижения необходимой функциональности. А раз так, то я не вижу большого смысла с ним церемониться. Я за то, чтобы контракт был, чтобы он был продуман и удобен в использовании, но это для меня не главный приоритет, это лишь следствие из моих правил, и до тех пор пока оно не противоречит самим правилам, я буду ему следовать, но принесу его в жертву более приоритетным вещам не задумываясь. Если же ты, например, решишь для себя, что веб-сервим януса должен быть вынесен на уровень функциональных требований, то нам с тобой договариваться о деталях уже не будет иметь никакого смысла. Бесполезно спорить о мелочах, не договорившись о главных приоритетах. Если же ты решишь наоборот, то очень скоро увидишь, что гораздо важнее не сам по себе контракт, а простота сопровождения интерфеса между сервером и янусом.

Вот такой набор правил. Пожалуй главное, что он мне даёт — это возможность быстро принимать решения и также быстро от них отказываться и принимать другие, наиболее подходящие, если меняются требования или появляется дополнительная информация. Это не значит, что я вот такой непостоянный. Это значит, что у меня нет идолов в коробке с инструментами, моя главная и единственная задача — написать требуемый функционал, который бы хорошо работал и который было бы легко сопровождать. И этому всё подчинено.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[31]: DTO внутри BusinessObject
От: Gollum Россия  
Дата: 16.01.07 07:21
Оценка: 8 (1) :)
Здравствуйте, IT, Вы писали:

IT>Всё это лишь способстует увеличению количества типов в системе, что само по себе есть зло. Да и не понимаю я, зачем мне разбивать сущность на три типа, если они никогда не используются раздельно. Глупости это всё. Хотя если вам платят за строчки кода, то why бы и not.


Читаю я тут все это, читаю... По-моему, тут просто терминологическая путаница. Сам же писал
Автор: IT
Дата: 06.09.06
, еще недавно:

Бизнес сущности, они же Domain Entities, они же Data Transfer Objects (DTO).


Видимо конечно правильно определять DTO как сущности, введенные только для того, чтобы передавать данные. Но вот я лично до того как прочел эту дискуссию считал BE и DTO синонимами По-моему отсюда и происходит путаница, ты говоришь про одно, а твои собеседники про другое.
Скорость перебора паролей прямо пропорциональна квадрату температуры утюга...
Eugene Agafonov on the .NET

Re[32]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 16.01.07 15:01
Оценка:
Здравствуйте, Gollum, Вы писали:

G>Читаю я тут все это, читаю... По-моему, тут просто терминологическая путаница.


100%. При чём, заметь, я постоянно пытаюсь уточнить что я под этим понимаю.

Сам же писал
Автор: IT
Дата: 06.09.06
, еще недавно:

G>

Бизнес сущности, они же Domain Entities, они же Data Transfer Objects (DTO).


Когда я это писал ещё не все дочитали до конца Фаулера.

G>Видимо конечно правильно определять DTO как сущности, введенные только для того, чтобы передавать данные. Но вот я лично до того как прочел эту дискуссию считал BE и DTO синонимами По-моему отсюда и происходит путаница, ты говоришь про одно, а твои собеседники про другое.


Посмотри на название топика. Как ты думаешь, что оно означает? Из-за этого я и завёлся. А потом уже началась неразбериха с терминологией.
Если нам не помогут, то мы тоже никого не пощадим.
Re[33]: DTO внутри BusinessObject
От: Mika Soukhov Stock#
Дата: 16.01.07 15:22
Оценка:
Здравствуйте, IT, Вы писали:

IT>Сам же писал
Автор: IT
Дата: 06.09.06
, еще недавно:


G>>

Бизнес сущности, они же Domain Entities, они же Data Transfer Objects (DTO).


IT>Когда я это писал ещё не все дочитали до конца Фаулера.


Сейчас-то дочитал до конца?
Re[34]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 16.01.07 16:03
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

IT>>Когда я это писал ещё не все дочитали до конца Фаулера.


MS>Сейчас-то дочитал до конца?


Типа подколол, молодец, смешно.

Фаулер, конечно, грамотный мужик, но его всегда выдавало его джавовское прошлое. Лучше читать майкрософтовские практики, особенно ранние. Они и появились раньше и чуши типа DTO в них поначалу не было.
Если нам не помогут, то мы тоже никого не пощадим.
Re[35]: DTO внутри BusinessObject
От: Mika Soukhov Stock#
Дата: 16.01.07 16:32
Оценка:
Здравствуйте, IT, Вы писали:

IT>Фаулер, конечно, грамотный мужик, но его всегда выдавало его джавовское прошлое.


На архитектуру это не особо влияет. Мне больше мелкие моменты у него не нравились, да и все, что связано с Remote Interfaces.

IT>Лучше читать майкрософтовские практики, особенно ранние. Они и появились раньше и чуши типа DTO в них поначалу не было.


Тут тоже не все так гладко. В начале практики напирали на ООП подход, затем на сервисный. + для меня была в свое время путаница с оракловой терминологией (у них есть свой СОА).

Фаулер все же более понятливый автор. Не боится засучить рукава, и полезть разгребать. Плюс обилие примеров помогает легче понять, нежели тот же практик от МС, где демо идет в конце, а не поэтапно.
Re[36]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 16.01.07 16:55
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

IT>>Фаулер, конечно, грамотный мужик, но его всегда выдавало его джавовское прошлое.


MS>На архитектуру это не особо влияет.


На архитектуру влияет всё и уж тем более платформа. Другое дело, что у .NET и джавы много общего, больше, например, чем у .NET и COM. Но разница есть и уши местами торчат.

MS>Фаулер все же более понятливый автор. Не боится засучить рукава, и полезть разгребать. Плюс обилие примеров помогает легче понять, нежели тот же практик от МС, где демо идет в конце, а не поэтапно.


Мне у него больше всего нравятся определения. То же определение архитектуры — кратко, ёмко и удивительно точно.
Если нам не помогут, то мы тоже никого не пощадим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.