【发布时间】:2014-02-19 13:14:54
【问题描述】:
我想这可能是一个有点分裂的帖子,但这是我一段时间以来一直在努力表达的东西,我想把它放到更广泛的开发社区。p>
我的工作是在提交文件签入之前运行 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 等。这会导致成员名称过长,尤其是在“拥有”方法需要其他自己的“拥有”方法时。
- De-factoring - 将代码从我最初重构的小方法中移回原来的方法中。这会导致方法很长。
- 部分类 - 我实际上还没有达到这一点,但我完全有可能最终将相关方法放入部分类中,以使它们与代码主体分开。这使解决方案资源管理器充满了成堆的代码文件。
显然,我对这些方法中的任何一种都不满意,但据我所知,它们是在操作参数范围内保持易读性的唯一真正选择。
显然,第二种方法是微软的房子风格,所以我想我的问题是:
- 第二种方法是微软家风格对吗?
- 如果是这样 - Microsoft 如何在第二种样式中保持干净可读的代码?
- 其他人是否遇到过这种差异,人们使用了哪些方法来实现高可读性?
- 编写简洁代码的一般风格偏好是什么?
我找到了一份微软编码风格的副本:http://blogs.msdn.com/b/brada/archive/2005/01/26/361363.aspx
【问题讨论】:
标签: c# coding-style resharper code-cleanup