实现TObjectList的排序,无需复制/粘贴代码

pro*_*tor 3 delphi sorting refactoring

我有一个在节点树中排序节点的过程(VirtualTreeView)从FMM4报告中提取的所有内存泄漏都存储在类TMemoryLeakList的对象中(这些是我想要排序的列表),它们存储在列表列表中称为TGroupedMemoryLeakList,TMLL和TGMLL都扩展了TObjectList.如果我想保持能够在升序和降序排序之间进行选择并在四种不同数据类型之一之间进行选择的功能,我必须'实现八种不同的比较方法(4种排序类型*2种排序方向)我转到主排序方法,因为我的TMLL列表扩展了TObjectList.主要的排序方法看起来像这样.

从GUI组合框中获取字段fSortType和fSortDirection的值.这八个通用比较函数中的一个看起来像这样.剩下的七个是这一个的复制/粘贴变体.

是否有任何合理的方法来重构大量的复制粘贴代码并仍保留选择特定排序类型和方向的功能?

NGL*_*GLN 5

关于重构的好问题,但我不喜欢你可能正在寻找的答案.一些额外的代码行或一些额外的例程没有任何问题.尤其是后者,在这种情况下,命名主动有助于提高可读性.

我的建议是:保留设计,但缩短代码:

function CompareSizeAsc(Item1, Item2: Pointer): Integer;
begin
  Result := TMemoryLeak(Item2).Size - TMemoryLeak(Item1).Size;
end;

function CompareSizeDesc(Item1, Item2: Pointer): Integer;
begin
  Result := TMemoryLeak(Item1).Size - TMemoryLeak(Item2).Size;
end;

function CompareClassNameAsc(Item1, Item2: Pointer): Integer;
begin
  Result := CompareStr(TMemoryLeak(Item1).ClassName,
    TMemoryLeak(Item2).ClassName);
end;

procedure TMemoryLeakList.Sort;
begin
  case FSortDirection of
    sdAsc:
      case FSortType of
        stSize: inherited Sort(CompareSizeAsc);
        stClassName: inherited Sort(CompareClassNameAsc);
        stCallStackSize: inherited Sort(CompareCallStackSizeAsc);
        stId: inherited Sort(CompareIdAsc);
      end;
    sdDesc:
      case FSortType of
        stSize: inherited Sort(CompareSizeDesc);
        stClassName: inherited Sort(CompareClassNameDesc);
        stCallStackSize: inherited Sort(CompareCallStackSizeDesc);
        stId: inherited Sort(CompareIdDesc);
      end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

你不能让它小得多,然后保持相同的可读性水平.

当然,您可以Sort按照Arioch'的建议重写例程:

procedure TMemoryLeakList.Sort;
const
  Compares: array[TSortDirection, TSortType] of TListSortCompare =
    ((CompareSizeAsc, CompareClassNameAsc, CompareCallStackSizeAsc,
    CompareIdAsc), (CompareSizeDesc, CompareClassNameDesc,
    CompareCallStackSizeDesc, CompareIdDesc));
begin
  inherited Sort(Compares[FSortDirection, FSortType]);
end;
Run Code Online (Sandbox Code Playgroud)

但那么:为什么不重写QuickSort例程以消除对单独比较例程的需要?

或者,您可以向TMemoryLeak添加所有权,在这种情况下,您可以引用拥有列表及其排序方向和排序类型,以便在单个比较例程中使用.