2009-01-05 35 views
8

Giả sử tôi có một phương phápHợp đồng nào (Thiết kế theo hợp đồng) tốt hơn?

public Patient(int id) 
{ 
    ---- 
} 

trả về đối tượng bệnh nhân đưa ra một id .. Tôi có thể xác định hợp đồng trong 2 cách

  1. Phương sẽ trả về null nếu bệnh nhân không tồn tại
  2. Phương pháp sẽ ném ngoại lệ nếu bệnh nhân không tồn tại. Trong trường hợp này, tôi cũng sẽ xác định phương thức truy vấn trả về true nếu Bệnh nhân tồn tại trong cơ sở dữ liệu hoặc sai khác ...

Tôi nên sử dụng hợp đồng nào? Bất cứ một đề nghị nào khác?

Cập nhật: Xin nhận xét về trường hợp này quá ... Nếu nó không phải là một cơ sở dữ liệu Id giao và nó là một cái gì đó một người dùng nhập vào giao diện người dùng .. như SSN .. sau đó cái nào là tốt hơn ..

Bình luận về mô hình Null từ Steve mà tôi nghĩ là hợp lệ: có lẽ không phải là một ý tưởng tốt ở đây, vì nó sẽ thực sự hữu ích để biết ngay lập tức khi một ID không tồn tại.

Và tôi cũng nghĩ rằng mô hình Null đây sẽ là trọng lượng hơi nặng

Cảm nhận từ Rob Wells vào ném ngoại lệ vì Id xấu của nó: tôi không nghĩ rằng một lỗi đánh máy trong tên của bệnh nhân là một hoàn cảnh đặc biệt" IMHO

Trả lời

15

Lưu ý rằng chuyển "qua dây" sang một cấp khác (cho dù cơ sở dữ liệu hoặc máy chủ ứng dụng) là một trong những hoạt động đắt nhất bạn có thể thực hiện - thường là cuộc gọi qua mạng sẽ mất nhiều đơn hàng hơn các cuộc gọi -memory.

Do đó, đáng giá trong khi cấu trúc API của bạn để tránh các cuộc gọi dư thừa.

xem xét, nếu API của bạn là như thế này:

// Check to see if a given patient exists 
public bool PatientExists(int id); 

// Load the specified patient; throws exception if not found 
public Patient GetPatient(int id); 

Sau đó, bạn có khả năng để đạt cơ sở dữ liệu hai lần - hoặc là phụ thuộc vào bộ nhớ đệm tốt để tránh điều này.

Một lưu ý khác là: Ở một số nơi, mã của bạn có thể có id "đã biết", ở những nơi khác thì không. Mỗi vị trí yêu cầu một chính sách khác nhau về việc có nên ném ngoại lệ hay không.

Dưới đây là một mô hình mà tôi đã sử dụng để hiệu quả tốt trong quá khứ - có hai phương pháp:

// Load the specified patient; throws exception if not found 
public Patient GetExistingPatient(int id); 

// Search for the specified patient; returns null if not found 
public Patient FindPatient(int id); 

Rõ ràng, GetExistingPatient() có thể được xây dựng bằng cách gọi FindPatient().

Điều này cho phép mã gọi của bạn nhận được hành vi thích hợp, ném ngoại lệ nếu có sự cố và tránh xử lý ngoại lệ trong trường hợp không cần thiết.

+0

Mặc dù về các tầng thay thế +1 –

+0

Awesome ... Thiết kế theo hợp đồng – StackUnderflow

4

một lựa chọn khác sẽ là Null Object pattern.

+0

có thể không phải là một ý tưởng tốt ở đây, vì nó sẽ thực sự hữu ích để biết ngay lập tức khi một ID không tồn tại. –

+0

Tôi không thực sự thấy cách đó sẽ là một lợi ích trong trường hợp này. –

+0

Cho dù đó có phải là một lợi ích hay không, anh ta đã yêu cầu các lựa chọn khác; Nó * IS * một lợi ích cho những người khác sau này đọc câu hỏi này để biết về tùy chọn này. –

4

bạn có lẽ nên ném một ngoại lệ. Nếu bạn có một id mà không trỏ đến một bệnh nhân hợp lệ, nơi mà nó đến từ đâu? một cái gì đó rất xấu đã có khả năng xảy ra. Đó là một trường hợp đặc biệt nce.

CHỈNH SỬA: Nếu bạn đang làm điều gì khác hơn là truy xuất dựa trên số nguyên, như tìm kiếm dựa trên văn bản, sau đó trả lại null là tốt. Đặc biệt là trong trường hợp đó bạn đang trả lại một tập hợp các kết quả, có thể nhiều hơn một (nhiều hơn một bệnh nhân có cùng tên, cùng ngày sinh, hoặc bất kỳ tiêu chí nào của bạn).

Chức năng tìm kiếm phải có hợp đồng khác với chức năng truy xuất.

+0

+1 - ID không hợp lệ là lỗi/ngoại lệ –

+0

tôi không nghĩ lỗi đánh máy của bệnh nhân là trường hợp ngoại lệ "IMHO –

+0

@ [Rob Wells]: hàm trong câu hỏi lấy ID nguyên làm đầu vào chứ không phải của bệnh nhân name –

1

Trong một tình huống đơn giản như thế này 1. có vẻ là quá đủ. Bạn có thể muốn thực hiện một cái gì đó giống như một phương thức gọi lại mà khách hàng gọi để biết tại sao nó trả về null. Chỉ là một gợi ý.

