2009-07-12 24 views
17

Vì vậy, cách thức ưu tiên để khởi tạo hồ sơ là gì?Delphi: Ghi lại hàm tạo và hàm nhà máy

Với một 'chức năng nhà máy':

TMyRecord = record 
    valueX: integer; 
    valueY: integer; 
end; 

function MyRecord(const AValueX, AValueY: integer): TMyRecord; 
begin 
    result.valueX := AValueX; 
    result.valueY := AValueY; 
end; 

var 
    myrec: TMyRecord; 
begin 
    myrec := MyRecord(1, 2); 
end; 

hoặc một constructor:

TMyRecord = record 
    valueX: integer; 
    valueY: integer; 
    constructor Create(const AValueX, AValueY: integer); 
end; 

constructor TMyRecord.Create(const AValueX, AValueY: integer); 
begin 
    self.valueX := AValueX; 
    self.valueY := AValueY; 
end; 

var 
    myrec: TMyRecord; 
begin 
    myrec := TMyRecord.Create(1, 2); 
end; 

Tôi cảm thấy rằng những điều constructor gói gọn hơn, nhưng nó làm cho nó dễ dàng để bị lẫn lộn khi đọc mã. Nó làm cho nó trông giống như một lớp học mà thiếu một cuộc gọi miễn phí. Nó cũng nhiều hơn để nhập ...

Tại sao bạn thích cái này hơn cái kia?

Trả lời

11

Tôi thích các lớp học hơn, nhưng nếu tôi phải sử dụng hồ sơ, tôi muốn đối xử với họ tương tự như các lớp học nhất có thể. Vì vậy, tôi sử dụng hàm tạo bản ghi.

Nhưng có một lỗi gây phiền nhiễu với các bản ghi và đơn vị. Nếu một hàm trả về một bản ghi (với các phương thức), nó sẽ tạo ra một lỗi nội bộ nếu bạn muốn truy cập các phương thức này. Bạn có thể phá vỡ điều này bằng cách chỉ định nó cho một biến khác:

type 
    TMyRec = record 
    .. 
    procedure X; 
    end; 


function GetRec: TMyRec; 



procedure Test; 
var 
    r1, r2 : TMyRec; 
begin 
    r1 := GetRec; 
    r1.X; // internal error 
    r2 := r1; 
    r2.X; // No internal error; 
+4

Tôi cũng sử dụng các nhà xây dựng bản ghi. Bạn có thể đặt tên cho nó một cái gì đó khác với "Tạo" nếu bạn thích, vì vậy bạn biết đó là một bản ghi. –

+5

FYI Vấn đề lỗi nội bộ bạn đã đề cập dường như đã được sửa trong D2010. –

+1

Câu hỏi là về hàm tạo, không chỉ là một phương thức. Nếu chúng ta sẽ làm theo cùng một ký hiệu cho hàm tạo thì rất khó để hiểu từ mã cho dù đó là bản ghi hay thể hiện của lớp. Đối với lớp, nó có nghĩa là rò rỉ bộ nhớ, vì vậy bất cứ ai thấy mã đó sẽ phải kiểm tra là nó thực sự ghi lại hoặc lớp. Vì vậy, tôi nghĩ rằng đó là cách xấu. –

0

Tôi thường không tạo nhà thầu cho bản ghi. Nó không tương thích với tất cả các phiên bản (và FPC). Hơn nữa thông thường chúng được sử dụng chỉ ở một nơi và thường là một que là đủ.

+4

Hơi khó để sử dụng FillChar() để khởi tạo một bản ghi với các giá trị, phải không? – Vegar

1

Trong dự án Delphi mà tôi đã tạo, tôi đã sử dụng các bản ghi thay vì các lớp để giảm số lượng phí trên một danh sách. Tôi sẽ có hàng trăm bản ghi trong một mảng động vì vậy tôi đã tạo hai bản ghi. Bản ghi đầu tiên là cho chính mục đó. Các trường được đặt ở chế độ riêng tư (có, bạn có thể sử dụng riêng tư/được bảo vệ bằng bản ghi) và thêm các thuộc tính chỉ đọc vào phần công khai. Một hàm tạo bổ sung cũng được thêm vào để khởi tạo bản ghi theo cách chính xác. Thiết lập này cho phép tôi bảo vệ nội dung khỏi hồ sơ này từ các nhà phát triển khác. Bản ghi thứ hai chỉ là một trình bao bọc xung quanh một mảng động của loại bản ghi trước đó. Mảng sẽ là riêng tư và tôi đã thêm các phương thức để nhận, thêm và xóa các bản ghi trong danh sách này. Kết quả là, toàn bộ danh sách được bảo vệ chống lại việc sử dụng sai bởi các nhà phát triển khác và cũng có chi phí thấp hơn rất nhiều so với giải pháp TList/TObjectList thông thường.

Hãy nhớ rằng các bản ghi không phải là các lớp. Bạn không thể kế thừa các hàm tạo và các phương thức khác. Chúng có ít chức năng hơn các lớp thực trong môi trường WIN32. Trong .NET, chúng chỉ được nâng cấp lên lớp một lần nữa. Và nó không phải là rất hữu ích để sử dụng thêm một nhà xây dựng khi các nhà phát triển có thể dễ dàng sửa đổi các nội dung của mỗi và mọi lĩnh vực trong hồ sơ của bạn. Bạn nên sử dụng các hàm tạo để bảo vệ các trường đó.

2

tôi muốn "phương pháp nhà máy" như

function TMyRecord.CreateRec(const AValueX, AValueY: integer): TMyRecord; 

chức năng nhà máy riêng rò rỉ incapsulation và ghi lại các contructor nhầm lẫn IMHO.

Các vấn đề liên quan