Microsoft User Group Винница feedback 10 лучших советов по написанию читабельного кода - Разработка приложений - Microsoft User Group Винница

 

10 лучших советов по написанию читабельного кода

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

Комментирование и документирование 

Очень полезной фичей в Visual Studio является возможность комментариев в пользовательских классах и методах, в С# приложениях просто надо добавит три слеша ("///") перед их объявлением.VS.NET автоматически создает необходимые XML атрибуты, куда можно вставлять описание и информацию о параметрах. После того как проект скомпилирован, VS.NET сохраняет введенную информацию, и она будет отображаться с использованием IntelliSense. Эта  информация включает комментарии для методов, параметры методов, возвращаемые переменные методов, перечислений и свойств.

Избегайте очевидных комментариев

Комментарии должны описывать цель секции кода, но не механизм как достичь эту цель - описывайте скорее "почему", а не "как". Если вы заметили, что комментариях  используете имена переменных, лучше остановится и переписать комментарий. 

Не правильно:

        // получить код
        countryCode = GetCountryCode(ServerType.BackUp);

        // если код US         
        if (countryCode == "US")

            // показать пользователя  
            InvokeUSUser(); 

Правильно:

        // отобразить пользователей с US 
        countryCode = GetCountryCode(ServerType.BackUp);
        if (countryCode == "US")
           InvokeUSUser();

Единый стиль в отступах 

Все знают что надо делат отступы в коде, чтобы повысить его читабельность о структурированность. Есть несколько стилей:

Стиль №1

        void DoSomething() { 

            if (maybe) { 
                DoItNow();
                Again(); 
            } else {
                AbortMission();
            }
        }

Стиль №2

        void DoSomething()
        { 

            if (maybe) 
            { 
                DoItNow();
                Again(); 
            }
            else 
            {
                AbortMission();
            }
        }

Выбор стиля зависит от вас, здесь самое лучшее правило - последовательность, если выбрали один, то придерживайтесь его всю жизнь :), ну или на протяжении одного проекта по крайней мере.

Еще по структуре отступов: 

  1. Разбивайте длинные SQL запросы на  несколько строчек используя verbatim strings, т.е. использовать "@" в начале строки. Выравнивать  последующие строчки лучше по началу  SQL выражения в первой строчке . Тоже правило работает для вызова функций с большим количеством параметров

    strSQL = @"SELECT tblAssemblyDetail.*, tblInventory.Description, 
               tblInventory.Serials FROM tblInventory RIGHT JOIN 
               tblAssemblyDetail ON tblInventory.ItemID = 
               tblAssemblyDetail.ItemID
               WHERE ((tblAssemblyDetail.Assembly)='Package A')
               ORDER BY tblAssemblyDetail.LineNumber;" ;
    
  2. Разбивайте длинные объявления методов на несколько строчек и отступайте на 6 символов или 2 TAB отступа. Тоже правило работает для длинных IF выражений.

          public void CreateNewNote( long accountNumber,
                              string noteDate, string startTime,      
                              string note, long repNumber){}  
    
  3. Когда присваиваете переменной длинное выражение, лучше сделать перенос сразу после знака "=", чтобы было видно все выражение в одной строчке.

          grdDetail.Columns("CanBuild").Text = 
                    (long)lngQuantityLocation / (long)grdDetail.Columns("Needed").Text; 
    

Группируйте код  

Чаще всего определенные задания занимают несколько строк кода. Хорошая идея группировать эти задания в отдельные блоки, с разделителем - пустая строка. 

            // initialization 
            SqlDataAdapter adapter; 
            SqlConnection connection;
            SqlCommand command;

            // getTicketID 
            string sqlCommand = " SELECT * FROM Cases " 
            command = new SqlCommand(); 

Добавление строки комментариев перед каждым блоком также визуально подчеркивает разделение . 

Избегайте глубоких вложений

Слишком много уровней вложенности усложняют читабельность кода и его тяжелее отследить. Часто можно внести некоторые изменения в код для большей читабельности.

Не правильно:

         public int DoSmth(){ 
            if (IsWritable(folder)) {  
                if (fp == FileOpen(filePath,"w")) {  
                    if (stuff = getSomeStuff()) {  
                       if (FileWrite(filePath,stuff)){  
                                // ..                         
                       } else {  
                           return false;  
                       }  
                   } else {  
                       return false;  
                  }  
               } else {  
                   return false;  
               }  
           } else {  
               return false;  
           }  
         }

Правильно:

         public int DoSmth(){
            if (!IsWritable(folder))
            {
                return false;
            }
            if (fp != FileOpen(filePath, "w"))
            {
                return false;
            }
            if (stuff != getSomeStuff())
            {
                return false;
            }
            if (!FileWrite(filePath, stuff))
            {
                //..
            }
            else
                return false;
        }   

Организация файлов и папок

Технически можно весь код содержать в одном файле, но его будет очень тяжело читать и поддерживать. Лучше всего разделять решение(Solution) на разные проекты (projects) в соответствии с разными уровнями, модулями, или компонентами определенными на стадии дизайна. 

В платформе .NET вводиться понятие проекта, одно решение может включать несколько проектов разных типов. После того как вы начинаете все разделять на разные проекты их может стать слишком много, и становится неудобно скролить между ними.

В Visual Studio 2005 ввели полезную фичу: возможность добавлять папки в одно решение, группировать проекты и даже папки в вашей собственной логической иерархи. 

Для примера пользуясь руководством Microsoft Patterns and Practicies по разработке трехуровневой архитектуры приложения, у вас может получиться что-то типа:

Будьте последовательны в именовании переменных 

Как правило имена переменных имеют смысловую нагрузку и состоят из нескольких слов. Но это не обязательно так для локальных переменных. Они могут состоят и из одного символа.  Хорошей практикой является  использование единого принципа в именовании локальных переменных во всем проекте.  Например: 

           // i для переменной счетчика циклов 
           for (int i = 0; i < 10; i++)

           // j для вложеных циклов 
           for (int j = 0; j < 10; j++)

           // ret для возвращаюшей результат переменной 
           public int Foo() 
           {
               ret["bar"] = GetBarCode();
               ret["stuff"] = GetStuff();
               return ret;
           }

           // fp для указателя файла (file pointer)  
           fp = FOpen("file.txt","w");  

Тут также стоит вспомнить про Венгерскую нотацию. Суть Венгерской нотации сводится к тому, что имена идентификаторов предваряются заранее оговорёнными префиксами, состоящими из одного или нескольких символов. Пример:

Class

cls

clsEmployee

Form

frm

frmLogin

Многие считают, что нотация устарела, но это хорошая практика быть последовательным и единым в именовании переменных. 

Пишите SQL спец. слова заглавными буквами 

Обращение к базам данных важная часть большинства WEB приложений. Если вы часто используете запросы, хорошая идея сделать их также более читабельными. Общепринятой практикой считается писать заглавными словами спец. слова SQL: 

           string statement = @"SELECT DISTINCT titel as linieName
                                FROM qry_Forecast_Taktzeiten
                                WHERE linieName LIKE 'lin%'; "; 

DRY принцип

DRY расшифровывается как Don’t Repeat Yourself (Не повторяйтесь). Также известно выражение DIE: Duplication is Evil(Повторение - зло). Принцип гласит:

“ Каждый сегмент знаний должен иметь единственное и однозначное  представление в рамках системы".

В ASP.NET можно использовать эталонные страницы( master pages) для задания шаблона всего сайта.   

Если вам все таки надо использовать кусок кода снова и снова, то его можно перенести на панель инструментов(ToolBox), просто  выделите ваш код и перетащите выбранный текст на общую вкладку. Теперь шаблон можно использовать как любой другой контрол. 

Рефакторинг

Рефакторинг — процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы. В основе рефакторинга лежит последовательность небольших эквивалентных (то есть сохраняющих поведение) преобразований.  Лучше проводить рефакторинг недавно написанного кода, пока он свежий в голове, что бы потом легче было его читать и использовать. Хорошая книга по рефакторингу "31 Days of Refactoring"

Использованные материалы: 


Поділитись


Related Posts with Thumbnails Posted мар 12 2010, 08:30 by mihasb View 2 698 17

Comments

Краковецкий А. on 03-13-2010 3:15

>> Разбивайте длинные SQL запросы на  несколько строчек используя символ "+".

Когда-то этот пункт вызвал у нас многочасовую дискуссию.

SQL скрипты в тексте - это  уже плохо, а выше упомянутый SQL скрипт можно без проблем переписать в виде многострочного текста (или с использованием string.Format() если нужно передать параметры).

LexRema on 03-13-2010 3:41

Кстати именно это положение меня тоже сильно насторожило. В настоящем проекте у меня динамических скриптов ну ОЧЕНЬ много. И каждое такое суммирование приведет к горомному количеству операнций над строками. Поэтому соглашусь что String.Format здесь будет намного более логичым.

"Очень полезной фичей в Visual Studio является возможность комментариев в пользовательских классах "

Вещь супер. На основе этих комментариев можно генерировать документацию в XML.

Andrey on 03-13-2010 3:56

В приведенном выше примере компилятор проведет конкатенацию на этапе компиляции кода. Если посмотреть исполняемый файл рефлектором, то Вы увидите, что это действительно так.

