@@AlexCSharp Кстати, делай репозитории на GitHub для каждого урока, это очень полезно. Есть канал CodeBlog тоже учит C#'пу (Немного о нем: Зовут Вадим, 8 лет уже работает на шарпе) и вот он делает на каждый урок свой репозиторий. Просто когда я делаю программы, я частенько залажу на его определенный репозиторий и смотрю как у него что-то реализованно.
@@Keeytari Я его знаю, но это был урок для школы программистов вообще.) Я не планировал канал вести, но будет видно) Думаю сюда просто разборы архитектур учеников ещё выкладывать, и занятия не по чистому языку(их как грязи) а по архитектурам, практикам в коммерческой разработке, SOLID и т.п. Но язык будет C# и технологии его же.
@@AlexCSharp Я новичок в C#, чуть больше года занимаюсь им. Мне как раз таки архитектура приложений нужна) Так как я сейчас разрабатываю прогу, сделал много функционала и все пойдет коту под хвост, так как все выглядит как какое-то дерьмо) Мне нужно научиться как раз таки делать архитектуру приложения правильно, чтобы все было удобно и понятно.) Спасибо за урок еще раз! И не забрасывайте канал, у вас хорошо получается, я думаю, что многим ваш опыт и видео будут полезны!
@@AlexCSharp С вами солидарен) Просто роликов по самому шарпу много, а вот по архитектурам мало, а еще меньше тех, которые рассказывают о коммерческой разработке, как все строится, как выглядит архитектура приложения и тд тп. Все что связано с коммерческой разработкой, этого всего мало) А роликов по типу: Изучаем паттерн Одиночка много)
@@shkurmander нет, мне не нравятся системы большинства школ программирования, поэтому я если что-то и делаю, то для их учеников, а не самих школ. ) Если встретили что-то похожее -не удивительно, ведь я учу best practices, а best они не просто так, и довольно распространены. Да и первоисточники я указал в начале ролика, можете ознакомиться, найдёте параллели наверняка. ;)
Мне кажется, что у класса DriverEntity должно быть поле со списком машин, иначе как нам подгружать связанные данные? Например, информацию о водителе и его машинах? Делать несколько запросов к бд? Для примера возьмем такой случай: нам нужно получить водителей, чей возраст находится в диапазоне от age1 до age2 и получить информацию о их машинах (для какой-нибудь статистики).
Я писал не бизнес-логику, а показывал архитектурный подход. Для бестпрактис по формированию и оптимизации запросов, работе с индексами, работе оптимизаторов БД и т.п. надо было бы делать ещё одно полуторачасовое видео.
Возник вопрос ,чем интерфейс для обшей модели сущности(возможно некоркектно вышло я говорю про BaseEntity) лучше абстрактного класса? я лично использую абстрактный класс.
Интерфейс в принципе лучше классов тем, что на одном классе может быть реализовано множество интерфейсов. А от класса можно лишь от одного наследоваться. В остальном ничем, и в данном случае тоже ничем.
А для чего в слое Entities нужен интерфейс IBaseEntity и абстрактный класс BaseEntity. Можно ли отказаться от интерфейса? Просто не до конца понятно в чем преимущество этого интерфейса, если абстрактный класс, ничего более не привносит. Может просто оставить абстрактный класс и всё?
Спасибо за лекцию! Все круто! Есть вопрос, надеюсь, если не ответите то хоть на толкнете на мысль. А как бы вы реализовывали структуру, если проект, а точнее сервисы разросстаются до большиъ масштабов? Получается, что не сильно удобно становится использовать сервисы, в плане бегать по сервису и искать нужный метод. Можно ли как-то от этого уйти? Заранее благодарю
Сервис работает с одной сущностью. Если у Вас 1000 и 1 метод для работы с одной сущностью: можно перейти на CQRS. Но тогда будет 1000 и 1 класс. А если эти методы не касаются непосредственно CRUD-функционала - их стоит вытащить в отдельные типы, в зависимости от смысла: конвертеры, мапперы, сериализаторы, дескрипторы и т.п. Опять же, используйте инструменты для обобщения и универсальности. Например, если надо получать одну и ту же сущность по 3м разным параметрам - не надо писать 3 разных метода, достаточно 1го метода, принимающего делегат с условием, где на более высоком уровне уже будет приниматься решение, по какому условию сущность будет получена.
@@AlexCSharp Спасибо за ответ! Только у меня небольшой диссонанс появился. Получается работать в сервисах мы можем/должны в рамках 4 методов (добавления, обновления, получения, удаления)? Напрашивается вывод, что для сложного приложения (с запутанной логикой) такое не подходит... В сложном приложении получение(редактирование, удаление, добавление) одной сущности может осуществляться разными способами. К примеру: 1) получение данных для пользователей разного уровня доступа. Руководитель (который видит всю инфу) и рядовой сотрудник (только то что ему нужно). В каком слое нужно отсеивать "лишнее" для рядового сотрудника и "оставить" для руководителя? 2) тоже самое хотелось бы спроецировать и на редактирование, к примеру некоторые данные рядовой сотрудник имеет право редактировать, а некоторые нет. Понятно, что можно ограничить ввод данных на UI слое, но хотелось бы услышать где правильнее это делать на стороне сервера. Буду признателен за ответ!
@@nikitashevyakov3057 Отсеивать лишнее в сервисном слое. На UI лететь должно только то, что необходимо. CRUD- это не 4 метода, это 4 типа операций. Удаление может быть разное, хардделит, софтделит, делит по условию и т.п., так же с получением данных: 1 сущность, коллекция, по такому условию, по эдакому условию, это всё CRUD. Но репозиторий не должно волновать, у кого там какие пермишены и т.п., максимум, это регулируется, как я выше писал, условием через делегат в качестве параметра. Get(Func condition). А про то, кто там что может редактировать - это решается на уровне UI, а если при недостаточном пермишене приходит запрос от UI на редактирование того, чего нельзя- ошибку кидать уже из контроллера. Репозиторий за такие вещи вообще не должен отвечать.
я так и не понял, почему мы в декораторе обращаемся не к классу, а к интерфейсу? по сути мы просто создаем новую логику, а не добавляем к старой, пожалуйста обьясните.
Это инверсия зависимостей. Мы всегда используем интерфейсы, как абстракцию, дающую гибкость и конкретно задекларированный функционал, а все декораторы и сам сервис так же реализуют один и тот же интерфейс. Их явная связь организуется только в месте инициализации всего пайплайна. Если мы захотим в декораторе изменить сам сервис - нам придётся его переписывать. В случае с интерфейсом мы просто добавляем ещё одну реализацию интерфейса, не меняя сам класс.
@@AlexCSharp Спасибо за ответ! Вроде понятно. Еще вопросик, декораторы можно ли перегружать? Ну то есть добавить не только логику логирования, но и другой функционал или же декоратор нужен только для точной функциональности? (только логирование и больше нельзя если надо еще создавайте еще 1 декоратор)
@@kurnakovv Строится цепочка декораторов. Чем больше разнопланового кода в одном месте - тем тяжелее читать, тем тяжелее дебажить. Каждый класс должен быть сфокусирован на одной задаче, как говорит Макконнелл. Это касается не только декораторов.
@@kurnakovv Много других дел. Надо работать, развиваться самому, писать методички для всё подрастающих учеников, поэтому на видео пока времени нет. Хотя хочу выпустить более крутые и проработанные видео по архитектуре, есть сценарий, но сложно все крутые штуки хорошо проработать и совместить, требует прорву времени.
@@ИгорьКочат по шарпам-то как раз предостаточно. А вот по архитектуре и кодстайлу мало. И я не столько шарпы даю(это просто язык, на котором я работаю), сколько общие принципы построения систем. Они подойдут для любого ООП-языка.
Охренительный ролик, как раз то, что искал! Спасибо большое
Хочу еще Ваши уроки по C#!!!!!!!!!!!! Лучшее объяснение что когда либо слышала!!!!!
Я планирую записать ещё. Как будет время. )
@@AlexCSharp Жду новые уроки, отличная лекция
Спасибо за лекцию! Очень информативно и понятно. Жду продолжения!
Лучшее по архитектуре! Спасибо!!!!
Спасибо большое за ваш урок! Очень понравился! Пожалуйста, не останавливайтесь и продолжайте выпускать видео по C#, у вас очень хорошо получается!
Спасибо! Я планирую)
@@AlexCSharp Кстати, делай репозитории на GitHub для каждого урока, это очень полезно. Есть канал CodeBlog тоже учит C#'пу (Немного о нем: Зовут Вадим, 8 лет уже работает на шарпе) и вот он делает на каждый урок свой репозиторий. Просто когда я делаю программы, я частенько залажу на его определенный репозиторий и смотрю как у него что-то реализованно.
@@Keeytari Я его знаю, но это был урок для школы программистов вообще.) Я не планировал канал вести, но будет видно) Думаю сюда просто разборы архитектур учеников ещё выкладывать, и занятия не по чистому языку(их как грязи) а по архитектурам, практикам в коммерческой разработке, SOLID и т.п. Но язык будет C# и технологии его же.
@@AlexCSharp Я новичок в C#, чуть больше года занимаюсь им. Мне как раз таки архитектура приложений нужна) Так как я сейчас разрабатываю прогу, сделал много функционала и все пойдет коту под хвост, так как все выглядит как какое-то дерьмо) Мне нужно научиться как раз таки делать архитектуру приложения правильно, чтобы все было удобно и понятно.) Спасибо за урок еще раз! И не забрасывайте канал, у вас хорошо получается, я думаю, что многим ваш опыт и видео будут полезны!
@@AlexCSharp С вами солидарен) Просто роликов по самому шарпу много, а вот по архитектурам мало, а еще меньше тех, которые рассказывают о коммерческой разработке, как все строится, как выглядит архитектура приложения и тд тп. Все что связано с коммерческой разработкой, этого всего мало) А роликов по типу: Изучаем паттерн Одиночка много)
топ все очень просто и понятно рассказываешь)
Спасибо! Не останавливайся!
Pure gold!! Шикарно!
Больше бы :/
Очень понятно, спасибо за труд!
Отлично, спасибо!
Отличное видео, подпишусь, вдруг автор решит продолжить)
Прошу прощения за плавающий звук, буду фиксить)
А не вы писали скринкасты для SkillFactory для курса Разработчик C#, в частности по разработке проекта SocialNetwork?
@@shkurmander нет, мне не нравятся системы большинства школ программирования, поэтому я если что-то и делаю, то для их учеников, а не самих школ. )
Если встретили что-то похожее -не удивительно, ведь я учу best practices, а best они не просто так, и довольно распространены. Да и первоисточники я указал в начале ролика, можете ознакомиться, найдёте параллели наверняка. ;)
Мощное видео
Спасибо за видео
Спасибо!)
Мне кажется, что у класса DriverEntity должно быть поле со списком машин, иначе как нам подгружать связанные данные? Например, информацию о водителе и его машинах? Делать несколько запросов к бд?
Для примера возьмем такой случай: нам нужно получить водителей, чей возраст находится в диапазоне от age1 до age2 и получить информацию о их машинах (для какой-нибудь статистики).
Я писал не бизнес-логику, а показывал архитектурный подход. Для бестпрактис по формированию и оптимизации запросов, работе с индексами, работе оптимизаторов БД и т.п. надо было бы делать ещё одно полуторачасовое видео.
Отличный контент, Алекс, спасибо! Оставь пожалуйста свои координаты для связи, хотелось бы взять у тебя несколько уроков, в Телеге не смог найти тебя
Спасибо!
t.me/RenMaRus может быть так выйдет
Возник вопрос ,чем интерфейс для обшей модели сущности(возможно некоркектно вышло я говорю про BaseEntity) лучше абстрактного класса? я лично использую абстрактный класс.
Интерфейс в принципе лучше классов тем, что на одном классе может быть реализовано множество интерфейсов. А от класса можно лишь от одного наследоваться. В остальном ничем, и в данном случае тоже ничем.
А для чего в слое Entities нужен интерфейс IBaseEntity и абстрактный класс BaseEntity. Можно ли отказаться от интерфейса?
Просто не до конца понятно в чем преимущество этого интерфейса, если абстрактный класс, ничего более не привносит.
Может просто оставить абстрактный класс и всё?
Можно отказаться и от того, и от другого. Всё зависит от задачи.
Спасибо за лекцию! Все круто!
Есть вопрос, надеюсь, если не ответите то хоть на толкнете на мысль. А как бы вы реализовывали структуру, если проект, а точнее сервисы разросстаются до большиъ масштабов?
Получается, что не сильно удобно становится использовать сервисы, в плане бегать по сервису и искать нужный метод. Можно ли как-то от этого уйти?
Заранее благодарю
Сервис работает с одной сущностью. Если у Вас 1000 и 1 метод для работы с одной сущностью: можно перейти на CQRS. Но тогда будет 1000 и 1 класс. А если эти методы не касаются непосредственно CRUD-функционала - их стоит вытащить в отдельные типы, в зависимости от смысла: конвертеры, мапперы, сериализаторы, дескрипторы и т.п.
Опять же, используйте инструменты для обобщения и универсальности. Например, если надо получать одну и ту же сущность по 3м разным параметрам - не надо писать 3 разных метода, достаточно 1го метода, принимающего делегат с условием, где на более высоком уровне уже будет приниматься решение, по какому условию сущность будет получена.
@@AlexCSharp Спасибо за ответ! Только у меня небольшой диссонанс появился.
Получается работать в сервисах мы можем/должны в рамках 4 методов (добавления, обновления, получения, удаления)?
Напрашивается вывод, что для сложного приложения (с запутанной логикой) такое не подходит... В сложном приложении получение(редактирование, удаление, добавление) одной сущности может осуществляться разными способами.
К примеру:
1) получение данных для пользователей разного уровня доступа. Руководитель (который видит всю инфу) и рядовой сотрудник (только то что ему нужно). В каком слое нужно отсеивать "лишнее" для рядового сотрудника и "оставить" для руководителя?
2) тоже самое хотелось бы спроецировать и на редактирование, к примеру некоторые данные рядовой сотрудник имеет право редактировать, а некоторые нет. Понятно, что можно ограничить ввод данных на UI слое, но хотелось бы услышать где правильнее это делать на стороне сервера.
Буду признателен за ответ!
@@nikitashevyakov3057 Отсеивать лишнее в сервисном слое. На UI лететь должно только то, что необходимо. CRUD- это не 4 метода, это 4 типа операций. Удаление может быть разное, хардделит, софтделит, делит по условию и т.п., так же с получением данных: 1 сущность, коллекция, по такому условию, по эдакому условию, это всё CRUD.
Но репозиторий не должно волновать, у кого там какие пермишены и т.п., максимум, это регулируется, как я выше писал, условием через делегат в качестве параметра.
Get(Func condition).
А про то, кто там что может редактировать - это решается на уровне UI, а если при недостаточном пермишене приходит запрос от UI на редактирование того, чего нельзя- ошибку кидать уже из контроллера. Репозиторий за такие вещи вообще не должен отвечать.
@@AlexCSharp Благодарю вас!
я так и не понял, почему мы в декораторе обращаемся не к классу, а к интерфейсу? по сути мы просто создаем новую логику, а не добавляем к старой, пожалуйста обьясните.
Это инверсия зависимостей. Мы всегда используем интерфейсы, как абстракцию, дающую гибкость и конкретно задекларированный функционал, а все декораторы и сам сервис так же реализуют один и тот же интерфейс. Их явная связь организуется только в месте инициализации всего пайплайна. Если мы захотим в декораторе изменить сам сервис - нам придётся его переписывать. В случае с интерфейсом мы просто добавляем ещё одну реализацию интерфейса, не меняя сам класс.
@@AlexCSharp Спасибо за ответ! Вроде понятно. Еще вопросик, декораторы можно ли перегружать? Ну то есть добавить не только логику логирования, но и другой функционал или же декоратор нужен только для точной функциональности? (только логирование и больше нельзя если надо еще создавайте еще 1 декоратор)
@@kurnakovv Строится цепочка декораторов. Чем больше разнопланового кода в одном месте - тем тяжелее читать, тем тяжелее дебажить. Каждый класс должен быть сфокусирован на одной задаче, как говорит Макконнелл. Это касается не только декораторов.
@@AlexCSharp Ок, еще раз спасибо! Жаль что вы больше видео не выпускаете...
@@kurnakovv Много других дел. Надо работать, развиваться самому, писать методички для всё подрастающих учеников, поэтому на видео пока времени нет. Хотя хочу выпустить более крутые и проработанные видео по архитектуре, есть сценарий, но сложно все крутые штуки хорошо проработать и совместить, требует прорву времени.
Планируешь ещё пилить видео по c# ?
Давно планирую, но всё никак не запилю. А скоро ещё начнут запрещать образовательную деятельность без аккредитации и всё, приплыли. )
@@AlexCSharp Сейчас не так много толковой информации по шарпам на ютубе. Будет очень круто, если продолжишь это дело
@@ИгорьКочат по шарпам-то как раз предостаточно. А вот по архитектуре и кодстайлу мало. И я не столько шарпы даю(это просто язык, на котором я работаю), сколько общие принципы построения систем. Они подойдут для любого ООП-языка.
@@AlexCSharp Можно у тебя взять урок по архитектуре ?
@@ИгорьКочат Конечно, под видео моя тг.
без dependency injection?
В смысле без IoC? это не относится к архитектуре, каждый сам решает, как именно управлять созданием объектов и их циклом жизни.
+++++
Слишком много повторяющегося кода. Меня это немного напрягает :)
Таковы правила игры. Претензии к создателям слоистых архитектур. Главное, при устройстве на работу никому этого не говори.
а где ApplicationContext???
Чтобы что? Это на откуп тех, кто пишет приложение. Я описывал бизнес-составляющую.
@@AlexCSharp понял