2009-04-06 27 views
7

Tôi gần đây đã suy nghĩ về những điều tôi đang trở về từ phương pháp và tôi nhận thấy rằng có 4 điều khác nhau tôi trở lại khi phương pháp thất bại.Điều gì để trở về từ một phương pháp thất bại và khi nào nên ném?

Điều gì làm phiền tôi về điều này, là mã của tôi không phải là rất consitent trong lĩnh vực này, vì vậy tôi muốn hỏi về "thực hành tốt nhất của bạn".

Vì vậy, cho phép hình dung một phương pháp mà mất Foo và trả về một danh sách các Bar:

public IList<Bar> Method(Foo something); 

Hoặc để giữ cho nó tổng quát hơn:

public IBar Method(IFoo something); 

Câu hỏi đặt ra là điều gì làm bạn quay trở lại vào loại của sự thất bại. các tùy chọn sẽ là:

  1. loại trả lại trống như: Danh sách mới; hoặc: new EmptyBar();
  2. rỗng
  3. ném một ngoại lệ
  4. một giá trị danh sách đặc biệt cho thấy sự thất bại như: Danh sách mới {FailureBar mới()}

Tôi thực sự ghét tùy chọn 4 nên Tôi đang chủ yếu interessted nghe khi sử dụng 3 tùy chọn khác và lý do tại sao

Trả lời

13

Tôi muốn chọn giữa danh sách trống và ngoại lệ tùy thuộc vào bản chất của lỗi.

Ví dụ:

Nếu cơ sở dữ liệu của bạn không kết nối được - ngoại lệ.

Nếu truy vấn của bạn không trả lại kết quả - danh sách trống.

+1

Sau này không phải là lỗi. –

+2

Đó là lý do tại sao tôi nói thất bại. –

0

Nếu logic nghiệp vụ của bạn có thể khác nhau tùy thuộc vào phương thức nào sẽ trả về và do đó, phương pháp của bạn trả về danh sách trống sau đó đi với 1).

Ném ngoại lệ nếu logic nghiệp vụ của bạn không có ý định có danh sách trống. Nếu nó là do sai thông qua 'Foo một cái gì đó' đi với Assert hoặc ngoại lệ logic. Nếu nó là do vấn đề dữ liệu bên ngoài như kết nối cơ sở dữ liệu hoặc lỗi hệ thống tập tin thì ggo với ngoại lệ thời gian chạy.

Không bao giờ đi với 4) sẽ rất khó để hiểu hành vi này sau này.

0

Trường hợp 1:

Nếu Method, gặp một vấn đề, mà có thể sẽ không cần ném một ngoại lệ. Mã gọi nên chăm sóc Exception

Trường hợp 2:

Tất cả các phương pháp trường hợp khác nên trở về null/trống/danh sách với giá trị. Chức năng gọi điện phải xử lý nulltrống.

+0

Khi rỗng khi trống? Và tại sao cả hai? Nó không có nghĩa là mã hóa nhiều hơn để xử lý hoặc viết là null hoặc là sản phẩm nào? –

+0

nils_gate: tôi đề nghị KHÔNG trả lại null trong trường hợp 2. chỉ có giá trị rỗng hoặc var. – RvdK

+0

@PowerRoy: Hmm, có thể, nhưng bạn sẽ đề nghị làm gì trong trường hợp null? – NileshChauhan

4

Điều đó tùy thuộc vào ý nghĩa của từ 'lỗi'.

Nếu nó là một thất bại trong ý nghĩa rằng một cái gì đó bất ngờ xảy ra, sau đó tôi muốn ném một ngoại lệ. Có lẽ một ngoại lệ đối số cho khi tham số không chính xác, một IOException khi bạn không thể đọc từ tệp, v.v.

Nếu 'thất bại' là không có mục nào có thể được tìm thấy cho giá trị tham số đã cho, thì tôi sẽ trả về một Danh sách trống. Trong trường hợp bạn trả về một đối tượng không phải là một collection, tôi sẽ trả về null.

Tôi không bao giờ trả lại mã kết quả đặc biệt, như -1 do lỗi. Tôi thực sự không thích nó. Mọi người có xu hướng quên mã, chúng thay đổi theo thời gian, bạn kết thúc với khả năng bảo trì kém nếu các câu lệnh kiểm tra các mã kết quả này, v.v.

+0

Có lẽ một NullObject sẽ tốt hơn null. –

0

Không chắc chắn nếu chúng có thể được phổ biến áp dụng, nhưng tôi khá thoải mái với các quy tắc sau:

  1. Nếu tên phương pháp là DoFoo, nó nên ném nếu nó không thể làm Foo đối với một số lý do: tài nguyên mạng không có sẵn, làm Foo không được hỗ trợ bởi việc triển khai giao diện cụ thể này, đối tượng ở trạng thái không nhất quán, v.v.
  2. Nếu tên của phương thức là GetBar, có thêm một tùy chọn: trả về giá trị rỗng. Nhưng tốt hơn nên phản ánh điều này bằng cách đặt tên nó như TryGetBar, GetBarOrNull vv. Tất nhiên, giá trị trả về null sẽ chỉ ra một cái gì đó đặc biệt và để đáp ứng với mọi điều kiện ngoại lệ.
