Re[2]: DTO внутри BusinessObject
От: Аноним  
Дата: 23.01.07 12:55
Оценка: :))) :))
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, снежок, Вы писали:


С>>Суть в том чтобы все get-ы и set-ы BO работали с DTO, а не приватными мемберами соответствующих свойств BO.


IT>Я вот никогда не понимал, в чём вообще смысл разделения на DTO и BO? Потому что Фаулер так сказал?


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

Если польза от разделения BO и BL вам не ясна — значит небыло еще в вашей жизни проекта, где такое разделение было бы критическим.
Re[3]: DTO внутри BusinessObject
От: Blazkowicz Россия  
Дата: 23.01.07 12:57
Оценка:
Здравствуйте, Аноним, Вы писали:

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


Вы с DAO не путаете?

А>Если польза от разделения BO и BL вам не ясна — значит небыло еще в вашей жизни проекта, где такое разделение было бы критическим.


А в чьей-то жизни такой проект был? Если в Вашей, то может поделитесь опытом откуда критичность возникла?
Re[3]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 23.01.07 14:14
Оценка: :))
Здравствуйте, <Аноним>, Вы писали:

А>DTO — инкапсуляция работы с бд.,


Надо же, я всегда думал, что это называется DAL. Оказывается это тоже называется DTO. Буду знать.

А>Если польза от разделения BO и BL вам не ясна — значит небыло еще в вашей жизни проекта, где такое разделение было бы критическим.


Простите, был не прав.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[46]: DTO внутри BusinessObject
От: GlebZ Россия  
Дата: 25.01.07 07:41
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Гораздо хуже, если бы он делал быстро, но не то, что нужно.

GZ>>Вот для этого и стоит определять что нам нужно быстро делать, что не столь важно, а на что вообще не стоит обращать внимание и бить разрабочика по ковырялкам если его заносит.
IT>И в чём проблема? Мы же вроде как говорим о приоритетности одних требований над другими
Разница в том, что ты говоришь о некой приоритетности функциональных над нефункциональными требованиями. Я утверждаю, что важность требований не зависит от того — функциональное или нефункциональное оно.

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

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

GZ>>

Функциональные требования — это достаточно строгая конструкция которая определяет сценарии/действия пользователя.

IT>Это примерно тоже самое, что "Функциональное требование — это предложение, записанное на бумаге". В таком смысле да, это строгая конструкция. Но любые функциональные требования базируются на предпочтениях человека их составялющих, а значит не могут быть чётко категоризированы.
Однако предпочтения клиента/аналитика точны и достаточны чтобы их точно выполнять. Мне как разработчику на это наплевать.

IT>К каким, например, категориям относятся требования к тёплости и мякгости?

А могут быть такие требования?

GZ>>Нефункциональные требования — все остальные требования к программе.

IT>А как же концептуальные требования?
А что концепция? Концептуальные документы показывают нужность программы, ее абстактные цели, ограничивают задачу рамками. При разработке

IT>>>Например, сопровождаемость.

GZ>>Сопровождаемость в разных задачах значат разные вещи. Что ты в данном случае имеешь ввиду под сопровождаемостью?
IT>Готовность системы к будущим изменениям.
К каким изменениям? Для одних это подмена всего сервера, для других версионификация контракта, для третьих возможность добавления новых типов и т.д. и т.п. Low Coupling/High Cohesion — есть свойство любой правильной архитектуры.

IT>Так именно это и является целью — обеспечение интерфейса для внешних систем

Слишком абстрактно чтобы данное требование можно было выполнить.

IT>Меняется очень сильно. В зависимости от "замени, если не нравится" у тебя будет совсем другая реализация.

Повторю. Я писал данные требования для уровня сервера. "Пользователем" является клиентская программа.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[4]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.01.07 02:52
Оценка: 8 (1)
Здравствуйте, IT, Вы писали:

IT>А зачем вообще нужно это разделение? По мне так оно выглядит очень натянуто.


Давай простой пример. Бизнес-объект User. Что с ним можно делать? Скажем сменить пароль, залогиниться, получить список пользователей. Итого у нас есть

На клиентской стороне
class BusinessObjectUser
{
    public string SystemName { get; }
    public string DisplayName { get; }

    public void ChangePassword(string oldPassword, string newPassword);
    public static BusinessObjectUser GetCurrentUser();
    public static IList<BusinessObjectUser> GetUsers();
}