2

Đối với trường hợp này, tôi sẽ có phương thức trả về null cho một bệnh nhân không tồn tại.

Tôi có xu hướng thích sử dụng ngoại lệ để hỗ trợ sự xuống cấp nghiêm trọng khi có sự cố với chính hệ thống.

Trong trường hợp này, nó có lẽ là mosdt:

  1. một lỗi đánh máy trong ID của bệnh nhân nếu nó đã được nhập vào một hình thức tìm kiếm,
  2. một lỗi nhập dữ liệu, hoặc
  3. một vấn đề công việc trong rằng hồ sơ của bệnh nhân anh ta chưa được nhập vào.

Do đó, trả lại giá trị không phải là ngoại lệ.

Nếu có sự cố khi liên hệ với cơ sở dữ liệu, thì tôi sẽ có phương pháp tăng ngoại lệ.

Chỉnh sửa: Chỉ thấy ID bệnh nhân trong chữ ký là số nguyên, cảm ơn Steven Lowe, vì vậy tôi đã sửa danh sách các lý do của mình.

Điểm cơ bản của tôi về khoanh vùng khi sử dụng ngoại lệ (đối với lỗi hệ thống) so với các phương pháp trả về lỗi (đối với lỗi nhập dữ liệu đơn giản) vẫn là viết tắt. IMHO.

HTH

cổ vũ,

Rob

1

tham descriptiong tại mệnh giá, có thể bạn cần cả hai:

  • ID xấu là lỗi/trường hợp ngoại lệ, như Adam chỉ ra, nhưng
  • nếu bạn được cấp ID ở nơi khác có thể đã biến mất, bạn sẽ cần phương pháp truy vấn để kiểm tra m
0

Giả sử tôi đọc mà chính xác ... Khi bạn gọi bệnh nhân (100) nó sẽ trả về một tham chiếu đối tượng cho một bệnh nhân với một id của 100. Nếu không kiên nhẫn với một id của 100 tồn tại, tôi nghĩ rằng nó sẽ trả về null. Các trường hợp ngoại lệ là IMO bị lạm dụng và trường hợp này không gọi cho nó. Hàm này trả về một giá trị rỗng. Nó đã không tạo ra một số trường hợp sai lầm có thể sụp đổ ứng dụng của bạn (trừ khi tất nhiên, bạn đã kết thúc không xử lý null và thông qua nó xung quanh một số phần khác của ứng dụng của bạn). Tôi chắc chắn sẽ có chức năng trả về 'null', đặc biệt nếu nó là một phần của một số tìm kiếm, nơi người dùng sẽ tìm kiếm bệnh nhân có ID cụ thể và nếu tham chiếu đối tượng kết thúc bằng null, nó sẽ chỉ đơn giản là trạng thái không có bệnh nhân nào tồn tại.

2

Nó phụ thuộc:

Nếu bạn xem xét các hoạt động bình thường sẽ dẫn đến một số pation không phù hợp với một tập tin trong DB sau đó là một kỷ lục rỗng (NULL) nên được trả lại.

Nhưng nếu bạn mong đợi rằng một ID nhất định phải luôn ghi một bản ghi thì khi không tìm thấy một bản ghi (điều này hiếm khi xảy ra) thì hãy sử dụng một ngoại lệ.

Những thứ khác như lỗi kết nối DB sẽ tạo ra ngoại lệ.
Như bạn mong đợi trong các tình huống bình thường, truy vấn tới DB luôn hoạt động (mặc dù nó có thể trả về 0 bản ghi hay không).

P.S. Tôi sẽ không trả về một con trỏ. (Ai sở hữu con trỏ?)
Tôi sẽ trả về một đối tượng có thể có hoặc không có bản ghi. Nhưng bạn có thể can thiệp vào sự tồn tại của bản ghi bên trong. Có khả năng là một con trỏ thông minh hoặc somthing hơi thông minh hơn một con trỏ thông minh hiểu được cotext.

0

Ném ngoại lệ.

Nếu bạn quay trở lại null, mã như thế này:

Console.WriteLine(Patient(id).Name); 

sẽ thất bại với một NullReferenceException nếu id không tồn tại, mà không phải là hữu ích như một nói một PatientNotFoundException (id). Trong ví dụ này, nó vẫn còn tương đối dễ dàng để theo dõi xuống, nhưng xem xét:

somePatient = Patient(id) 

// much later, in a different function: 

Console.WriteLine(somePatient); 

Về thêm một chức năng để kiểm tra xem bệnh nhân tồn tại: Lưu ý điều này sẽ không ngăn cản PatientNotFoundExceptions hoàn toàn. Ví dụ:

if (PatientExists(id)) 
    Console.WriteLine(Patient(id).Name); 

- một luồng khác hoặc quy trình khác có thể xóa bệnh nhân giữa các cuộc gọi đến bệnh nhân và bệnh nhân. Ngoài ra, điều này có nghĩa là hai truy vấn cơ sở dữ liệu thay vì một. Thông thường, tốt hơn là chỉ cần thử gọi và xử lý ngoại lệ.

Lưu ý rằng tình huống khác với các truy vấn trả lại nhiều giá trị, ví dụ: như một danh sách; ở đây, nó là thích hợp để trả về một danh sách trống nếu không có kết quả phù hợp.

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