Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 12:44
Оценка:
По сути код работает со структирированными данными. Назовем бизнес-объекты.

Практически в каждом проекте эти данные используются для 4-5 вещей:

1. Для внутреннего потребления, т.е. вы некие классы передаете/принимаете в своих методах и что-то с ними делаете.

2. Для сохранения. Как правило ORM позволяет сохранять сами эти структуры данных. Но так просто не получается -- их нужно либо наделить атрибутами либо кодогенерацией (ну или XML-описанием).

3. Эти же структуры данных иногда приходится сохранять на диск в неком формате без ORM. К примеру для сохранения в xlsx-файл.

4. Эти же структуры вам нужно отдавать через REST/SOAP-API внешним пользователям.

5. Эти же структуры вам нужно получать из внешнего API, от которого уже вы зависите.

Главное неудобство вижу в том, что по стуи очень похожие структуры в каждом из этих 5 случаев нужно копировать одну в другую. Потому что они хотя и похожи, порой на 90%, но все же отличаются. К примеру в одном случае требуется обязательное наличие set-еров, иначе библиотека отказывается работать с данными (к примеру, стандартная XML-сериализация требует чтобы у списка был set-ер). Но наличие set-еров противоречит внутренней парадигме.

Видите ли вы проблему в том что по сути одни и те же данные по многу раз приходится копировать из одной структуры в другую лишь по той причине, что они применяются в разных слоях (но по стуи одинаковые сущности)?
Отредактировано 26.09.2017 12:45 Shmj . Предыдущая версия .
Re: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Mihas  
Дата: 26.09.17 13:06
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Видите ли вы проблему в том что по сути одни и те же данные по многу раз приходится копировать из одной структуры в другую лишь по той причине, что они применяются в разных слоях (но по стуи одинаковые сущности)?

Я считаю нормальным, что одни и те же данные видоизменяют свое представление в зависимости от задачи.
А сталкивался обратной с проблемой. Варианты представления одних и тех же данных рассматривались как независимые друг от друга. И обработчики имели независимые. В результате, приходилось одни и те же правки вносить в разных участках кода.
Re[2]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 13:18
Оценка:
Здравствуйте, Mihas, Вы писали:

M>Я считаю нормальным, что одни и те же данные видоизменяют свое представление в зависимости от задачи.


Что вы имеете в виду под представлением? То что для каждого случая вы создаете на 90% совпадающие классы?

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


Если создаете классы для каждого из 5 случаев -- то при изменении структуры данных правки придется вносить везде.
Re: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Kolesiki  
Дата: 26.09.17 13:22
Оценка: 2 (1) -1
Здравствуйте, Shmj, Вы писали:

S> Но наличие set-еров противоречит внутренней парадигме.


Вот с этого и надо начинать. Если некая свежепровозглашённая шиза не вписывается в практичную логику, это не "парадигма", а сферический конь в вакууме.

S>Видите ли вы проблему в том что по сути одни и те же данные по многу раз приходится копировать


Разумеется! Поэтому я делаю проще — создаю комбинированные классы.
1. В них есть все поля, чётко ложащиеся на поля СУБД.
2. Поля не для СУБД помечаем как SqlIgnore — это те самые полезные "бизнес-проперти".
3. Сериализация в JSON у нас используется во всю ширь, поэтому так же как с СУБД, что не надо — помечаем JsonIgnore.

В результате, один и тот же класс СПОКОЙНО вращается в бизнес логике, прыгает в сторидж и обратно, сериализуется для внешних API и радует прогера безо всяких вырвиглазных MVVM/MVC и т.п.
Re[2]: Про бизнес-объекты: для сохранения, для API, для внут
От: Shmj Ниоткуда  
Дата: 26.09.17 13:32
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Вот с этого и надо начинать. Если некая свежепровозглашённая шиза не вписывается в практичную логику, это не "парадигма", а сферический конь в вакууме.


Ну почему шиза? Вы читали Guidelines https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/guidelines-for-collections ?
Те же коллекции не должны иметь set-еров по этим рекомендациям. А для XML-сериализации/десериализации, к примеру, они обязательны.


