Wiki
Небольшое вступление и пояснение к некоторым будущим записям из рубрики Процесс. С недавнего времени я начал работать в компании, где надо полностью поднять весь процесс разработки ПО. Заметки по ходу этого действа будут появляться чаще и порой без кода совсем. У меня просьба к читателям высказывать свое мнение и наработки, по освещаемым вопросам. Ну и я надеюсь, что в результате такой работы будет много интересного материала и пищи для размышления.
Еще из необходимого ПО я считаю надо ставить wiki. К сожалению, предыдущий опыт не был сильно удачен. До этого я пробовал ставить википедии с помощью WebPlatform, насчет самой платформы нареканий нет, но представленные на тот момент википедии удручали. Одна не смогла доставить MySQL, да и сам MySQL не особенно желанный гость на моей машине. Второй движок ScrewWiki – вполне оправдывает свое название. Нифига не работает, редактирование паршивое, оформление тоже. Было решено отказаться от такого счастья. Поиск других движков не выглядел радужной перспективой и на какой-то момент я бросил это дело.
На днях снова заглянул в Web Platform Installer и обнаружил там новый движок для википедии, блогов, рассылок и чего-то в духе твиттера. Называется Incentive. До 10 зарегистрированных пользователей бесплатно.
Правила оформления кода C# v1.0
Волею судеб я попал в "девственные леса" организации, где не было разработок на C# и надо поставить все процессы с нуля. Систему контроля версий, процесс работы, сбор требований и учет работы. Правила оформления кода. Как раз первую версию такого документа я представляю на ваш суд. Я руководствуюсь исключительно своими предпочтениями в оформлении кода, которые позволяют мне быстро и эффективно ориентироваться по коду приложения.
Здесь отражено только форматирование кода, нет указаний на code smell или какие-либо еще недочеты в самом коде.
Если есть что добавить по существу, то прошу обсудить это в комментариях.
Краткое содержание:
- Переменные
- Использование VAR
- Именование методов
- Обрамление кода
- Комментарии
- Оформление блоков кода
- Свойства
- Логические операции
- Организация класса
Assert DSL 1.1
Никто уже не отрицает полезность тестов в любой сколько-нибудь сложной системе. Без тестов очень быстро можно скатиться в хаос и проводить большую часть времени в отладчике, занимаясь поиском и отловом косвенных эффектов от изменений той или иной части приложения. Тесты важны, нужны и так далее по тексту.
По науке, тесты являются документированием системы. Грамотно написанные тесты дают понять, как работает система, как ведет себя, причем читаться все это должно как готовая спецификация на поведение системы. Т.е. в идеале должен получаться связный и понятный текст. Это идеал, к которому постепенно приближаются методы тестирования, начиная от юнит тестирования и наиболее явно проявляясь в поведенческом/приемочном тестировании, когда сами тесты уже пишутся на языке бизнеса (в этом моменте вспоминаем Fitnesse).
При написании тестов не стоит скупиться на строчки кода и классы, важно только их правильно структурировать. Я считаю, что может быть вполне нормальной ситуация, когда у вас тестовый класс состоит только из одного метода – не надо этого стесняться, это гораздо лучше, чем классы на 20 экранов. HD экранов.
В общем, все должно быть направлено на максимальную ясность и четкость тестов, чтобы явно было видно все взаимосвязи. Чтобы можно было восстановить логику программы по одним лишь тестам. В дело читабельности пойдет не только Assert DSL (Domain Specific Language), но и именование файлов, подход Arrange Act Assert. Все это не новые подходы как оказывается, но широкой известности пока не получившие, судя по тому, что я вижу в окружающих меня проектах. Да и сам я натолкнулся на новые темы случайно, изучая исходные коды StructureMap.
Чтобы не томить, сразу расскажу какие основные шаги предлагаются для улучшения тестов:
- Именовать тестовые файлы по основному методу, который тестируется.
- Использовать DSL для создания объектов, чтобы методы делать максимально лаконичными.
- Стараться писать тесты в стиле «один тестовый метод – один assert».
- Структурировать внутренности теста.
- Создать и использовать Assert DSL.
Думаю что для большинства многие перечисленные пункты не новость, и почти все они применяются в реальной разработке.
Ненавистный INotifyPropertyChanged
Да, уже из названия видно мое отношение к интерфейсу INotifyPropertyChanged и к его явной реализации в проекте. Я покрываюсь мурашками, и меня бросает в дрожь только при одном виде такого кода:
private string description;
public string Description {
get { return description; }
set {
description = value;
RaisePropertyChanged("Description");
}
}
Какая растрата места на экране, какая колоссальная неэффективность написания кода, какая хрупкость в работе. Передача строковых переменных не может быть не хрупкой.
А когда таких свойств прописано с десяток и все это обернуто в регион (#region), то взгляд стекленеет, становится безжизненным и мозг отказывается верить в реальность происходящего. Конечно, самое большое зло от такого подхода – потеря времени на написание и на чтение.
Более того, это чистый инфраструктурный код, который не должен попадаться на глаза в логике приложения, только если специально его искать. Реализация INotifyPropertyChanged прямой и явный кандидат на реализацию в рамках аспектного-ориентированного программирования.
К сожалению, при разработке пользовательского интерфейса на WPF такая реализация «в лоб» встречается до сих пор сплошь и рядом. Не далее чем неделю назад вычищал такой код из рабочего проекта. Я бы порадовался за трудолюбие и усидчивость разработчиков пишущих такой код, но я склонен думать, что программист должен быть ленивым. В хорошем смысле. Так что лучше потерять немного времени на настройку и потом быстро-быстро все сделать. Далее я опишу 4 более-менее различных подхода к решению данной проблемы.
MS SQL 2011 (Denali) – Автономная база данных
В течение последних лет Microsoft внедрила множество интересных технологий, которые прочно вошли в арсенал разработчиков. Кардинальные изменения были включены в SQL Server 2005, после чего SQL Server 2008 развил и укрепил успех. Denali несет в себе множество новых инструментов, а так же расширений функционала для существующих. В этой статье в деталях рассмотрим один из новых инструментов, который, я уверен, придется по душе разработчикам баз данных. Этот инструмент, фича – автономные базы данных (Contained Database). Рассмотрим что они собой представляют, как с ними работать, к чему можно применить и другие вещи.
Что не так с текущими базами?
Перед тем как перейти к описанию сущности независимых баз данных, рассмотрим почему они были придуманы и чем не устраивает разработчиков текущая реализация.
Вот некоторые из ключевых проблем:
- Потеря информации во время разворачивания базы или передвижения ее между серверами.
Во время передвижения базы данных между серверами, то такая информация как логины, пароли, агенты заданий и прочее не может быть передвинуто вместе с базой. Потому что эта информация принадлежит серверу баз данных. Пересоздание упомянутых объектов руками не самое приятное занятие, которое к тому же занимает много времени и не гарантирует защиты от ошибок. - Различия между Разработкой и Разворачиванием приложений.
При разворачивании приложения разработчиков могут поджидать самые разные неприятности, начиная от несовпадения тонких настроек окружения, таких как разрешения на создание новых логинов, отключенная командная строка (xp_cmdshell), языковые настройки сервера. - Вопросы безопасности в администрировании приложения.
Весьма сложно администрировать и поддерживать отдельно стоящую базу данных из-за того, что, например, агенты задач доступны в пределах всего сервера, что влечет за собой повышение привилегий отдельно взятых пользователей. Однако эти повышенные права дают доступ к другим частям сервера, которые не желательно открывать. Все это может вести к серьезным проблемам безопасности.
После того, как обозначили ключевые недостатки существующих баз, перейдем к описанию нового типа.
MS SQL 2011 (Denali) – With Result Set
Модификация возвращаемого набора данных (NEW)
В оригинальном звучании и в жизни эта возможность звучит как With Result Set. Эта штука позволяет менять имена и типы данных в возвращаемом хранимой процедурой наборе данных.
Перед тем, как мы углубимся в детали использования данной возможности, рассмотрим, как предыдущие версии SQL серверов обходились с данными, которые возвращает хранимая процедура. Какие возможности они предоставляли для работы с результатом.
Для демонстрации работы будем использовать в качестве примера таблицу tbl_Test состоящую из 3 колонок.
MS SQL 2011 (Denali) — Throw
Служебное слово Throw (NEW)
Новое полезное дополнение для SQL Server 2011 (Denali) – выражение Throw. Разработчики на .Net уже догадались наверно, где и как оно будет использоваться.
Это слово может использоваться в сочетании с управляющей конструкцией Try…Catch и позволяет послать уведомление о возникновении ошибки времени исполнения. Когда возникает исключение, программа ищет ближайший по иерархии вверх блок Catch который может обработать исключение. Используя это выражение внутри блока Catch можно изменить вывод ошибки. Более того, теперь вызывать исключение можно произвольно в любом месте скрипта.
Далее рассмотрим различные способы поимки исключении, которые предоставляет SQL Server начиная с версии 2000.
MS SQL 2011 (Denali) – Offset
Offset и Fetch First\Next выражения – расширения команды Order By (NEW)
В новом SQL Server 2011 (Denali) расширяются возможности команды Order By с помощью двух долгожданных дополнительных команд:
- Offset (смещение)
- Fetch First или Fetch Next (взять первые… или взять следующие…)
Offset
Использование данной команды позволяет пропустить указанное количество строк перед тем как выводить результаты запроса. Что под этим подразумевается: Допустим, у нас есть 100 записей в таблице и нужно пропустить первые 10 строк и вывести строки с 11 по 100. Теперь это легко решается следующим запросом:
Select * From <SomeTable> Order by <SomeColumn> Offset 10 Rows
Для тех товарищей, которые практикуют .Net должен быть знаком метод расширения для коллекций Skip, который пропускает указанное количество строк. Так вот выражение Offset работает точно так же. После того как данные упорядочены каким-либо образом, можно применять выражение Offset.
MS SQL 2011 (Denali) – Sequence
Sequence (NEW) - последовательность
Возможность которой не удивишь нынче пользователей Oracle, DB2, PostgreSQL и множества других реляционных баз данных, наконец-то появилась и в SQL Server. На арене Sequence!
Sequence – генерирует последовательность чисел так же как и identity. Однако основным плюсом sequence является то, что последовательность не зависит от какой-либо конкретной таблицы и является объектом базы данных.
Рассмотрим пример скрипта написанного на SQL Server 2008. Создание простой таблицы с двумя колонками, одна из которых будет авто инкрементальной.
Create Table WithOutSequence1 ( EmpId int identity not null primary key ,EmpName varchar(50) not null ) Insert into WithOutSequence1 Select 'Violet' Union All Select 'Tape' Select * from WithOutSequence1
Похожим образом создадим еще одну таблицу.
Create Table WithOutSequence2 ( EmpId int identity not null primary key ,EmpName varchar(50) not null ) Insert into WithOutSequence2 Select 'Violet' Union All Select 'Tape' Select * from WithOutSequence2
Как можно заметить из примеров, мы записали значения в таблицу при этом значение инкрементального поля автоматически и независимо от нас заполнилось. Мы не можем повторно использовать значение этого поля в другой таблице. Давайте посмотрим какой выход дает Sequence из этой ситуации.
Общий синтаксис для команды выглядит так:
CREATE SEQUENCE [schema_name . ] sequence_name
[ AS { built_in_integer_type | user-defined_integer_type } ]
| START WITH <constant>
| INCREMENT BY <constant>
| { MINVALUE <constant> | NO MINVALUE }
| { MAXVALUE <constant> | NO MAXVALUE }
| { CYCLE | NO CYCLE }
| { CACHE [<constant> ] | NO CACHE }