0

tôi sẽ ném một ngoại lệ duy nhất khi một cái gì đó gây trở ngại cho những gì tôi đang cố gắng để làm, chẳng hạn như các thông số đầu vào xấu, lỗi cơ sở dữ liệu, vv

Tôi thường đi với trả về một null trong hầu hết các trường hợp khác, bởi vì việc kiểm tra các giá trị null đến một cách tự nhiên, nhưng tôi sẽ trả về một danh sách trống nếu dữ liệu mà nó được cho là giữ đơn giản là rỗng.

2

Nếu có trường hợp ngoại lệ được mong đợi, tôi sẽ ném một ngoại lệ.

Nếu tôi đang tìm kiếm Bar và không tìm thấy nó, tôi sẽ trả về giá trị rỗng.

Nếu tôi đang tìm kiếm List<Bar> và không tìm thấy bất kỳ thông tin nào, tôi sẽ trả về số trống List<Bar>.

Nếu việc tìm kiếm null sẽ rất phổ biến, và việc sử dụng nó là hợp lý, tôi sẽ thực hiện Null Object pattern và trả về EmptyBar.

Vì vậy ... Tôi cho rằng thật công bằng khi nói rằng tôi đồng ý với các phương pháp hiện tại của bạn ngay bây giờ. Tôi chỉ đảm bảo rằng tôi đã nhất quán trong bất kỳ dự án nào và không trộn & khớp với các cách tiếp cận khác nhau với các trường hợp khác nhau.

+0

Lợi ích của Mẫu đối tượng Null khi trả về một giá trị null thực tế là gì? –

+0

Yeap, câu hỏi hay! – abatishchev

+0

Bạn không cần phải kiểm tra null mỗi lần. Hoặc nếu bạn quên kiểm tra, bạn sẽ nhận được một ngoại lệ Null Pointer, điều này rất khó chịu, bởi vì bạn sẽ không biết nguyên nhân là gì. –

1

Nếu không tìm thấy phần tử nào, hãy trả lại danh sách trống. Đây là trường hợp cụ thể của mẫu Null Object. Nó giúp xử lý tất cả các trường hợp một cách nhất quán, có nghĩa là khách hàng sẽ không phải kiểm tra xem giá trị có là không. Hoặc tệ hơn, nếu họ không kiểm tra, một Null Pointer Exception được ném và gỡ lỗi hạnh phúc để tìm ra nguyên nhân là gì. Chỉ trả về null nếu bạn có một lý do rất tốt cho nó.

Cập nhật: Martin Fowler mô tả một sự thay thế tốt hơn để trở về null: http://martinfowler.com/eaaCatalog/specialCase.html

Nhưng ném một ngoại lệ nếu phương pháp của bạn không hoạt động như nó đã được yêu cầu, trường hợp ngoại lệ cơ sở dữ liệu, trường hợp ngoại lệ dòng vv

0

Có ARW hai câu hỏi để trả lời ở đây:

  • là một sự thất bại của hàm khái niệm khác nhau từ thực hiện thường xuyên với một kết quả có sản phẩm nào? Người gọi có thể thực sự cần biết trường hợp nào trong số những trường hợp này xảy ra không? Nếu vậy, trả về một danh sách trống không phải là một lựa chọn. Tôi đoán về lý thuyết bạn có thể trả về một danh sách trống rỗng "đặc biệt", nhưng đó là sự làm xáo trộn.
  • Nếu chức năng bị lỗi, thông thường ai sẽ cần phản ứng? Nếu nó không phải là mã gọi ngay lập tức nhưng một cái gì đó cao hơn, một ngoại lệ là giải pháp sạch nhất.
1

Tôi muốn giảm nó đến ngoại lệ hoặc danh sách trả lại sản phẩm nào để giữ nó càng đơn giản càng tốt

  1. rỗng kiểu trả về như sau: Danh sách mới; hoặc: new EmptyBar();

Bạn nên trả lại điều này khi thao tác điền vào danh sách đã hoàn thành chính xác mà không có lỗi rõ ràng, nhưng không có kết quả nào được trả về - vì đây là điều ngụ ý IMO. Điều này cũng có nghĩa là mã phụ thuộc vào sự trở lại (ví dụ) vòng lặp thông qua danh sách sẽ không cần xử lý đặc biệt.

  1. ném một ngoại lệ

IMO Exceptions nên được ném ra khi một cái gì đó đã đi sai trong hàm - ví dụ không thể mở tập tin, kết nối không thể được thực hiện vv Tính toán trả lại rác - Điều này khác với "không có kết quả trả về"

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