А вообще можно использовать verbatim strings. Строки с символом @ в начале. Внутри таких допускаются символы перевода строки.

OldDino on 03-13-2010 4:08

Говорить на эту тему можно долго и, главное, никто никого не убедит.

Эти "лучшие" советы - это просто набор некоторых рекомендаций, не более. Думаю, что каждый, кто не "клепает" код "на коленке", может привести массу подобных рекомендаций. Например, об использовании регионов, раз уж речь идет о VS. Или, скажем, о том, нужно ли выносить каждый класс в отдельный файл. Так что :-( .

А вот за рекомендацию о переносе части кода в toolbox благодарю. Не знал.

Краковецкий А. on 03-13-2010 4:28

Действительно, "лучших" советов быть не может, тут я с вами согласен.

>> А вот за рекомендацию о переносе части кода в toolbox благодарю. Не знал.

Кстати, да. Очень полезный совет.

mihasb on 03-13-2010 4:45

>>с использованием string.Format() если нужно передать параметры  

я задал этот вопрос на stackoverflow stackoverflow.com/.../question-about-string-format

Я так и не понял как в этом случае использовать string.Format(), там вообще советуют не использовать  string.Format(). Либо использовать

>> Строки с символом @ в начале

таким образом получится

string statement = @" SELECT DISTINCT titel as linieName

                              FROM qry_Forecast_Taktzeiten

                              WHERE linieName LIKE 'lin%'; ";

>> Эти "лучшие" советы - это просто набор некоторых рекомендаций, не более .

Это действительно просто набор рекомендации, а "лучших" - рекламный ход  :)

progg.ru on 03-13-2010 4:50

Thank you for submitting this cool story - Trackback from progg.ru

Краковецкий А. on 03-13-2010 4:56

>> Я так и не понял как в этом случае использовать string.Format(), там вообще советуют не использовать  string.Format().

В первом комментарии я сказал, что лучше использовать многосточный текст, т.е. использовать "@" если у нас просто SQL запрос:

var sql = @"select * from table

                       where column =1";

Но если у нас есть параметры, то есть смысл использовать string.Format() как дополнение к "@":

var sql = string.Format(@"select * from {0}                        

                        where column ={1}", tableName, someValue);

mihasb on 03-13-2010 5:06

Краковецкий Александр, Andrey спасибо за коментарии на счет форматирования SQL запросов. Переделал.

Konstantin on 03-13-2010 10:04

"Группируйте код"

если для читабельности код приходится группировать, то скорее всего его уже надо рефакторить - т.к. не ясно его назначение его кусков и надо применять ExtractMethod(принципы самодокументирования никто не отменял).

Ar on 03-14-2010 14:41

хочется добавить что совр. аддины типа R# или CodeRush

могут автоматически форматировать код, имеют настраиваемый CodeStyle и поддержку шаблонов

Darky Darkov on 03-14-2010 19:07

Использование String.Format для подстановки значений параметров в SQL-запрос есть зло. По крайней мере, при использовании Oracle. Если нужно использовать параметры, применяйте коллекцию OracleCommand.Parameters и пишите запросы, поддерживающие параметры:

select * from emploee where emp = :emp;

hdd on 03-15-2010 2:49

Вы про StyleCop наверняка уже слышали. Так вот, не поленитесь поставьте его (а еще лучше связку Resharper + StyleCop for ReSharper  stylecopforresharper.codeplex.com )

На первый взгляд StyleCop содержит много мусора и высосаных из пальца правил (у меня в проекте было почти 4 тысячи warning), но поверьте если над проектом работает больше 1 человека, то StyleCop является очень хорошим контролером. Ну и исходники в конце концов становятся тоже более читабельными :)

dm.CaT on 03-15-2010 3:53

Уже во второй компании берём за основу RSDN Style Guide rsdn.ru/.../codestyle.XML, адаптируем под себя и используем.

Andrew on 03-16-2010 6:46

Советы скорее (и даже точно) для начинашек.

Alex on 05-03-2010 8:19

Венгерка давно устарела. Используйте, если хотите ухудшить читаемость.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Please add 5 and 4 and type the answer here:

Enter captcha:

Информация

О нас
Timeline
Спонсоры
Поддержать

Разделы

Блоги
Медиа
Форумы
Вики
Презентации

Работа

Вакансии
Компании

Проекты

TechPosters
Data Mining SDK
Численные методы на C#
iPhoner
Data Extracting SDK

Контакты

msugvn@gmail.com
krakovetsky.alex
@msugvnua
ВКонтакте
LinkedIn
Facebook
INETA

Разработка логотипа: Helen

Статистика

Powered by Community Server (Non-Commercial Edition), by Telligent Systems