降低类复杂性-认知复杂性c#



如何提高代码中的认知复杂性?

我有一个方法,它有while循环,里面有很多IF ELSE块,我试图用SWITCH语句删除IF ELSE,但根据SONAR立方体分析,认知复杂性没有改善。

这是我现有的代码:

while (this.moveNextDelegate(fileLineEnumerator))
{
var line = fileLineEnumerator.Current;
var recordType = GetRecordType(line);  // This Method returns the type of record
if (recordType == "1")
{
headerId++;
fileHeader = line; // Here fileHeader is being used in downsteam code flow - line 19
// some custom logic - deleted
}
else if (recordType == "5")
{
batchHeader = line; // Here batchHeader is being used in downsteam code flow - line 19
isRepeativeRecord = false;
}
else if (recordType == "6")
{
batchHeaderId =     // some custom logic - deleted
// Here batchHeaderId is being used in downsteam code flow - line 35 
detailId++;
isFlag = false;
isRepeativeRecord = true;
// some custom logic - deleted
}
else if (recordType == "7" && !isFlag)
{
addendaId++;
detailRecordsExist = true;
// some custom logic - deleted
}

currentIndex++;
}

我的新代码使用Switch语句-但仍然没有提高复杂性

while (this.moveNextDelegate(fileLineEnumerator))
{
var line = fileLineEnumerator.Current;
var recordType = GetRecordType(line);
switch (recordType)
{
case "1":
{
headerId++;
fileHeader = line; 
// some custom logic - deleted
break;
}
case "2":
{
batchHeader = line;
isRepeativeRecord = false;
break;
}
case "6": 
{
// some custom logic - deleted
break;
}
case "7": 
{
if (!isFlag)
{
// some custom logic - deleted
}
break;
}
case "8": 
{
if (!isFlag)
{
// some custom logic - deleted
}
break;
}
}
currentIndex++;
}

if/else语句切换到switch语句可能是一个好主意,不要从最终代码中丢弃它,但不会降低复杂性,因为&;if/else/switch&;语句和其他if语句仍然存在于主体中。

为了避免声纳的复杂性,编写更多的简单方法,每个都有一个单目标,最好是测试和有更少的逻辑来理解。

https://en.wikipedia.org/wiki/SOLID

看看你的代码,你可以提取一些方法,我做了一些重构来降低复杂性,正如你在下面的列表中看到的:

  1. 提取while主体代码到方法
  2. 摘录"记录类型">
  3. 你仍然可以重构为类(小心,可能是一个过度工程)
private void Foo()
{
FileEnumerator fileLineEnumerator = new FileEnumerator();
while (this.moveNextDelegate(fileLineEnumerator))
{
string line = fileLineEnumerator.Current;
ReadNextLine(line);
currentIndex++;
}
}
private void ReadNextLine(string line)
{
var recordType = GetRecordType(line);
if (recordType == "1")
{
this.ReadHeader(line);
}
else if (recordType == "5")
{
ReadBatchHeader(line);
}
else if (recordType == "6")
{
ReadRepeativeRecord();
}
else if (recordType == "7" && !this.isFlag)
{
ReadDetail();
}
}
private void ReadDetail()
{
this.addendaId++;
this.detailRecordsExist = true;
}
private void ReadRepeativeRecord()
{
this.batchHeaderId = this.detailId++;
this.isFlag = false;
this.isRepeativeRecord = true;
}
private void ReadBatchHeader(string line)
{
this.batchHeader = line;
this.isRepeativeRecord = false;
}
private void ReadHeader(string line)
{
this.headerId++;
this.fileHeader = line;
}

看起来你正在写一个阅读器,所以如果你有很多阅读器/步骤,如阅读标题,正文,文件的页脚,详细信息和递归内容,你可以在一个单独的类中分离每个片段,如HeaderReader,BodyReader,DetailReader,但这可能是一个工程,所以你会决定是否值得。

public class ReadState
{
public RecordType RecordType { get; set; }
public string Line { get; set; }
}
public class ReadResult
{
public int HeaderId { get; set; }
}
public class BodyReader : IYourCustomFileFragmentReaderInterface
{
public bool Test(ReadState state)
{
// check if is header
return state.RecordType == RecordType.Body;
}
public ReadResult Read(ReadResult result, ReadState state)
{
// write state
result.HeaderId = int.Parse(state.Line);
return result;
}
}

使用单独的阅读器,您可以在IYourCustomFileFragmentReaderInterface的列表中分组,调用Test(),如果为真,则调用Read方法。

相关内容

  • 没有找到相关文章

最新更新