2014-02-19 3 views
9

Я предполагаю, что это может быть немного расходящимся сообщением, но это то, над чем я изо всех сил пытался сформулировать какое-то время, и я хотел бы поместить его в более широкое сообщество развития.ReSharper и StyleCop против понижающего правила (чистый код)

Я работаю в роли, где перед выполнением регистрации в файле мы запускаем инструмент автоматического форматирования ReSharper, который группирует вещи в регионах с помощью модификатора доступа и сортирует элементы внутри этого алфавита. В основном это соответствует шаблону макета класса, описанному в этом сообщении: Alphabetizing methods in Visual Studio, в котором люди, похоже, очень заинтересованы.

Я рад работать с любыми стандартами кодирования, но я изо всех сил стараюсь примирить этот подход с написанием чистого кода, прежде всего потому, что я строго придерживаюсь правила понижения (Robert C Martin - Clean Code), и алфавит разбивает это.

Понижающий Правило описывается следующим образом:

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

После этого подхода, я мог бы написать следующее (надуманный) код:

public class Processor 
{ 
    public Processor(ProcessData data) 
    { 
     Configure(data); 
    } 


    public void Configure(ProcessData data) 
    { 
     ClearState(); 
     UnpackData(); 
     ProcessData(); 
     TransformData(); 
     PostProcessData(); 
    } 

    private void ClearState() { /*Snip*/ } 

    private void UnpackData() { /*Snip*/ } 

    private void ProcessData() { /*Snip*/ } 

    private void TransformData() { /*Snip*/ } 

    private void PostProcessData() { /*Snip*/ } 


    public IEnumerable<GroupedRecordSet> AggregateRecords(IEnumerable<Record> records) 
    { 
     var groups = CalculateGrouping(records); 
     PopulateGroups(groups, records); 
     return groups; 
    } 

    private IEnumerable<GroupedRecordSet> CalculateGrouping(IEnumerable<Record> records) { /*snip*/ } 

    private void PopulateGroups(IEnumerable<GroupedRecordSet> groups, IEnumerable<Record> records) { /*snip*/ } 
} 

Затем, когда я бегу автоформатирование, я в конечном итоге, глядя на следующие (Комментарии удалены):

public class Processor 
{ 
    #region Constructors and Destructors 

    public Processor(ProcessData data) 
    { 
     Configure(data); 
    } 

    #endregion 

    #region Public Methods and Operators 

    public IEnumerable<GroupedRecordSet> AggregateRecords(IEnumerable<Record> records) 
    { 
     var groups = this.CalculateGrouping(records); 
     this.PopulateGroups(groups, records); 
     return groups; 
    } 

    public void Configure(ProcessData data) 
    { 
     this.ClearState(); 
     this.UnpackData(); 
     this.ProcessData(); 
     this.TransformData(); 
     this.PostProcessData(); 
    } 

    #endregion 

    #region Methods 

    private IEnumerable<GroupedRecordSet> CalculateGrouping(IEnumerable<Record> records) { /*snip*/ } 

    private void ClearState() { /*snip*/ } 

    private void PopulateGroups(IEnumerable<GroupedRecordSet> groups, IEnumerable<Record> records) { /*snip*/ } 

    private void PostProcessData() { /*snip*/ } 

    private void ProcessData() { /*snip*/ } 

    private void TransformData() { /*snip*/ } 

    private void UnpackData() { /*snip*/ } 

    #endregion 
} 

Теперь я считаю, что второй стиль намного сложнее понять с первого взгляда, и я нахожусь в необычной длине, чтобы сохранить читаемость первого стиля в пределах второго. К ним относятся:

  • Владелец имя метода префикс - т.е. ConfigureClearState, ConfigureUnpackData, AggregateRecordsCalculateGroupings, AggregateRecordsPopulateGroups и т.д., что приводит к длинным именам членов, особенно если «принадлежащие» методы требуют дополнительных «принадлежащих» методов своих собственных.
  • Де-факторинг - движущийся код из небольших методов. Я изначально был реорганизован, обратно в метод, из которого он пришел. Это приводит к длительным методам.
  • Частичные классы. На данный момент я до сих пор не дошел до этого момента, но вполне возможно, что в конечном итоге я добавлю связанные методы в частичные классы, чтобы они отличались от основного кода. Который заполняет проводник решений с помощью груды файлов кода.

