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