class BusinessObjectSystem
{
    public BusinessObjectUser Login(string systemName, string password);
}

Но это совсем не то что мы посылаем серверу и принимем с сервера. А посылаем и принимаем мы вот что
struct DataTrasferUserChangePasswordRequest
{
    public string SystemName;
    public string OldPassword;
    public string NewPassword;
}

struct DataTrasferUserLoginRequest
{
    public string SystemName;
    public string Password;
}

struct DataTrasferUserGetListResponseItem
{
    public string SystemName;
    public string DisplayName;
}

struct DataTrasferUserGetListResponse
{
    public List<DataTrasferUserGetListResponseItem> Users;
}


А если посылать и принимать BO, то мало того что мы резко увеличит траффик, так ещё и нагрузим BO всяким мусором. Например в BusinessObjectUser пришлось бы завести write-only поля OldPassword и NewPassword которые бы почти никогда не использовались (но всегда гонялись по сети туда-обратно). Это не только неэффективно, но и приводит к трудно поддерживаемому коду с оттенком процедурного, а не ОО программирования, когда в один класс запихали то что нужно в разных местах.

Пример с User несколько экстремальный, но лично я всегда выделяю DTO. Особенно это важно в .Net, где можно "за компанию" незаметно для себя сериализовать кучу левый вещей, а потом играть в игру "какая клиентская сборка нужна на сервере". А ещё бывает, что на клиенте есть свой кеш, но храниться там не совсем то, что используеться и не совсем то, что получается с сервера.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[5]: DTO внутри BusinessObject
От: akasoft Россия  
Дата: 27.01.07 19:33
Оценка:
Здравствуйте, adontz, Вы писали:

A>Но это совсем не то что мы посылаем серверу и принимем с сервера. А посылаем и принимаем мы вот что


А почему? Пример замечательный привёл. Так почему нельзя получить удалённую ссылку на опубликованный класс BusinessObjectUser и дёргать его методы? Зачем опускаться до обмена сообщениями? Ведь приведённые затем структуры мне представляются попыткой полезть на уровень ниже, где происходит обмен сообщениями между удалённым объектом и его прокси, и подменить их. Зачем?
... << RSDN@Home 1.2.0 alpha rev. 673>> SQL Express 2005
Re[6]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.01.07 20:49
Оценка:
Здравствуйте, akasoft, Вы писали:

A>Так почему нельзя получить удалённую ссылку на опубликованный класс BusinessObjectUser и дёргать его методы?


В веб-сервисах? Может, я что-то в этой жизни упустил, но я так не умею.
А Remoting через Интернет вообще не стоит использовать — пол мира за HTTP proxy сидят.

Вот так и мучаемся с DTO
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[5]: DTO внутри BusinessObject
От: IB Австрия http://rsdn.ru
Дата: 27.01.07 20:50
Оценка: 33 (3) +4
Здравствуйте, adontz, Вы писали:

A>Давай простой пример. Бизнес-объект User.

На самом деле, все выглядит немного не так... Для начала, в чем у нас проблема с объектом User? Проблема в том, что в него почему-то положили и бизнес-логику, то есть сделали как раз то, от чего Игорь предостерегал, да еще, помимо этого и UI-логикой нагрузили. На самом деле свойство DisplayName, видимо должно представлять собой какой-то из UI-ных методов, методы же GetCurrentUser() и GetUsers() — должны лежать в специальных классах бизнес-логики, которые знают, где брать пользователей вообще, и где брать текущих пользователей... Очевидно, сам-по себе бизнес-объект User подобными знаниями обладать не должен, так как подобное знание гвоздями его пришпилит к конкретному месту в системе или, говоря по модному, увеличит связность.
Далее ChngePassword. Этому методу так же место, скорее всего, в каком-нибудь UserManager-е, который и занимается насущным обслуживанием объекта User...
Вот после этих преобразований можно начинать прикручивать к Юзеру DTO. Надо ли это делать, учитывая что теперь в объекте User осталось? Вопрос для домашнего задания... =)
Мы уже победили, просто это еще не так заметно...
Re[6]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.01.07 20:54
Оценка:
Здравствуйте, IB, Вы писали:

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


A>>Давай простой пример. Бизнес-объект User.

