Pull to refresh
7

User

Send message
угол атаки переднего антикрыла обязательно подкручивают при переходе на дождевую резину
Мне всегда нравились примеры с «пацанами»…

Современная технология разработки ПО направлена на решения проблемм сложности, а не на построение отдельных алгоритмов (для этого 5 лет ходят в ВУЗ).

Ни какой пацан, не зная проекта изнутри, ни когда не сможет сказать «что будет», если «зафигарить здесь полочку». Вспомните книги гуру — практикующих консультатов. Все их расказы начинаются с того, что они приходят на умирающий проект и пару дней разбираются с причинами — почему 10 человеколет еще не начали приносить прибыль. Гуру — знает об ограничениях своего восприятия, «пацан» — нет.

Идеи «пацанов» это не более чем одна из тысячи интерестных идей в мозговом штурме, которая должна еще пройти 5 фильтров и 5 трансформаций, чтобы стать возможно полезной.
Я прочитал всю статью, а не только обзор.

Что здесь правда?
— 300 строк кода? Для меня и 25 много
— статики с изменяющимся состоянием? Попробуйте к такому проекту добавить логику о которой не предполагал автор (кода) — например еще один экземпляр SQL-фасада.
— Патерны. Согласен. Патерн не должен использоваться там, где нет необходимости в его конкретной фишки. И от патерна стоит избавиться там, где негатив от него превышает позитив.
— IoC. Согласен.
— Code first. В больших проектах, где к базе обращается 3-4 клиента разрабатываемых в разное время, разными группами. Когда у вас в компании 2 десятка баз синхронизируются друг с другом. Когда у вас есть таблицы с 1.5*10^9 строк. Удачи.

Как я и говорил автор не прав и ни неправ одновременно. У меня у самого есть воззрения достойные халевара, но я же не говорю что сообщество «не доросло до моего уровня, чтобы понять их глубину и проницательность».
Сплошное ИМХО автора, возведенное в абсолют. С некоторыми тезисами я бы согласился, по некоторым начал «грызню». В общим, тролинг чистой воды.
К сожелению, не дождался ответа на свой вопрос, поэтому продолжаю свою мысль. Подход совмещения контрактов с юнит тестами напоминает вариант построения тестов на тестируемом классе. То есть, некоторый класс A содержит не только полезный функционал, но и тесты проверяющие его. Недостаток такого подхода очевиден — слишком много кода в классе.

Перед переходом на TDD, я пользовался контрактам. Тогда они были достаточно архаичными — System.Debug.Assert. Доходило до смешного — рядом с двумя строчками полезного кода распологался десяток Assert-ов. Два три экрана кода, при удалении «мусора» превращались в пол экрана.

Я потому и спрашивал. Может контракты и правда жизнеспособны? Разбиваем 100500 тестов на группы. Называем каждую из них «контрактом». Награждаем ими конкретные классы (хоть десять контрактов на один класс). В тестах запускаем проверку Типа на соответствие всем его контрактам. Как частный случай проверки, может сработать.
Не до конца отформатировал сообщение. Отправил раньше времени. Sory.
А существуют способы ассоциировать ContractClassForAttribute с набором тестов (стандартные)? Грубо, если класс награжден контрактом, то для него среда тестирования автоматически вызовет 1,2,3… тесты. Ну или с минимальными усилиями хотябы — пишим тест с телом одну строку? типа ContractClassForAttribute.Assert(()=>new AAA()).
договоренность по использованию (точнее не использованию) транзакций в хранимках. По крайней мере для тестируемых
Надо сокращать наборы данных на которых фактически выполняются тесты, например вводом фиктивных параметров в хранимки и WHILE (@a is null or @a=tbl.field)
Я понимаю, что у этой задачи есть множество решений разной степени сложности. Когда я только начинал писать тесты, я пользовался рефлексией — за что мне до сих пор стыдно.

