Современная технология разработки ПО направлена на решения проблемм сложности, а не на построение отдельных алгоритмов (для этого 5 лет ходят в ВУЗ).
Ни какой пацан, не зная проекта изнутри, ни когда не сможет сказать «что будет», если «зафигарить здесь полочку». Вспомните книги гуру — практикующих консультатов. Все их расказы начинаются с того, что они приходят на умирающий проект и пару дней разбираются с причинами — почему 10 человеколет еще не начали приносить прибыль. Гуру — знает об ограничениях своего восприятия, «пацан» — нет.
Идеи «пацанов» это не более чем одна из тысячи интерестных идей в мозговом штурме, которая должна еще пройти 5 фильтров и 5 трансформаций, чтобы стать возможно полезной.
Что здесь правда?
— 300 строк кода? Для меня и 25 много
— статики с изменяющимся состоянием? Попробуйте к такому проекту добавить логику о которой не предполагал автор (кода) — например еще один экземпляр SQL-фасада.
— Патерны. Согласен. Патерн не должен использоваться там, где нет необходимости в его конкретной фишки. И от патерна стоит избавиться там, где негатив от него превышает позитив.
— IoC. Согласен.
— Code first. В больших проектах, где к базе обращается 3-4 клиента разрабатываемых в разное время, разными группами. Когда у вас в компании 2 десятка баз синхронизируются друг с другом. Когда у вас есть таблицы с 1.5*10^9 строк. Удачи.
Как я и говорил автор не прав и ни неправ одновременно. У меня у самого есть воззрения достойные халевара, но я же не говорю что сообщество «не доросло до моего уровня, чтобы понять их глубину и проницательность».
К сожелению, не дождался ответа на свой вопрос, поэтому продолжаю свою мысль. Подход совмещения контрактов с юнит тестами напоминает вариант построения тестов на тестируемом классе. То есть, некоторый класс A содержит не только полезный функционал, но и тесты проверяющие его. Недостаток такого подхода очевиден — слишком много кода в классе.
Перед переходом на TDD, я пользовался контрактам. Тогда они были достаточно архаичными — System.Debug.Assert. Доходило до смешного — рядом с двумя строчками полезного кода распологался десяток Assert-ов. Два три экрана кода, при удалении «мусора» превращались в пол экрана.
Я потому и спрашивал. Может контракты и правда жизнеспособны? Разбиваем 100500 тестов на группы. Называем каждую из них «контрактом». Награждаем ими конкретные классы (хоть десять контрактов на один класс). В тестах запускаем проверку Типа на соответствие всем его контрактам. Как частный случай проверки, может сработать.
А существуют способы ассоциировать ContractClassForAttribute с набором тестов (стандартные)? Грубо, если класс награжден контрактом, то для него среда тестирования автоматически вызовет 1,2,3… тесты. Ну или с минимальными усилиями хотябы — пишим тест с телом одну строку? типа ContractClassForAttribute.Assert(()=>new AAA()).
Надо сокращать наборы данных на которых фактически выполняются тесты, например вводом фиктивных параметров в хранимки и WHILE (@a is null or @a=tbl.field)
Я понимаю, что у этой задачи есть множество решений разной степени сложности. Когда я только начинал писать тесты, я пользовался рефлексией — за что мне до сих пор стыдно.
Вопрос в том, какой профит мы хотим от этого получить: пользоваться сингелтоном за его изящество (меня он восхитил в первый раз именно этим) или принять, что это просто глобальная видимость. «Сложность» тестирования, подсистем использующих глобальные сущности, это не самая серьезная из их проблем. Так есть ли смысл ее решать?
И сразу получаем проблему независимости тестов. Определяем TestInitialize и TestCleanup. Получаем проблемму с конфигурирование отдельных тестов. Определяем класс очистки и установки среды через IDisposable с параметрами в конструкторе — получаем сложную систему подготовки среды к тестирования.
И зачем такие финты ушами? Что бы получить доступ из любого места в коде к объекту. То есть — это обычная глобальная видимость. Но нам то хочется еще и временем жизни упровлять. Противоречие.
Решение:
Передаем объект от GetInstance через параметр (конструктора или метода) и забываем о всех проблеммах раз и на всегда. По сути отказываемся от сингелтона.
Именно поэтому, широко известные в узких кругах гуру советуют делать везде, где только можно минимальную реализация и пользоваться рефакторингом для дальнейшего развития. Так и говорят: «Если у кого и получается предсказывать будущее, то ему очень повезло. А я по старинке»
1. Тесты (или тест?) после кода
2. Тесты не как не повлияли на построение архитектуры, она целиком была сделана на бумаге. Driving-а (да и Design-а тоже) из аббревиатуры TDD нет
3. Нет и намека о ритме
4. Второй описанный (возможно, другие не были описанные) — точно не UnitTest. Или это небыл тест? Тогда sorry.
С использованием автотестирования — да. Но не TDD.
Но основной тезис «Тест – это не дополнение к коду, но его важная часть» классный.
У меня на Moq не получилось переопределить виртуальный метод у класса. Rhino справился. Может конечно я не знаю как. А так, использование Moq немного удобнее. ИМХО, конечно
Как это не будут? Объект будет обязательно создан, только ссылка потеряется. И при попытке, удалить файл до сборки мусора поднимется исключение по доступу.
Выполнение описываемых предписаний не защитят вас от проблем между строками «var tmpFile» и «try» (например, из-за асинхронных исключений). Они скорее говорят как уменьшать вероятность возникновения проблем, уменьшив прослойку. Для полной уверенности надо предпринимать отдельные усилия, подобные habrahabr.ru/post/144240/#comment_4841489
Мне кажется, что проблемы не существует при понимании работы using(...). Все что в скобках — не финализируется; в теле — финализируется.
А вообще напоминает объявление переменных через запятую: int a,b;
Я когда это вижу всегда коллег спрашиваю: «Что это?». Когда получаю ответ — до меня доходит. Вот и здесь сидел и думал: «А в чем суть?». Смешно то, что +2 строки. Удачный сахарок. Я не про инициализацию вообще, только вместе с using. Не конструкция — беременный гиппопотам.
В общем, если бы анализировал этот код перетащил бы определение параметров в тело только бы из эстетических соображений. И не когда бы не узнал, что пофиксил страшный баг.
Но в ней и не сказано, что это проблема решается путем отказа от статиков.
Еще раз — это проблема времени жизни объекта (или метаобъекта, если хотите) и решается она явным его определением. Все остальное — это нейтрализация тонких особенностей с помощью других тонких тонких особенностей функционирования CLR.
Не жалко себя, подумайте обо мне. Прихожу я завтра в вашу организацию и получаю код, который работает только потому, что статическое поле «abc» находится в классе «def». Если перенести его в «ghi» все разваливается. Как вы думаете, долго будет спасать вас дверь туалетной кабинки?
Современная технология разработки ПО направлена на решения проблемм сложности, а не на построение отдельных алгоритмов (для этого 5 лет ходят в ВУЗ).
Ни какой пацан, не зная проекта изнутри, ни когда не сможет сказать «что будет», если «зафигарить здесь полочку». Вспомните книги гуру — практикующих консультатов. Все их расказы начинаются с того, что они приходят на умирающий проект и пару дней разбираются с причинами — почему 10 человеколет еще не начали приносить прибыль. Гуру — знает об ограничениях своего восприятия, «пацан» — нет.
Идеи «пацанов» это не более чем одна из тысячи интерестных идей в мозговом штурме, которая должна еще пройти 5 фильтров и 5 трансформаций, чтобы стать возможно полезной.
Что здесь правда?
— 300 строк кода? Для меня и 25 много
— статики с изменяющимся состоянием? Попробуйте к такому проекту добавить логику о которой не предполагал автор (кода) — например еще один экземпляр SQL-фасада.
— Патерны. Согласен. Патерн не должен использоваться там, где нет необходимости в его конкретной фишки. И от патерна стоит избавиться там, где негатив от него превышает позитив.
— IoC. Согласен.
— Code first. В больших проектах, где к базе обращается 3-4 клиента разрабатываемых в разное время, разными группами. Когда у вас в компании 2 десятка баз синхронизируются друг с другом. Когда у вас есть таблицы с 1.5*10^9 строк. Удачи.
Как я и говорил автор не прав и ни неправ одновременно. У меня у самого есть воззрения достойные халевара, но я же не говорю что сообщество «не доросло до моего уровня, чтобы понять их глубину и проницательность».
Перед переходом на TDD, я пользовался контрактам. Тогда они были достаточно архаичными — System.Debug.Assert. Доходило до смешного — рядом с двумя строчками полезного кода распологался десяток Assert-ов. Два три экрана кода, при удалении «мусора» превращались в пол экрана.
Я потому и спрашивал. Может контракты и правда жизнеспособны? Разбиваем 100500 тестов на группы. Называем каждую из них «контрактом». Награждаем ими конкретные классы (хоть десять контрактов на один класс). В тестах запускаем проверку Типа на соответствие всем его контрактам. Как частный случай проверки, может сработать.
Вопрос в том, какой профит мы хотим от этого получить: пользоваться сингелтоном за его изящество (меня он восхитил в первый раз именно этим) или принять, что это просто глобальная видимость. «Сложность» тестирования, подсистем использующих глобальные сущности, это не самая серьезная из их проблем. Так есть ли смысл ее решать?
И зачем такие финты ушами? Что бы получить доступ из любого места в коде к объекту. То есть — это обычная глобальная видимость. Но нам то хочется еще и временем жизни упровлять. Противоречие.
Решение:
Передаем объект от GetInstance через параметр (конструктора или метода) и забываем о всех проблеммах раз и на всегда. По сути отказываемся от сингелтона.
1. Тесты (или тест?) после кода
2. Тесты не как не повлияли на построение архитектуры, она целиком была сделана на бумаге. Driving-а (да и Design-а тоже) из аббревиатуры TDD нет
3. Нет и намека о ритме
4. Второй описанный (возможно, другие не были описанные) — точно не UnitTest. Или это небыл тест? Тогда sorry.
С использованием автотестирования — да. Но не TDD.
Но основной тезис «Тест – это не дополнение к коду, но его важная часть» классный.
Выполнение описываемых предписаний не защитят вас от проблем между строками «var tmpFile» и «try» (например, из-за асинхронных исключений). Они скорее говорят как уменьшать вероятность возникновения проблем, уменьшив прослойку. Для полной уверенности надо предпринимать отдельные усилия, подобные habrahabr.ru/post/144240/#comment_4841489
точно не лучше
А вообще напоминает объявление переменных через запятую: int a,b;
Я когда это вижу всегда коллег спрашиваю: «Что это?». Когда получаю ответ — до меня доходит. Вот и здесь сидел и думал: «А в чем суть?». Смешно то, что +2 строки. Удачный сахарок. Я не про инициализацию вообще, только вместе с using. Не конструкция — беременный гиппопотам.
В общем, если бы анализировал этот код перетащил бы определение параметров в тело только бы из эстетических соображений. И не когда бы не узнал, что пофиксил страшный баг.
Еще раз — это проблема времени жизни объекта (или метаобъекта, если хотите) и решается она явным его определением. Все остальное — это нейтрализация тонких особенностей с помощью других тонких тонких особенностей функционирования CLR.
Не жалко себя, подумайте обо мне. Прихожу я завтра в вашу организацию и получаю код, который работает только потому, что статическое поле «abc» находится в классе «def». Если перенести его в «ghi» все разваливается. Как вы думаете, долго будет спасать вас дверь туалетной кабинки?