Очевидно, что меня не устраивает какой-либо из этих подходов, но, насколько я вижу, они являются единственными реальными вариантами для обеспечения удобочитаемости в рабочих параметрах.

Видимо, второй подход является стилем дома Microsoft, так что я предполагаю, что мой вопрос (ы) будет:

  • Верно ли, что второй подход является стилем дома Microsoft?
  • Если это так - как Microsoft поддерживает чистый читаемый код во втором стиле?
  • Неужели кто-то еще столкнулся с этим несоответствием, и какие подходы люди использовали для достижения высокой читаемости?
  • Каковы общие предпочтения стиля для написания чистого кода?

Я нашел копию стиля Microsoft кодирования: http://blogs.msdn.com/b/brada/archive/2005/01/26/361363.aspx

ответ

3

Подход Роберт Мартин нацелен на читаемость. Чтобы в полной мере пользоваться преимуществами, вы должны применять дополнительные соглашения или правила (например, именовать, оставлять комментарии ради выбора значимых и описательных имен, единой ответственности, коротких методов ...). Затем вы можете прочитать свой код как обычный текстовый документ. Если отступ в следующем функциональном блоке уровня абстракции также улучшает читаемость. Таким образом, вы можете выразить уровни абстракции вашего формата код:

public void Level1Member() 
{ 
    RunLevel2Member(); 
    RunAnotherLevel2Member(); 
} 

    private void RunLevel2Member() 
    { 
     RunLevel3Member(); 
    } 

     private void RunLevel3Member() 
     { 
      //.... 
     } 

    private void RunAnotherLevel2Member() 
    { 
     //.. 
    } 

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

Это два разных подхода, имеющих разные цели. Одному нравится улучшать читаемость (для людей) и позволяет находить методы по потоку программы, в то время как другим нравится, чтобы вы быстро находили методы по их имени. Алфавитная сортировка поддерживает общее соглашение, позволяющее объединить все общедоступные методы, что также увеличивает вероятность выяснить цель и поведение класса (с первого взгляда). Поэтапное смешение смешивает общественные и частные методы, следуя другой цели.

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

Если вы считаете, что чтение понижающего стиля кажется более удобным и естественным, чем чтение кода в стиле словаря, вы должны его использовать. Я делаю.

Никогда не слышал о внутренних соглашениях Microsoft, таких как сортировка их кода по алфавиту. Официальное соглашение .NET не предназначено для организации или конвенции для структуры кода (например, рекомендуя разместить делегат события в верхней части класса и т. Д.).

Пошаговое правило - это просто неофициальный стиль. Некоторые средства автоматического форматирования не поддерживают методы отступов и помещают их обратно на один уровень.

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

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

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

Да, но я лично предпочитаю уйти в отставку.

+0

Я согласен, и я также считаю, что сортировка по алфавиту довольно избыточна, так как у нас уже есть множество мест в среде IDE, где мы можем получить доступ к элементам в алфавитном порядке и перейти прямо к ним. –

+0

Кроме того - не уверен, что я чувствую, что отступы от кода, чтобы сделать шаги физическими, я всегда имел тенденцию отделять логические группы операторов метода вместо двойной белой строки. –

+0

Да, это все по вкусу. Я думаю, что при прокрутке страницы легче определить изменение отступа, чем разницу в пространстве строк (1 строка), чтобы просто определить, где вы находитесь в коде. Известно, что больше пробелов между строками неловко читать (движение глаз). Отступы делают уровни абстракции более заметными. Идея состоит в том, что вам просто нужно прочитать первый уровень (без отступов) и, возможно, методы второго уровня, чтобы понять основную функцию вашего кода. Каждый последующий уровень отступа или абстракции показывает больше деталей о том, как выполняется основная функция этого класса. – BionicCode

Смежные вопросы