2011-11-11 26 views
7

Khi giới thiệu các loại ngoại lệ mới, tôi luôn là người không chắc chắn cách thực hiện điều này một cách chính xác. Có một quy ước chung nào không? Bạn làm nó như thế nào?Làm cách nào để đặt tên và sắp xếp các ngoại lệ của bạn?

Tôi quan tâm đến phạm vi bạn tổ chức chúng (Giữ chúng trong đơn vị chúng được sử dụng trong? Có một đơn vị về mức độ thành phần? Mức trọn gói? Ứng dụng?)

này cũng ảnh hưởng đến việc đặt tên. Bạn đưa vào bao nhiêu bối cảnh? Tốt hơn là làm cho chúng rất cụ thể (như EPersonIDNotFoundError) hoặc cố gắng làm cho chúng có thể tái sử dụng (như ENotFoundError)?

Và hậu tố "Lỗi" - khi nào tôi nên thêm nó và khi rời khỏi? Tôi không thể thấy logic, ví dụ: in Classes.pas:

EWriteError = class(EFilerError); 
    EClassNotFound = class(EFilerError); 
    EResNotFound = class(Exception); 
+0

Tôi nghĩ rằng việc tổ chức ngoại lệ theo mức độ nghiêm trọng và mỗi gói là rất tốt. Theo mức độ nghiêm trọng ví dụ. ngoại lệ xác thực riêng biệt từ lỗi tải/lưu dữ liệu. Trường hợp ngoại lệ có thể chứa chi tiết cụ thể hơn về sự kiện xảy ra. – too

+1

Đây không phải là một câu hỏi ... Quá nhiều câu hỏi cùng một lúc, với một số tranh luận tiềm năng (trolling?). IMHO này không phù hợp với mục đích SO. –

+0

@Arnaud Vâng, hãy để tôi thử trả lời câu hỏi này. Bởi vì tôi thực sự đánh giá cao đầu vào. –

Trả lời

6

Quy ước thực sự duy nhất tôi biết là đặt tiền tố là E. Tôi đã không thực sự cho nó nhiều suy nghĩ trong quá khứ, nhưng bây giờ tôi nghĩ về nó, có vẻ như với tôi rằng cả hai ErrorException thường được sử dụng như một postfix. Nếu bạn trộn chúng, tôi muốn nói rằng Exception liên quan đến một sự cố bất ngờ, như kết nối bị hỏng hoặc tệp không thể đọc được, trong khi lỗi liên quan đến nhập sai, ví dụ: một số dự kiến, nhưng ai đó đã nhập văn bản.

VCL dường như tuân theo quy ước nào đó quá, nhưng có vẻ như để thêm một postfix chỉ khi nó sẽ không được rõ ràng và không bị lỗi mà không có nó, ví dụ

EConvertError, EMathError, EVariantError

vs

EAccessViolation, EInvalidPointer, EZeroDivide

sau đó mô tả lỗi chính nó, nơi mà danh sách đầu tiên cần postfix để chỉ ra một lỗi trong một quá trình hoặc tổ chức nào đó.

Những ví dụ này được tìm thấy trong SysUtils, có thể bạn có thể xem ở đó, bởi vì nó chứa nhiều lớp ngoại lệ cũng như các lớp cơ sở cho một số lượng lớn hơn ngoại lệ. Rất ít kết thúc trong số Exception, ngoại trừ một số lỗi rất cụ thể mà bạn thực sự hy vọng sẽ không bao giờ gặp phải, như EHeapException và ESafecallException.

+0

Điểm tốt về bỏ qua "Lỗi" khi thông báo lỗi tự vận chuyển tình trạng lỗi khá tốt. Bạn có trộn "Ngoại lệ" và "Lỗi" không? –

+1

Tôi hiếm khi sử dụng "Lỗi", mặc dù tôi có thể từ bây giờ, vì câu hỏi này khiến tôi suy nghĩ về nó. Nhưng tôi thường không giới thiệu nhiều loại ngoại lệ. Tôi có xu hướng tạo ra một vài ngoại lệ cấp ứng dụng cơ bản và tôi (lại) sử dụng rất nhiều ngoại lệ hiện có. Nếu tôi thất bại trong việc chuyển đổi một số giá trị, tôi rất vui khi sử dụng EConvertError cho nó, và việc triển khai danh sách/mảng/bộ sưu tập của riêng tôi có thể dễ dàng sử dụng lại EListIndexError của bất cứ thứ gì nó được gọi. Tôi chắc chắn không tạo ngoại lệ riêng biệt cho từng trường không tìm thấy. – GolezTrol

1

Khi tạo ngoại lệ mới, tôi làm cho ứng dụng trở nên rộng rãi. Tôi bắt đầu từ lỗi chi tiết nhất đến tổng quát nhất, như lớp (Ngoại lệ) và tôi đặt tên cho phù hợp.

Vì vậy, trong ví dụ của bạn, tôi sẽ sử dụng EPersonIDNotFoundError, ENotFoundError, Exception.

Nó thực sự phụ thuộc vào bao nhiêu chi tiết mà bạn muốn từ các thông báo lỗi của bạn và những gì bạn đưa vào nhật ký của bạn (nếu bạn giữ một bản ghi lỗi)

1

Thông thường đối với các ứng dụng đơn giản, bạn có thể nhận được ngay với Exception.Create ('Thông báo lỗi'). Trường hợp ngoại lệ được mạnh mẽ là có thể phát hiện các loại phản ứng yêu cầu bằng cách nhìn vào lớp. Delphi đã thực hiện điều này bằng thủ tục Abort, điều này làm tăng EAbort. EAbort là 'đặc biệt' ở chỗ nó không kích hoạt một 'lỗi' như vậy, tức là nó là một loại ngoại lệ 'im lặng'. Bạn có thể sử dụng hành động theo lớp cụ thể này để kiểm tra một ngoại lệ và thực hiện những việc khác nhau. Bạn có thể tạo EMyWarning, EMyVeryNastyError, v.v., mỗi dòng được lấy từ kiểu Exception cơ bản.

Hơn nữa, bạn có thể xác định một lớp ngoại lệ mới để thực hiện thêm thông tin cho đến khi ngoại lệ bị mắc kẹt. Ví dụ: với mã (không được chọn):

EMyException = class(Exception) 
    constructor Create(const AErrorMessage : string; AErrorCode : integer); reintroduce; 
PUBLIC 
    ErrorCode : integer 
end; 

constructor EMyException.Create(const AErrorMessage : string; AErrorCode : integer); 
begin 
    inherited Create(AErrorMessage); 
    ErrorCode := AErrorCode; 
end; 

Bây giờ bạn có thể đặt 'ErrorCode' khi bạn nêu ngoại lệ và bạn có sẵn khi ngoại lệ bị bắt. Ngoại lệ là khá mạnh mẽ.

+0

Không thực sự là một câu trả lời cho câu hỏi, nhưng là một minh chứng tốt về lý do tại sao để kế thừa từ ngoại lệ ở nơi đầu tiên. Và tôi yêu EAbort. :) Bạn có thể hủy bỏ rất nhiều thứ. Ví dụ: hủy đăng bản ghi bằng cách tăng EAbort trong OnBeforePost và nhiều lần bị gián đoạn như vậy. Tôi cũng sử dụng nó rất nhiều để hủy bỏ các hoạt động phức tạp. – GolezTrol

1

Phạm vi tổ chức chúng trong?

Sử dụng một đơn vị cho toàn bộ ứng dụng nơi bạn cố gắng vừa với các ngoại lệ chung nhất. Mọi thứ khác đi vào đơn vị nơi ngoại lệ được ném. Nếu bạn cần những ngoại lệ này trong các đơn vị khác thì hãy chuyển chúng sang một đơn vị chung được sử dụng bởi hệ thống con mà bạn đang làm việc.

Cách đặt tên?

Cố gắng thực hiện một hoặc hai cấp độ ngoại lệ "chung" như ENotFoundError. Đặt các tệp này vào tệp toàn cầu của ứng dụng. Đừng cố gắng hết sức để khái quát vì bạn không thể biết ngoại lệ nào sẽ đến sau đó yêu cầu bạn thay đổi mọi thứ. Tạo ngoại lệ chuyên biệt trên cấp độ đơn vị kế thừa từ các đơn vị toàn cầu.

Điều gì về postfix "Lỗi"?

Ngừng suy nghĩ về điều đó. Add it. Trừ khi nó có vẻ ngu ngốc.

+2

Trong trường hợp mã sử dụng giao diện rất nhiều, tôi sẽ khai báo các ngoại lệ trong đơn vị khai báo giao diện, không phải trong mã thực thi mà ném chúng – mjn

+1

@mjn Tuyệt đối. Nếu không, người dùng của giao diện không thể thực hiện kiểm tra cụ thể đối với các lớp ngoại lệ mà không nhận được sự phụ thuộc vào người triển khai ... –

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