簡體   English   中英

如何在項目之間共享記錄結構,並且會有細微的差異?

[英]How to share records structure between projects, with slight variations?

我有2個處理相同數據,不同流程的項目。 主數組幾乎相同,只是略有不同,例如:

// Project 1

TData1 = record
  A:string;
  B:integer;
  C:word;
  ...
end;

// Project 2

TData1 = record
  A:string;
  B:integer;
  C:word;
  ...
  XMLNode:TXMLNode; // Extra value needed in Project 2, not needed in Project 1
end;

我想在項目之間共享許多數組。 我想保持相同的數組結構,以便我可以復制並粘貼需要在兩個項目中實現的任何將來的更改。 有什么辦法可以使記錄保持相同但略有不同?

我在想這樣的事情:

    // in Project 1:

    TExtras = record
    end;

    // in Project 2:

    TExtras = record
      XMLNode:TXMLNode;
    end;

    // shared - in both projects

    TData1 = record
      A:string;
      B:integer;
      C:word;
      ...
      Extras:TExtras; // different extra fields based on project needs
    end;

而且我可以將其他字段添加到Project2的Extras中,以使用Data1.Extras.XMLNode訪問字段。 不確定這是否可以用於將來。

目標是一天之內將所有共享結構放入一個共享單元中,一個維護點,而不再需要復制和粘貼。 我需要數組來保持靈活性,就像簡單的數組( array of TData1TArray<TData1> array of TData1 )一樣,所以我不能進入復雜的實現方式,這將限制選項來輕松地復制,排序,區分,操縱數據...

那是正確的方法嗎? 還有更好的主意嗎?


編輯:

兩個項目都使用相同的數據,因此它們都從相同的“源”文件中讀取,但是產生不同的最終結果。 現在,我有很多數組,其中有99%的數組用於兩個項目中的相同目的,相同功能。 但是現在,當我處理一個或另一個項目時,添加新的記錄字段,使用新字段的新功能,並且如果我不立即同步結構和新功能,那么可能會在幾周后發生在項目2中執行相同的操作,我將創建具有不同名稱和不同函數名稱的新字段。 因此,當我最終在項目之間復制某些復雜功能時,我發現它們僅由於命名不同而無法匹配。


編輯2:

從所有評論和建議中,我決定走另一條路:在共享單元中共享通用數據結構和代碼,並在項目2中創建帶有額外記錄字段的其他數組。我將創建這些新數組,這些新數組鏈接到主數據數組,從而有:

// shared data 
TData1 = record
  A:string;
  B:integer;
  C:word;
  ...
end;

Data1:TArray<TData1>;

// additional in Project 2
TDataExtra = record
  DataIdx:integer;// link to TData1
  XMLNode:TXMLNode;
  ...
end; 

DataExtras:TArray<TDataExtra>;

可以輕松訪問每個Data1記錄的XMLNode值:

fGetXMLNode(i); // where i is index in Data1 array and function will return XMLNode

我相信,我可以保留共享單元,並以最少的額外工作將任何額外的內容添加到任何陣列,這仍然比維護2個數據結構和代碼的成本低。

那會是更好的解決方案嗎?

如果沒有完整的上下文,很難說哪種解決方案是最佳/更好,但是這里有一些其他方法可以達到相同的效果。

條件定義

TData1 = record
  A:string;
  B:integer;
  C:word;
  [...]
{$IFDEF NEEDXMLNODEINTDATA1}
  XMLNode:TXMLNode; // different extra fields based on project needs
{$ENDIF}
end;

使用新結構

在第二個應用程序中使用其他結構。 我希望這是大多數情況下的正確方法。

TData1Node = record
  Data1 : TData1;
  XMLNode : TXMLNode;
end;

一直包含XMLNode

由於它只是一個指針,除非您的應用程序中有大量的記錄,否則它幾乎不會注冊內存使用情況。

