Примеры C#. DataGenerator. Структура проекта
HTML-код
- Опубликовано: 16 фев 2016
- Начинаем практику по C#! Задача - создать генератор скрипта. Формализуем требования, выстраиваем структуру проекта, создаем первый интерфейс.
Поддержи развитие канала! money.yandex.ru/to/4100139057...
Qiwi Wallet +79534684569
Группа ВКонтакте: easycomp
Файлы с данными: drive.google.com/file/d/0B1nj...
мне понадобилось несколько лет чтобы понять всю важность фиксации технического задания(правда в другой области)! Это колоссальный совет, и он показывает по крайней мере, лично мне, что автор ролика действительно специалист. Спасибо за видео!
Добрый день.
Никогда не пишу коментарии но тут уже не удержался.
Спасибо большое за труд, видео про многопоточность пересматривал несколько раз чтобы словить все детали.
Работаю на позиции мидла в небольшой команде и как-раз есть ощущение что недостаточно умений и знаний как правильно организовать проект, разделить на слои. Также не пользуемся юнит-тестами, хотя очень хочется.
Так что мне очень нравится идея вести "живой "проект с 0, показать как делать все чисто и аккуратно, как думать.
Жду с нетерпение новые уроки.
Дядька ты лучший!!! Более понятного изложения я еще не встречал.
Превосходно! И TDD, DI и рефакторинг! Спасибо, что поделились своими знаниями и изложили столь доступно!
Очень интересные уроки. После каждого просмотренного хочется смотреть ещё и ещё!
Огромнейше благодарю) Прекрасный урок.
Спасибо за урок, у вас все очень понятно и интересно. Поддержу канал
Отличный урок, то что надо. Особенно то что коснулись юнит тестов. Всегда хотел увидеть как это работает на практике :) Жду продолжения .
Как всегда супер познавательно и полезно. С нетерпением в ожидании следующего урока. Большое спасибо.
Круто! Мне очень не хватало этих знаний! Спасибо
Просто молюсь на эти уроки! )))
Игорь, Спасибо Вам! Еще раз поддержу проект.
Как всегда на высоте. Круто👍👍👍
ооо, как я вижу вы начали снова поддерживать канал. очень рад, спасибо вам большое)
0. Задание.
1. Создания солюшена с начальным проектом.
2. Сразу добавляем библиотеку для бизнес-логики.
3. Наша логика не должна зависеть от поставщика данных.
По этому нужна еще одна библиотека.
Мы берем данные с файлов, но могли бы брать с БД или с веб-сервера.
Чтобы абстрагировать бизнесс логику от поставщика данных мы обработку данных вынесем в отдельную библиотеку.
4. У нашего приложения как у всякого уважающего себя приложения должны быть юнит-тесты.
Юнит-тесты принято хранить в отдельной папке, делаем её и называем Test.
5. Добавляем в нее две библотеки: для тестирования библиотеки .BL, а другую для тестирования библиотеки .Data
Названия делаем такими же как и у тестируемых библиотек, только добавляем ".Test" .
6. Для тестирования будем использовать библиотеку NUnin. Необходимо ее подключить к обеим тестовым библиотекам.
Получаем ее через NeGet. ПКМ на солюшене -> Manage NuGet Packages for Solutions... -> NUnit
Перед инсталляцией пакетов ставим галочки только напротив библиотек из папки Test. Альтернатива - встроеный MSTest.
7. Добавляем заранее подготовленные файлы со словами для генератора.
В заголовке Solution Explorer-a (предворительно выбрав ЛКМ папку TestDataGenerator) нажимаем кнопку "Show all files",
и видим "пунктирную папочку" Files. Делаем на ней ПКМ и выбираем "Include in Project".
Структура проекта завершена. (Я еще добавил ReadMe.txt для этого описания)
8. По гендерному признаку в словах отличаются только имена.
9. Начинаем разработку с бизнес-логики (а не с интерфейса или БД, что тоже возможно).
10. Надо создать скрипт, тогда начинаем с создания класса, который будет этот скрипт создавать.
Добавляем этот класс (вернее интерфейс, что важно) в библиотеку бизнес-логики Add -> New Item -> Interface.
Интерфейс позволяет сосредоточится на создании самих методов, а не их реализации.
Класс должен только создавать скрипт, а не парсить файлы или записывать итог в файл или отправлять его на сервер,
если такое будет, его надо будет рефакторить и разбивать.
11. IScriptGenerator
string CreateScript(); на этом часто проектирование заканчивается, но что если мы захотим менять кол-во строк скрипта...
добавляем параметр entityCount - количество записей в скрипте.
12. Кроме того надо дать возможность потребителю класса манипулировать выдаваемые данные.
Нам нужен объект, где эти данные будут храниться, в него же данные будут попадать после того
как мы их распарсим из исходных файлов. По логике этот класс должен храниться
в пространстве имен Data. Добавляем UserEntity туда. Это "плоский класс" или "Poco object" (он не будет связан
ни какими отношениями ни с какими другими классами) и предназначен для хранения информации.
Все его свойства предназначены для генерирования строки с данными в нашем скрипте... или в других задачах можно
записывать эти данные в БД, или генерить XML-файл, или отправить на вэб-сервер,..
13. Возвращаемся в интерфейс и добавляем метод UserEntity GentrateUser(); Его задача создать один
объект с данными, предназначенного для генерации одной строки с данными.
Ведь потребитель захочет создать строку с данными на своей стороне, в своем формате.
И ему необходимо получить объект, представляющий эту строку.
Но тип UserEntity сразу не виден, т.к. находится в др. сборке чем наш интерфейс.
Добавляем в References ссылку на проект TestDataGenerator.Data и строку "using TestDataGenerator.Data;" ,
подключая пространство имен.
14. Добавляем метод string GetValueLine(UserEntity entity); Этот метод (как видно из сигнатуры) превращает
нашу сущность пользователя в строку, которая используется в нашем скрипте, т.е. в одну строку скрипта.
Но тут вопрос, зачем этому методу параметр? Ведь можно было его исключить и сразу получить искомую строку.
Так тоже можно сделать, но с параметром мы а) можем протестировать логику получения отдельно взятого
пользователя (метод UserEntity GenerateUser() ); б) отдельно получить механизм преобразования нашего
пользователя в строку; в) кроме этого, потребитель нашего класса имеет UserEntity код с другого источника,
например, он самостоятельно решил добавить в наш скрипт какую-то строку, тогда он создает на своей стороне
сущность UserEntity с помощью своих тестовых данных, а не тех, которые мы считываем с репозитария, и получает
строку для своего скрипта. Метод string GetValueLine(); можно было бы оставить в качестве перегруженного.
15. Добавляем метод string GetInsertLine();; что бы кроме строки с данными мы могли получить и стартовую строку.
Строка будет константной ("INSERT LINE... VALUES").
16. Интерфейс готов и можно приступать к его тестированию (покрыть его unit-тестами)!
Как же так??? Ведь реализации нет, кода нет.
Этот подход называется "Разработка через тестирование" (Test Driving Development).
+Serge Pikovsky Ого, конспект )
+Программирование - это просто
Смейтесь, смейтесь... я, между прочим, сделал конспект, чтобы не крутить урок в поисках недопонятых деталей, так что, я думаю, вам стоит подумать, чтобы прибить эти конспекты втихую. :-)
Я совсем не смеюсь, конспекты - очень хорошее дело
Ты крут=)
Большое спасибо!
Хороший урок! Когда второй будет!
Очень полезный урок! Спасибо большое за труды!
Но хотелось бы немного больше информации про низкоуровневую работу той или иной строчки кода, желательно с картинками связей потоков данных из одного класса в другой, от одной строчки кода к другой. Тогда будет предельно доходчиво. (очень надеюсь, что это возможно для автора)
Хотя и так всё шикарно, ещё раз спасибо! :-)
Очень хорошие уроки)
Хорошее видео.
спасибо за урок
Круто!
супер
Ооооооо дааааааа ТО ЧТО НУЖНО!
Спасибо!
доступно и понятно, и главное логически верно и просто ) спасибо за урок
у меня возникли такие вопросы
1. зачем вы создаете проект под каждую из частей программы?
почему бы не использовать в 1 проекте и данные и бизнес логику, разделив допустим неймспейсы по каталогам:
например:
DataGenerator
+ Logic
* IScriptGeneratot
* BL.cs
+ Data
* UserEntity.cs
* DataType1.cs
тогда в одном проекте сохранилась бы целостность данных и методов работы с ними.
2. мне кажется - было бы удобней поместить метод GetValueLine в класс UserEntity, который эти данные и содержит
Занятие очень понравилось, больше Вам спасибо.
+Иван Анфёров хорошие вопросы, постараюсь на них ответить в следующем видео )
Спасибо Вам.
Игорь , спасибо за ваши видео. Хотел дополнить. У вас зависимость направлена не в ту сторону, согласно чистой архитектуре Роберта Мартина, бизнес логика не должна зависеть от слоя который предоставляет доступ к данным, поэтому стоить объект UserEntity переместить в слой с бизнеслогикой, и обратить зависимости в обратную сторону, что бы все детали(слой доступа к данным и тд) зависили от нее.
интересно, но непонятно, жду продолжения. ибо все эти награмождения классов, ради награмождения классов меня, всегда напрягают - ссылок между классами и методами до и больше, в итоге объявления и описания занимают места больше чем реализация (несколько раз встречал такое, ноль документации, минимум комментариев и много много классов, а в результате сотня другая строк тривиального кода, в лютой обертке) . надеюсь в следующих выпусках будет наглядно показана польза от этой иерархии.
+Mikhail Kh Какие нагромождения? Пока у нас только 1 класс и 1 интерфейс.
+Программирование - это просто и еще пять обьявлений, к реализации которых не приступали.
я это не в укор, а по незнанию. поэтому очень интересно как это все развернется. но если сделаете обзор преимуществ сравнительный - было бы отлично.
я бы сделал гуй, да пяток методов в одном классе. понимаю что это не правильно. но вот почему имено никак не возьму в толк.
Здравствуйте, у меня к Вам вопрос, сразу хочу написать, что Ваши уроки мне очень по нраву, Вы очень качественно объясняете материал. А теперь, когда я к Вам уже достаточно подлизался, так сказать, ответьте, пожалуйста, на мой вопрос, потому что мне кажется, что вы мне можете помочь в этом вопросе.
Мой преподаватель дал мне задание на диплом, состоит оно в том, чтобы на "главном" компьютере локальной сети было установлено приложение WinForms, на котором бы в PictureBox'es высвечивались рабочие столы компьютеров в реальном времени, то есть, кто куда лазит, что делает, типо слежка.
Так вот, получить рабочий стол в PictureBox вышло, но как организовать структуру клиент-серверную, чтобы в локальной сети это работало.
Мне посоветовали использовать WCF, но я в растерянности пока что, посоветуйте, как быть, что почитать, может и правда использовать WCF?
Ещё!
Подкреплю данатом проек.
что за расширение, сигнализирующее об ошибке? и где вы меняли цветовую гамму для отображения методов(нашел практически для всего, а вот методов не вижу)? спасибо.
+13danyocean13 Это всё Resharper
Здравствуйте! Что бы вы порекомендовали почитать по проектированию и разработке ПО?
+Sergei Derunov Начните с книг Фаулера. "Архитектура корпоративных приложений" и "Рефакторинг"
+Программирование - это просто
Спасибо! Почитал отзывы - что надо!
И за уроки Спасибо!
День добрый, Если говорить об архитектуре, то нужно говорить правильно. Слои нужны не только для того о чем вы говорили. Слои это библиотеки. Библиотеки должны быть самодостаточными, независимыми друг от друга. По моему это здесь обычно ссылаются на принцип SOLID.
По порядку.
DAL.Contexts
Контекст должен быть в отдельной библиотеке,
DAL.Domains
Domain модели в отдельной библиотеки,
DAL.Facade
интерфейс IRepository в отдельной библиотеке там же где и интерфейс IUnitOfWork,
DAL.Repositories
реализация всех Repository в отдельной библиотеке,
BLL.Facade
интерфейсы сервисов + их DTO классы в отдельной библиотеке,
BLL.Services
сами сервисы + паттерны в отдельной библиотеке
UI.Facade
ViewModels тоже желательно содержать отдельно от UI. Сегодня ваш проект WinForms, а завтра сайт или мобильное приложение. Чтобы не копировать / переписывать модели выносим в отдельную библиотеку.
Далее рекомендации использовать AutoMapper и Ninject. НО как, где распологать их классы?
Например если нужно создать Map для Domain и Dto модели, где должен распологаться класс Map?
Ведь если мы расположим этот класс в UI то мы притащим за собой DAL.Domain или это норма?
Как итог.
Могли бы вы показать как в данном проекте, а еще лучше в WinForms проекте сделать слабо связанные слои с использованием AutoMapper и Ninject?
Если нет желания создавать еще 1 видео, то могли бы вы объяснить как использовать AutoMapper и Ninject ответив в коментарии?
Заранее спасибо.
Есть какая-то объективная причина использовать NUnit вместо встроенного в вижуалку инструментария? Или просто дело привычки?
+Sheogorath Дело практики. Я работаю с NUnit. Но подход одинаков, если кто-то захочет использовать MSTest - пожалуйста, суть не изменится.
+Sheogorath пробовал и NUnit и MSTest, NUnit значительно удобней.
Как говорил мой дед,- проектируй на уровне интерфейсов, а не классов.
Почему следующее видео с ограниченным доступом?
+Саша Черкашин Они в процессе редактирования
А что такое скрипт?
В классе UserEntity на видео нет метода GenerateUser()..
+Nik Brons Его там и не должно быть. Этот метод находится в интерфейсе IScriptGenerator.
+Программирование - это просто, В интерфейсе IScriptGenerator добавляется ссылка на TestDataGenerator.Data, после чего ошибка пропадает. В общем, что делает GenerateUser()?
+Nik Brons Реализация этого метода будет в следующих уроках. GenerateUser создает UserEntity на основании бизнес-правил и данных в файлах.
+Программирование - это просто, ну вот теперь все понятно!
Аааа 😵 как громко!
А где файлики обещаные на 06:28?
+Uladzimir F выложил drive.google.com/file/d/0B1njhfJVtfRpX0lLMmJjVHkxZXc/view?usp=sharing
+Uladzimir F не рекомендую пользоваться "файликами"
На своём опыте убедился что всё руками надо повторять - так закрепляется намного лучше.
Файл посмотрел - всё понятно вроде - а повторить сложности возникают. Это как с английским языком - навык чтения и слушания идёт отдельно от письма и говорения
Этот подход называется - как у начинающего программиста вызвать отвращение к программированию на всю оставшуюся жизнь. Там еще Кнут говорил, что преждевременная оптимизация - корень всех зол. Бритва Оккама - о том, что не стоит плодить сущности сверх необходимости. Минимализм, решение проблем по мере возникновения - все по бороде. Видео о том, как не написав ни строчки полезного кода превратить свой проект в Франкенштейна, испугаться его, и до конца жизни вздрагивать при слове "программирование".
А я уж было думал что один с ума схожу с таких подходов к казалось бы простым вещам))
Разработчики языка хотят упростить людям написание программ, а люди сами себе эту задачу усложняют и городят огороды.