С коллекциями ошибся, оказывается и без сетеров сериализация работает. Но как быть с другими свойствами? Если один объект для всего, то вообще нельзя создавать только get-свойства. Получается если передали объект в метод -- нет гарантий что он там не подвергнется изменениям.
Отредактировано 26.09.2017 18:00 Shmj . Предыдущая версия .
Re[3]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Mihas  
Дата: 26.09.17 13:38
Оценка:
Здравствуйте, Shmj, Вы писали:


M>>Я считаю нормальным, что одни и те же данные видоизменяют свое представление в зависимости от задачи.

S>Что вы имеете в виду под представлением?
Под представлениями я понимаю перечисленное в стартовом посте:
1. Для внутреннего потребления
2. Для сохранения через ORM
3. для сохранения в xlsx-файл.
4. В структуре REST/SOAP-API
Один и тот же элемент данных (например, описание товара) нужно представлять в той или иной структуре.


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

S>Если создаете классы для каждого из 5 случаев -- то при изменении структуры данных правки придется вносить везде.
Что-то обязательно можно вынести в общую часть.
Re[4]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 14:14
Оценка:
Здравствуйте, Mihas, Вы писали:

S>>Если создаете классы для каждого из 5 случаев -- то при изменении структуры данных правки придется вносить везде.

M>Что-то обязательно можно вынести в общую часть.

То есть вы предлагаете использовать наследование?
Re[5]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Sharov Россия  
Дата: 26.09.17 14:52
Оценка:
Здравствуйте, Shmj, Вы писали:

S>То есть вы предлагаете использовать наследование?


Для 1-3 -- наследование, подвязанное к ORM. 4-5 -- dto с трасфорамацией в бизнес объекты.
Кодом людям нужно помогать!
Re[3]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: rameel https://github.com/rsdn/CodeJam
Дата: 26.09.17 16:03
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Те же коллекции не должны иметь set-еров по этим рекомендациям. А для XML-сериализации/десериализации, к примеру, они обязательны.


Поправочка: если это коллекция (ICollection<T>, IDictionary<TKey,TValue>, ISet<T> или их наследники), то сеттер не нужен, все и так работает, если
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Re[6]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 16:32
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Для 1-3 -- наследование, подвязанное к ORM. 4-5 -- dto с трасфорамацией в бизнес объекты.


А конкретно. Вы создаете объекты в EF DB-First/Model-First а потом наследуетесь от них? Т.е. вся ваша архитектура гвоздями прибита к EF?
Re[2]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 16:53
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>В результате, один и тот же класс СПОКОЙНО вращается в бизнес логике, прыгает в сторидж и обратно, сериализуется для внешних API и радует прогера безо всяких вырвиглазных MVVM/MVC и т.п.


Вот в идеале хотелось бы такое, чтобы 1 класс создавался на одну сущность. Ну или в крайнем случае наследование.

Но есть два минуса:

1. Если используете тот же EF CodeFirst, то нужно помечать атрибутами поля. А это значит что библиотека ваших контрактов будет иметь зависимость на конкретную ORM.

2. Все поля должны быть get и set, даже если по вашей внутренней логике объект не мутабельный. Фактически любой ваш объект может быть изменен в любом слое, вы не можете этого запретить.
Re[6]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 16:54
Оценка:
Здравствуйте, Sharov, Вы писали:

S>4-5 -- dto с трасфорамацией в бизнес объекты.


И еще. Как выполняете трансоформацию? С помощью рефлексии или вручную?
Re[4]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 17:11
Оценка:
Здравствуйте, rameel, Вы писали:

R>Поправочка: если это коллекция (ICollection<T>, IDictionary<TKey,TValue>, ISet<T> или их наследники), то сеттер не нужен, все и так работает, если


А вот:

https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/property

✓ DO create get-only properties if the caller should not be able to change the value of the property.
Keep in mind that if the type of the property is a mutable reference type, the property value can be changed even if the property is get-only.


По вашей схеме вообще не будет никакой возможности сделать get-only свойства. Вообще никак. Все должны быть и get и set.