IB>На самом деле, все выглядит немного не так... Для начала, в чем у нас проблема с объектом User? Проблема в том, что в него почему-то положили и бизнес-логику, то есть сделали как раз то, от чего Игорь предостерегал, да еще, помимо этого и UI-логикой нагрузили. На самом деле свойство DisplayName, видимо должно представлять собой какой-то из UI-ных методов, методы же GetCurrentUser() и GetUsers() — должны лежать в специальных классах бизнес-логики, которые знают, где брать пользователей вообще, и где брать текущих пользователей... Очевидно, сам-по себе бизнес-объект User подобными знаниями обладать не должен, так как подобное знание гвоздями его пришпилит к конкретному месту в системе или, говоря по модному, увеличит связность.
IB>Далее ChngePassword. Этому методу так же место, скорее всего, в каком-нибудь UserManager-е, который и занимается насущным обслуживанием объекта User...
IB>Вот после этих преобразований можно начинать прикручивать к Юзеру DTO. Надо ли это делать, учитывая что теперь в объекте User осталось? Вопрос для домашнего задания... =)


Ну ты фактически используешь внутри программы DTO, а всю логику выносишь во внешние манипуляторы. А потом говоришь, что DTO не нужны
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[7]: DTO внутри BusinessObject
От: IB Австрия http://rsdn.ru
Дата: 27.01.07 21:04
Оценка: 14 (2) +1
Здравствуйте, adontz, Вы писали:

A>Ну ты фактически используешь внутри программы DTO, а всю логику выносишь во внешние манипуляторы. А потом говоришь, что DTO не нужны

Bingo! =) Хоть горшком назови..
Собственно Игорев поинт в том и состоит, если я правильно понял, что уж коли BO и так практически не содержит логики, так почему бы и не использовать его в качестве DTO, вместо того, чтобы городить дополнительные конструкции и обзывать их разными умными словами...
Мы уже победили, просто это еще не так заметно...
Re[8]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.01.07 22:12
Оценка:
Здравствуйте, IB, Вы писали:

IB>Bingo! =) Хоть горшком назови..

IB>Собственно Игорев поинт в том и состоит, если я правильно понял, что уж коли BO и так практически не содержит логики, так почему бы и не использовать его в качестве DTO, вместо того, чтобы городить дополнительные конструкции и обзывать их разными умными словами...

Ну с одной строны это хорошо, потому что переливания данных между объектами не будет. С другой плохо, потому что с инкапсуляция тю-тю. получаем обычное процедурное программирование. Ну и кроме того... как ты себе представляешь этот самый облегчённый объект User из моего примера? С двумя полями OldPassword и NewPassword? Хоть все методы оттуда выкинь, если есть передача частичных, неполных, нехранимых данных, то выделение DTO делает логику более чёткой, а протокол обмена менее избыточным. И всё ради того, чтобы избежать переливания данных между объектами? Мне кажется избыточность протокола больше повлияет на производительность.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[5]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 27.01.07 23:06
Оценка: 16 (3) +3
Здравствуйте, adontz, Вы писали:

class User
{
    public int    ID          { get; }
    public string SystemName  { get; }
    public string DisplayName { get; }
}

class UserManager
{
    public void       ChangePassword(int userID, string oldPassword, string newPassword);
    public User       GetUser(int userID);
    public List<User> GetUserList();
}


Всего два класса. User не прибит гвоздями к источнику данных и может использоваться любой частью системы от UI до серверной бизнес логики. ChangePassword великолепно реализуется функцией с параметрами.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.01.07 23:46
Оценка:
Здравствуйте, IT, Вы писали:

IT>Всего два класса. User не прибит гвоздями к источнику данных и может использоваться любой частью системы от UI до серверной бизнес логики. ChangePassword великолепно реализуется функцией с параметрами.


Тут нет DTO или того что используется как DTO. Что шлёт ChangePassword серверу, где этот класс?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[7]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 27.01.07 23:54
Оценка:
Здравствуйте, adontz, Вы писали:

IT>>Всего два класса. User не прибит гвоздями к источнику данных и может использоваться любой частью системы от UI до серверной бизнес логики. ChangePassword великолепно реализуется функцией с параметрами.


A>Тут нет DTO или того что используется как DTO. Что шлёт ChangePassword серверу, где этот класс?


class ClientUserManager
{
    public void       ChangePassword(int userID, string oldPassword, string newPassword);
    public User       GetUser(int userID);
    public List<User> GetUserList();
}
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 28.01.07 00:10
Оценка:
Здравствуйте, IT, Вы писали:

