Есть сайт. В нём классы бизнес-моделей, кладущиеся на таблицы БД: User, Configuration и т.д.
И у каждой такой модели есть сопряжённый класс, который содержит ряд функций бизнес-логики. Каждая такая функция работает с БД-контекстом (создаваемым и убиваемым в её рамках), кроме того некоторые функции используют сопряжённые классы других сущностей.
UserService? Но сервисы в данном проекте уже заняты за классами, время жизни которых превышает жизнь контроллеров, они долгое время висят в памяти, в отдельном потоке, и общаются с другими через многопоточные очереди/сеть.
UserHelper? Но хелперы в данном проекте эти легковесные классы, чаще всего даже статические, содержащие "несерьёзный" вспомогательный код (в противовес сабжевым классам с их "серьёзным", незаменимым кодом).
Здравствуйте, D.Lans, Вы писали:
DL>Вопрос на засыпку: какой суффикс выбрать для таких классов?
DL>Конечно есть классический менеджер: UserManager, ConfigurationManager. DL>Но это вроде как моветон
Моветон — это если применяется бессистемно. А если в проекте есть строгие соглашения по именованию, то хоть фубарами обзывать можно. Главное, чтоб путаницы не было.
DL>UserService? Но сервисы в данном проекте уже заняты за классами, время жизни которых превышает жизнь контроллеров, они долгое время висят в памяти, в отдельном потоке, и общаются с другими через многопоточные очереди/сеть.
В большинстве проектов под сервисами понимаются именно локальные сервисы. Которые (в идеале) stateless и не имеют разделяемого состояния.
А вот это "общаются с другими через многопоточные очереди/сеть" обзывают по-разному. В зависимости от того, какую книжку читал проектировщик, это actors/grains/pipes/channels/nodes/servicepoints/microservices. Именно чтоб не путать с локальными сервисами.
Re: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, D.Lans, Вы писали:
DL>Есть сайт. В нём классы бизнес-моделей, кладущиеся на таблицы БД: User, Configuration и т.д.
Я их называю DbUser, DbConfiguration. Это никакая не бизнес-модель, это просто классы для маппинга сырых данных на БД.
DL>И у каждой такой модели есть сопряжённый класс, который содержит ряд функций бизнес-логики. Каждая такая функция работает с БД-контекстом (создаваемым и убиваемым в её рамках), кроме того некоторые функции используют сопряжённые классы других сущностей.
Я предполагаю, вот это и есть настоящая модель предметной области. Эти классы будут называться User, Configuration и так далее, причём они не обязательно будут совпадать с классами маппинга Db*. Они содержат конкретные методы и свойства, реализующие пресловутую бизнес-логику, они могут быть полу-абстрактными и в наследниках уже использовать классы маппинга БД, когда наступает момент по бизнес-логике что-то поменять в БД.
DL>Вопрос на засыпку: какой суффикс выбрать для таких классов? DL>Конечно есть классический менеджер: UserManager, ConfigurationManager. DL>Но это вроде как моветон DL>https://blog.codinghorror.com/i-shall-call-it-somethingmanager/
DL>Как бы вы назвали?
Ну вот — никаких суффиксов.
Кстати, для простого чтения данных из БД и отображения их на экране я использую другие классы: UserModel, ConfigurationModel. Эти классы сразу содержат много ненормализованных данных, которые нужно отобразить. Естественно, чтение из БД — это довольно простой и быстрый код.
А модель предметной области используется только для записи в БД, но не для чтения.
Re[2]: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, Vladek, Вы писали:
V>Я их называю DbUser, DbConfiguration. Это никакая не бизнес-модель, это просто классы для маппинга сырых данных на БД.
V>Кстати, для простого чтения данных из БД и отображения их на экране я использую другие классы: UserModel, ConfigurationModel.
Можете привести пример DbUser и UserModel, в котором бы была видна причина разделения их на два класса?
Re: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, D.Lans, Вы писали:
DL>И у каждой такой модели есть сопряжённый класс, который содержит ряд функций бизнес-логики. Каждая такая функция работает с БД-контекстом (создаваемым и убиваемым в её рамках), кроме того некоторые функции используют сопряжённые классы других сущностей.
То есть Transaction Script? Обычно сервисом и кличут. Если они более БД ориентированы, то Repository?
DL>UserService? Но сервисы в данном проекте уже заняты за классами, время жизни которых превышает жизнь контроллеров, они долгое время висят в памяти, в отдельном потоке, и общаются с другими через многопоточные очереди/сеть.
И ни слова о том что они делают и для чего нужны.
Re[2]: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, Blazkowicz, Вы писали:
B>То есть Transaction Script?
Да, что-то в этом роде.
B>Если они более БД ориентированы, то Repository?
Тоже сначала думал над репозиторием, но, насколько я понимаю, этот паттерн содержит только простейшие методы для работы с БД с минимумом логики: добавить, отредактировать, удалить, найти. Всё что сверх этого — уже в понятие "репозиторий" не попадает. А в данном случае как раз таки полно "сверх этого" — сложных методов, содержащих кучу логики.
B>И ни слова о том что они делают и для чего нужны.
На стороне сайта такой "сервис", висящий в отдельном потоке, получает от контроллеров запросы по Queue и отправляет их по WebSockets в виндовую службу (которая кстати тоже содержит в имени злополучный Service), в которой аналогичный "сервис" в своём потоке эти запросы принимает и перенаправляет дальше по очереди в другой поток-"сервис" (назовём его ключевым).
В службе висят ещё несколько "сервисов", время от времени собирающих информацию из внешней среды (базы данных, файловая система) и сохраняющих в кеш, которым и пользуется "ключевой сервис" для подготовки ответов и возврата обратно по цепочке на сайт в его кеш.
Re[3]: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, D.Lans, Вы писали: DL>Здравствуйте, Vladek, Вы писали: V>>Я их называю DbUser, DbConfiguration. Это никакая не бизнес-модель, это просто классы для маппинга сырых данных на БД. V>>Кстати, для простого чтения данных из БД и отображения их на экране я использую другие классы: UserModel, ConfigurationModel. DL>Можете привести пример DbUser и UserModel, в котором бы была видна причина разделения их на два класса?
Причина их разделения кроется в кардинальном отличии их ролей: один содержит в себе данные для БД, второй содержит данные для пользователя.
Не буду далеко ходить и приведу конкретный пример из приложения клиента для RSDN: первый класс содержит минимум полей, необходимых для сохранения поста в БД, второй класс содержит всю информацию, необходимую для отображения поста на экране в составе целого треда. Две роли, два класса, а класс для БД вообще internal в отдельной сборке.
DbPost
namespace Rsdn.Client.Data.Storage
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SQLite;
[Table("Post")]
internal class DbPost
{
[PrimaryKey]
public int Id { get; set; }
public int? ThreadId { get; set; }
public int? SubthreadId { get; set; }
[NotNull]
public int ForumId { get; set; }
[NotNull]
public string Title { get; set; }
[NotNull]
public string Message { get; set; }
[NotNull]
public int UserId { get; set; }
[NotNull]
public string Username { get; set; }
[NotNull]
public DateTime Posted { get; set; }
public DateTime? Updated { get; set; }
[NotNull]
public bool IsClosed { get; set; }
}
}
PostDetails
namespace Rsdn.Community.Interaction
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class PostDetails : IIdentifiable, IVotes
{
public int Id { get; private set; }
public int? ThreadId { get; private set; }
public int? SubthreadId { get; private set; }
public string Title { get; private set; }
public string Message { get; private set; }
public DateTime? Updated { get; private set; }
public DateTime Posted { get; private set; }
public string Username { get; private set; }
public int? InterestingCount { get; private set; }
public int? ThanksCount { get; private set; }
public int? ExcellentCount { get; private set; }
public int? AgreedCount { get; private set; }
public int? DisagreedCount { get; private set; }
public int? Plus1Count { get; private set; }
public int? FunnyCount { get; private set; }
public int Position { get; internal set; }
public int Level { get; internal set; }
public bool IsNew { get; internal set; }
}
}
Более того, одна и та же информация отображается по разному в разных контекстах, вот класс для отображения текущих тредов в отдельном форуме:
ThreadDetails
namespace Rsdn.Community.Interaction
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class ThreadDetails : IIdentifiable, IVotes
{
public int Id { get; private set; }
public string Title { get; private set; }
public string Excerpt { get; private set; }
public string Username { get; private set; }
public DateTime Updated { get; private set; }
public DateTime? Viewed { get; private set; }
public int NewPostCount { get; private set; }
public int PostCount { get; private set; }
public int? InterestingCount { get; private set; }
public int? ThanksCount { get; private set; }
public int? ExcellentCount { get; private set; }
public int? AgreedCount { get; private set; }
public int? DisagreedCount { get; private set; }
public int? Plus1Count { get; private set; }
public int? FunnyCount { get; private set; }
public bool IsNew { get; internal set; }
}
}
И все три класса представляют разные роли для одной и той же сущности.
Re[3]: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, D.Lans, Вы писали:
DL>Можете привести пример DbUser и UserModel, в котором бы была видна причина разделения их на два класса?
Ровно про это и хотел сказать: вы же сами их и разделили! (см. начальное сообщение) Вопрос: а зачем? Ну есть класс PurchaseOrder — в нём куча полей для мэппинга в БД. Нужны бизнес-функции? Да ради бога, создавай! Что мешает-то? Нужны "бизнес-проперти" — тоже не проблема, "субдшные" поля помечаем атрибутами, остальное — наши полезные члены. Аналогично создаются проперти для удобного view (например, код валюты -> её название). В результате, из этой белиберды MVVM остаётся только Business-Database-Entity — ОДИН класс и его хватает за глаза на всё, включая тесты.
Возможно, где-то есть суперзадачи, где "одноклассовая" модель не подходит, но у меня таких не встречалось.
Re[4]: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, Vladek, Вы писали:
V>И все три класса представляют разные роли для одной и той же сущности.
Вот именно. Сущность — одна, а её представителей АЖ ТРИ. Причём с кучей пересекающихся членов. Мне кажется, в наш век безразмерной памяти, уже можно не экономить десяток байт и совместить все три сущности в одну. Причём специфичные (но не нужные сейчас) поля просто не заполнять.
V> public int? InterestingCount { get; private set; } V> public int? ThanksCount { get; private set; } V> public int? ExcellentCount { get; private set; } V> public int? AgreedCount { get; private set; } V> public int? DisagreedCount { get; private set; } V> public int? Plus1Count { get; private set; } V> public int? FunnyCount { get; private set; }
Боже, ну и маразм!... РСДН не хочет слегка умерить гамму эмоций по отн. к посту? Бред же — интересно, спасибо, пажалуста, плюс, согласен.... это делал гуманитарий?
V>Более того, одна и та же информация отображается по разному в разных контекстах
Вот это и есть повод объединить всё в одно. Данные — они одни, показывать из по-разному — задача UI.
Re[4]: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, Vladek, Вы писали:
V>Не буду далеко ходить и приведу конкретный пример из приложения клиента для RSDN: первый класс содержит минимум полей, необходимых для сохранения поста в БД, второй класс содержит всю информацию, необходимую для отображения поста на экране в составе целого треда. Две роли, два класса, а класс для БД вообще internal в отдельной сборке.
Угу, это отличное решение для случая, когда весь код работает как подай-принеси, без особой логики.
У топикстартера, как я понял, биз-логики достаточно много. Настолько, что её в отдельный слой оформляют.
Как мне кажется, в этом случае держать несколько разных типов для представления несколько накладно. Проще работать напрямую с моделью, а viewmodel оставить как dto для фронтэнда.
Re[3]: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, D.Lans, Вы писали:
DL>Тоже сначала думал над репозиторием, но, насколько я понимаю, этот паттерн содержит только простейшие методы для работы с БД с минимумом логики: добавить, отредактировать, удалить, найти. Всё что сверх этого — уже в понятие "репозиторий" не попадает. А в данном случае как раз таки полно "сверх этого" — сложных методов, содержащих кучу логики.
Нет. Задача репозитория как раз инкапсулировать сложные запросы, а не CRUD.
DL>На стороне сайта такой "сервис", висящий в отдельном потоке, получает от контроллеров запросы по Queue и отправляет их по WebSockets в виндовую службу (которая кстати тоже содержит в имени злополучный Service), в которой аналогичный "сервис" в своём потоке эти запросы принимает и перенаправляет дальше по очереди в другой поток-"сервис" (назовём его ключевым).
"Диспетчер" это, а не сервис. Или "брокер" какой-нибудь.
Re: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, D.Lans, Вы писали:
DL>Есть сайт. В нём классы бизнес-моделей, кладущиеся на таблицы БД: User, Configuration и т.д.
DL>И у каждой такой модели есть сопряжённый класс, который содержит ряд функций бизнес-логики. Каждая такая функция работает с БД-контекстом (создаваемым и убиваемым в её рамках), кроме того некоторые функции используют сопряжённые классы других сущностей.
DL>Вопрос на засыпку: какой суффикс выбрать для таких классов? DL>Конечно есть классический менеджер: UserManager, ConfigurationManager. DL>Но это вроде как моветон DL>https://blog.codinghorror.com/i-shall-call-it-somethingmanager/
DL>Как бы вы назвали?
Либо Controller (модель у нас имеется, а без V можно жить), либо Manager.
Кодом людям нужно помогать!
Re: Общее именование классов, работающих с бизнес-сущностями?
Здравствуйте, D.Lans, Вы писали:
DL>Есть сайт. В нём классы бизнес-моделей, кладущиеся на таблицы БД: User, Configuration и т.д. DL>И у каждой такой модели есть сопряжённый класс, который содержит ряд функций бизнес-логики. DL>Как бы вы назвали?