А что если ваш объект требует неизменности? Вы его передаете и должна быть гарантия что метод его не изменит. Что тогда?
Re[7]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Sharov Россия  
Дата: 26.09.17 17:17
Оценка:
Здравствуйте, Shmj, Вы писали:

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


S>>Для 1-3 -- наследование, подвязанное к ORM. 4-5 -- dto с трасфорамацией в бизнес объекты.


S>А конкретно. Вы создаете объекты в EF DB-First/Model-First а потом наследуетесь от них? Т.е. вся ваша архитектура гвоздями прибита к EF?


У меня сценарий проще, поэтому всюду использую сгенерированные orm объекты (у меня telerik openaccess). В случае передачи объектов между сервисами,
использую трансформацию в dto, которую для меня тот же orm уже сгенерировал. Трансформация выполняется копированием полей+какая-то специфичная бизнес логика.
Кодом людям нужно помогать!
Re: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: bnk Австрия http://unmanagedvisio.com/
Дата: 26.09.17 17:38
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Видите ли вы проблему в том что по сути одни и те же данные по многу раз приходится копировать из одной структуры в другую лишь по той причине, что они применяются в разных слоях (но по стуи одинаковые сущности)?


Нет тут никакой проблемы.
Определяешь 5 разных классов, и все. Если попытаешься переиспользовать один — все закончится кашей (перемешиванием разных модулей и слоев)
Копируешь автомаппером например (самая распространенная либа для этого на .net) — обеспечивает гибкое эффективное копирование "похожих" объектов.
Re[5]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: rameel https://github.com/rsdn/CodeJam
Дата: 26.09.17 17:54
Оценка:
Здравствуйте, Shmj, Вы писали:

Я ответил на вот это вот:
S> А для XML-сериализации/десериализации, к примеру, они обязательны.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Re[2]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: Shmj Ниоткуда  
Дата: 26.09.17 17:55
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Нет тут никакой проблемы.

bnk>Определяешь 5 разных классов, и все. Если попытаешься переиспользовать один — все закончится кашей (перемешиванием разных модулей и слоев)
bnk>Копируешь автомаппером например (самая распространенная либа для этого на .net) — обеспечивает гибкое эффективное копирование "похожих" объектов.

Не ясно почему обязательно получится "каша".

А про копирование. Ведь есть такое понятие как конструктор и он вызвается при создании класса. Там указываются обязательные поля. А ваш automapper знает про конструкторы и обязательные поля?

Или вы предлагаете отказаться от концепции конструкторов, оставлять его всегда пустым и просто использовать метод VilidateInstance для проверки установлены ли обязательные поля?
Re[6]: Про бизнес-объекты: для сохранения, для API, для внут
От: Shmj Ниоткуда  
Дата: 26.09.17 17:57
Оценка:
Здравствуйте, rameel, Вы писали:

R>Я ответил на вот это вот:

S>> А для XML-сериализации/десериализации, к примеру, они обязательны.

Да, для коллекций оказывается не обязательны.

Но по предложенной выше парадигме с использованием единого класса для всего -- вообще все свойства будут имет обязательно и get и set. А что если объект не подразумевает возможность изменений?
Отредактировано 26.09.2017 17:58 Shmj . Предыдущая версия .
Re[7]: Про бизнес-объекты: для сохранения, для API, для внутреннего
От: rameel https://github.com/rsdn/CodeJam
Дата: 26.09.17 18:02
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Но по вашей парадигме вообще все свойства будут имет обязательно и get и set. А что если объект не подразумевает возможность изменений?


Какой парадигме?! Я вообще-то один раз только написал, указать, что для стандартной XML (де)сериализации коллекции не обязательно наличии сеттера.

Вопрос я думаю адресуется не ко мне, я в дискуссии не учавствовал
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Re[7]: Про бизнес-объекты: для сохранения, для API, для внут
От: rameel https://github.com/rsdn/CodeJam
Дата: 26.09.17 18:07
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Но по предложенной выше парадигме с использованием единого класса для всего -- вообще все свойства будут имет обязательно и get и set. А что если объект не подразумевает возможность изменений?


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