A>>Тут нет DTO или того что используется как DTO. Что шлёт ChangePassword серверу, где этот класс?


IT>
IT>class ClientUserManager
IT>{
IT>    public void       ChangePassword(int userID, string oldPassword, string newPassword);
IT>    public User       GetUser(int userID);
IT>    public List<User> GetUserList();
IT>}
IT>


Эээ, может я неудачно выразился. "Что шлёт ChangePassword серверу" имелось ввиду какие данные и в каком формате. Где класс хранитель тех данных, которые ChangePassword шлёт классу?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[9]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 28.01.07 01:01
Оценка: +1
Здравствуйте, adontz, Вы писали:

A>Эээ, может я неудачно выразился. "Что шлёт ChangePassword серверу" имелось ввиду какие данные и в каком формате. Где класс хранитель тех данных, которые ChangePassword шлёт классу?


ChangePassword шлёт 3 переменных. Создвавать для этого специальный класс нет никакой необходимости.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 28.01.07 01:04
Оценка:
Здравствуйте, IT, Вы писали:

A>>Эээ, может я неудачно выразился. "Что шлёт ChangePassword серверу" имелось ввиду какие данные и в каком формате. Где класс хранитель тех данных, которые ChangePassword шлёт классу?


IT>ChangePassword шлёт 3 переменных. Создвавать для этого специальный класс нет никакой необходимости.


Если ты не выделил DTO в класс, это ещё не значит что у тебя совсем нет DTO, это значит что абстрактное понятие DTO реализовано в виде трёх переменных. А DTO всё равно есть, пусть и не так явно.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[11]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 28.01.07 01:16
Оценка:
Здравствуйте, adontz, Вы писали:

A>Если ты не выделил DTO в класс, это ещё не значит что у тебя совсем нет DTO, это значит что абстрактное понятие DTO реализовано в виде трёх переменных. А DTO всё равно есть, пусть и не так явно.


Рома, это чушь, против которой я собственно говоря и протестую. Таким образом DTO можно обозвать всё что угодно, даже пакеты TCP. А назвав всё что можно DTO мы начинаем пихать его куда ни поподя уже не понимая нужно оно там или нет. Твой пример с ChangePassword это очень хорошо демонстрирует. Там где можно обойтись тремя параметрами ты создал целый класс. Класс здесь, класс там, а потом мы удивляемся почему сложность системы выходит из под контроля.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: DTO внутри BusinessObject
От: adontz Грузия http://adontz.wordpress.com/
Дата: 28.01.07 01:43
Оценка:
Здравствуйте, IT, Вы писали:

IT>Рома, это чушь, против которой я собственно говоря и протестую. Таким образом DTO можно обозвать всё что угодно, даже пакеты TCP. А назвав всё что можно DTO мы начинаем пихать его куда ни поподя уже не понимая нужно оно там или нет. Твой пример с ChangePassword это очень хорошо демонстрирует. Там где можно обойтись тремя параметрами ты создал целый класс. Класс здесь, класс там, а потом мы удивляемся почему сложность системы выходит из под контроля.


Игорь, честное слово, я не идиот Я просто явно выделил DTO чтобы было точно понятно о чём я говорю, и только. В реальном проекте я конечно же создам вебметод с 3 параметрами, а не вебметод с одним параметром и вспомогательный класс.
Я просто не хотел приводить излишне громоздкие примеры, которые многим покажутся надуманными. Повторюсь — когда передются частичные данные, DTO в явном или не явном виде нужны.
Вот тебе такой пример. Пусть у User есть список некоторых именованных свойств (DAL ничего не знает об их смысле) которые хранят вспомогательные данные. Например свойство с именем "email" хранит адрес электронной почты. На клиенте у тебя будет
class User
{
    public IDictionary<string, string> NamedProperties {get;}
}

Но когда я хочу просто получить список всех пользователей в группе Administrators мне глубоко наплевать на их номер ICQ и количество детей женского пола. С сервера вернётся список пользоватей, где для каждого пользователя будут личь частичные данные и гнать кучу классов с пустым Dictionary<string, string> нет решительно никакого смысла. Надо делать отдельный класс — DTO.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[13]: DTO внутри BusinessObject
От: IT Россия linq2db.com
Дата: 28.01.07 03:04
Оценка:
Здравствуйте, adontz, Вы писали:

A>Надо делать отдельный класс — DTO.


Зачем? Просто не передавай данные, которые не используются.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.