Вопрос в том, какой профит мы хотим от этого получить: пользоваться сингелтоном за его изящество (меня он восхитил в первый раз именно этим) или принять, что это просто глобальная видимость. «Сложность» тестирования, подсистем использующих глобальные сущности, это не самая серьезная из их проблем. Так есть ли смысл ее решать?
И сразу получаем проблему независимости тестов. Определяем TestInitialize и TestCleanup. Получаем проблемму с конфигурирование отдельных тестов. Определяем класс очистки и установки среды через IDisposable с параметрами в конструкторе — получаем сложную систему подготовки среды к тестирования.

И зачем такие финты ушами? Что бы получить доступ из любого места в коде к объекту. То есть — это обычная глобальная видимость. Но нам то хочется еще и временем жизни упровлять. Противоречие.

Решение:
Передаем объект от GetInstance через параметр (конструктора или метода) и забываем о всех проблеммах раз и на всегда. По сути отказываемся от сингелтона.
Именно поэтому, широко известные в узких кругах гуру советуют делать везде, где только можно минимальную реализация и пользоваться рефакторингом для дальнейшего развития. Так и говорят: «Если у кого и получается предсказывать будущее, то ему очень повезло. А я по старинке»
Тесты для TDD не составляются, а пишутся. И не в момент продумывания архитектуры, а при вводе каждого нового элемента поведения.
Не считайте меня снобом, но описаное не TDD.

1. Тесты (или тест?) после кода
2. Тесты не как не повлияли на построение архитектуры, она целиком была сделана на бумаге. Driving-а (да и Design-а тоже) из аббревиатуры TDD нет
3. Нет и намека о ритме
4. Второй описанный (возможно, другие не были описанные) — точно не UnitTest. Или это небыл тест? Тогда sorry.

С использованием автотестирования — да. Но не TDD.

Но основной тезис «Тест – это не дополнение к коду, но его важная часть» классный.
У меня на Moq не получилось переопределить виртуальный метод у класса. Rhino справился. Может конечно я не знаю как. А так, использование Moq немного удобнее. ИМХО, конечно
надо выделить код и в комбобоксе выбрать C#
Как это не будут? Объект будет обязательно создан, только ссылка потеряется. И при попытке, удалить файл до сборки мусора поднимется исключение по доступу.

Выполнение описываемых предписаний не защитят вас от проблем между строками «var tmpFile» и «try» (например, из-за асинхронных исключений). Они скорее говорят как уменьшать вероятность возникновения проблем, уменьшив прослойку. Для полной уверенности надо предпринимать отдельные усилия, подобные habrahabr.ru/post/144240/#comment_4841489
Я как раз утверждаю, что

using(new A("a")
	{
		B=1
	})
{
	//какой-то код
}


точно не лучше

using(var a=new A("a"))
{
	a.B=1;
	//какой-то код
}

Мне кажется, что проблемы не существует при понимании работы using(...). Все что в скобках — не финализируется; в теле — финализируется.

А вообще напоминает объявление переменных через запятую: int a,b;
Я когда это вижу всегда коллег спрашиваю: «Что это?». Когда получаю ответ — до меня доходит. Вот и здесь сидел и думал: «А в чем суть?». Смешно то, что +2 строки. Удачный сахарок. Я не про инициализацию вообще, только вместе с using. Не конструкция — беременный гиппопотам.

В общем, если бы анализировал этот код перетащил бы определение параметров в тело только бы из эстетических соображений. И не когда бы не узнал, что пофиксил страшный баг.
Но в ней и не сказано, что это проблема решается путем отказа от статиков.

Еще раз — это проблема времени жизни объекта (или метаобъекта, если хотите) и решается она явным его определением. Все остальное — это нейтрализация тонких особенностей с помощью других тонких тонких особенностей функционирования CLR.

Не жалко себя, подумайте обо мне. Прихожу я завтра в вашу организацию и получаю код, который работает только потому, что статическое поле «abc» находится в классе «def». Если перенести его в «ghi» все разваливается. Как вы думаете, долго будет спасать вас дверь туалетной кабинки?
1
23 ...

Information

Rating
Does not participate
Registered
Activity