-->

пятница, 5 июня 2015 г.

Соглашения по оформлению кода C#

Недавно наша команда приняла соглашение по оформлению кода, в составлении и продвижении которого я принимал непосредственное участие. Мы не стали изобретать велосипед и взяли за основу соглашения от команды RSDN, дополнив их. Надеюсь, теперь в рабочем коде будет чуть меньше хаоса. Ниже приводится текст принятого документа (чуть съехала верстка):

Цели документа:
       выработать единый стиль написания кода;
       облегчить понимание кода всеми участниками команды;
       предоставить критерии качества оформления кода.

Введение
За основу берем известные многим Соглашения по оформлению кода команды RSDN. ВСЕ соглашения необходимо соблюдать, поэтому начните с чтения статьи по ссылке.
В документе рассматривается только форматирование кода (без паттернов, code smells, рефакторингов и т.п.). Также мы собираем свод дополнительных правил по оформлению, которые каждый может дополнить своим наболевшим. Дополнительные правила приводятся ниже:

1. Общие правила (еще раз)
    Помните! Код чаще читается, чем пишется, поэтому не экономьте на понятности и чистоте кода ради скорости набора.
    Старайтесь не использовать сокращения лишний раз, помните о тех, кто читает код.
    В то же время, делайте имена идентификаторов как можно короче (но не в ущерб читабельности).
    Используйте имена с простым написанием. Их легче читать и набирать.

2. Отступы, пробелы и прочее форматирование
    Форматируйте код при помощи команды Format Document (Ctrl+K, Ctrl+D)  в Visual Studio, это решит большинство проблем с форматированием. Не пренебрегайте автогенерацией кода ReSharper.

3. Именование
3.1. Общее
    Еще раз, хватит сокращать слова, мы не в 70-х и мониторы у нас не 12”.
Плохо:            SelectProds, GetPns
Хорошо:          SelectProducts, GetPartNumbers

    Идентификатор объекта - Id:
Плохо:            OrderID, idReseller
Хорошо:          OrderId, ResellerId

Избегайте нескольких названий для одной и той же сущности:
Плохо:
ResellerModel GetReseller(string userName)
ResellerModel GetById(int id)
var resellerInfo = repository.GetById(resellerId);

Хорошо:
Reseller GetReseller(string userName)
Reseller GetReseller(int resellerId)
var reseller = repository.GetReseller(resellerId);

3.2. Переменные
    Не используйте имена переменных из одной буквы, даже в циклах. Сравните читабельность:
Плохо:            grid[i][j]
Хорошо:          grid[rowIndex][columnIndex]

    Для лямбда-функций аналогично:
Плохо:            Where(x => x.Foo).Select(y => y.Bar)
Хорошо:          Where(order => order.Foo).Select(order => order.Bar)

    Избегайте использования var при объявлении переменных примитивных типов (решили попробовать)
Плохо:
var index = 0;
var text = "bar";
Хорошо:
int index = 0;
string text = "bar";

3.3. Методы
    Используйте конструкцию "глагол-объект" для именования методов:
ShowUserInfo()
GetUserId()
Глагол Get предпочтителен для выборки из БД.

    Используйте одну пустую строку между инструкциями в методе. Допустима  группировка схожих инструкций, либо логических частей без пустой строки между ними.

4. Комментарии
    Избегайте бессмысленных комментариев, например:
//это логгер
ILogger Logger
Комментарий должен содержать дополнительную информацию для упрощения понимания кода. Комментарии необходимы, вырабатывайте привычку их писать.

5. Классы
    Группируйте члены класса в коде - сначала все приватные и защищенные поля, позже идут свойства, далее - методы.

    Если класс представляет собой сущность, хранимую в базе данных – рекомендуется держать соответствие между названием и свойствами класса и названиями и столбцами таблицы. Избегайте введения дополнительных названий без необходимости.

Пример: есть таблица: Customer(Id, Name, StateId)
Плохо:            класс CustomerInfo(Id, Login, StateId)
Хорошо:          класс Customer(Id, Name, StateId)
Хорошо:          класс CustomerModel(Id, Name, StateEnum))

    Избегайте инициализации объектов неанонимных типов в виде:
Foo foo = new Foo
{
               Property1 = webService.GetProperty1(),
               Property2 = repository.GetProperty2(),
               Property3 = Random.GetNext()
}
При возникновении исключения по инициализатору нельзя пройтись отладчиком построчно, не заходя в тело каждого вызываемого метода. Коллективом решено: допустима подобная инициализация, если она не мешает отладке и читабельности кода. Вместо вызовов методов в инициализаторе необходимо использовать конструктор, либо локальные переменные:
var property1 = webService.GetProperty1();
var foo = new Foo { Property1 = property1};
var bar = new Bar (property1);

6. Типы
    Используйте встроенные типы C#.
Плохо:            String, Int32
Хорошо:          string, int

Комментариев нет:

Отправить комментарий