Pascal沒有void / Unit數據類型,您仍然可以進行模擬。 編譯器並不總是對此感到SizeOf(someType) ,在某些路徑中,它只是不做任何假設/檢查,在某些極端情況下SizeOf(someType)可能為零。

不過,如果您確實需要壓縮Project 2中的每個最后一個字節,同時保持與Project 1共享源,則可以使用此丑陋的技巧:

文件Project_1.inc

{$IFnDEF THIS_IS_PROJECT_1}
halt compilation! wrong setup!!!
{$EndIf}

{$IFDEF THIS_IS_PROJECT_2}
halt compilation! wrong setup!!!
{$EndIf}

type TDataPayload = TXMLNode;

文件Project_2.inc

{$IFnDEF THIS_IS_PROJECT_2}
halt compilation! wrong setup!!!
{$EndIf}

{$IFDEF THIS_IS_PROJECT_1}
halt compilation! wrong setup!!!
{$EndIf}

type REmpty = packed record end;

type TDataPayload = REmpty;

// after compilation - call `assert(SizeOf(TDataPayload) = 0);`

文件CommonDataType.pas

{$IfDef THIS_IS_PROJECT_1}
  {$INCLUDE Project_1.inc}
{$EndIf}

{$IfDef THIS_IS_PROJECT_2}
  {$INCLUDE Project_2.inc}
{$EndIf}

TData1 = 
{$IFDEF THIS_IS_PROJECT_2}
  packed
{$EndIf}
  record
    A:string;
    B:integer;
    C:word;
  ...
    Payload: TDataPayLoad;
  end;

話雖這么說,您的評估表明您不能通過項目2中的type TXMLNode=byte兼容性存根type TXMLNode=byte浪費單個字節,這對我來說似乎非常可疑。 因為:

  1. 您使用快速內存​​填充record而不是慢速字節壓縮packed record
  2. 您使用TXMLNode,即使在不同的項目中-每個TObject實例也將占用數十個字節,指向RTTI的指針,指向VMT的指針,在Heap Manager中支持幀。...記錄中指向該對象的指針還將另外占用4個字節或8個字節。 而且您不能負擔一個額外的字節,而不是所有這些??? 來吧!
  3. 您的A:string; 每個記錄中的每個指針花費4(或8)個字節,然后作為StringRec標頭再使用12個字節,然后在字符串內容之后再分配未知的預分配大小寫緩沖區,然后為尾隨#0增加兩個額外的字節,以及然后在堆管理器中支持數據結構。 仍然只有一個type TXMLNode=boolean stub type TXMLNode=boolean額外字節太多了???
  4. 如果您的應用程序性能/正確性僅取決於每個數據幀一個額外的字節,這還意味着隨着用戶生成的數據比平時多出5%,您的應用程序也會損壞。 期。 如果您信任您的評估,那么您的應用程序已經超出了算法/設計限制。 並且應該進行重塑以使用無內存綁定算法。 一個簡單的例子-它可以使用磁盤上的流排序,而不是使用內存中的Quicksort,它具有相同的最壞情況復雜度,但只需要4個數據幀的內存即可。

簡便的解決方案是保持兩個項目之間共享數據結構和相關功能,並添加包含每個項目特定數據的附加數組。 使用額外的數組將帶來更多的工作,但是將使共享的代碼真正共享。

因此,代替其他答案中提出的新類或IFDefs,鏈接到主數據的簡單額外數組是解決該問題的最佳選擇:

// shared main data through both projects
TData1 = record
  A:string;
  B:integer;
  C:word;
  ...
end;

Data1:TArray<TData1>;

// additional in Project 2
TDataExtra = record
  DataIdx:integer;// link to TData1
  XMLNode:TXMLNode;
  ...
end; 

DataExtras:TArray<TDataExtra>;

使用此解決方案,可以輕松添加,擴展任何其他數組,例如DataExtras或其他數組的其他字段,而無需更改共享代碼。 共享代碼將易於維護,因為它僅包含主要數據,而沒有僅針對一個項目的特定內容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM