2010-11-15 40 views
28

tôi có hai lựa chọn (mà về mặt kỹ thuật là như nhau, như tôi hiểu) để khai báo một lớp tùy chỉnh Ngoại lệ duy nhất ném từ một lớp học đặc biệt com.XXX.Foo:Exceptions như các lớp học nào so với các lớp bên trong public static

  • như một public class trong gói: com.XXX.CustomException
  • như một lớp bên trong tĩnh công cộng: com.XXX.Foo.CustomException tùy chọn

Đó là tốt hơn?

+1

Có thể áp dụng cùng một câu hỏi và tùy chọn cho bất kỳ lớp học nào. Có một đặc điểm của ngoại lệ mà làm cho chúng đặc biệt thích hợp để làm tổ, hay là câu hỏi đơn giản hỏi [khi nào sử dụng các lớp lồng nhau?] (Https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html) – jaco0646

Trả lời

15

Trong trường hợp ngoại lệ rất cụ thể đối với lớp học Foo, tôi không lưu ý rằng nó là một lớp học được tổ chức public. Và bất cứ khi nào nó có vẻ như một thời gian để giải nén nó ra, chỉ cần giải nén ra.

Nói chung, tôi chưa bao giờ thấy bất kỳ lớp lồng nhau nào được xác định cho Ngoại lệ. Tôi cũng không biết liệu có tồn tại trong Java API hay không.

3

Tôi thích lớp (không nhất thiết phải công khai) trong cùng một gói, vì gói là nhóm lôgic hợp lý mô tả mô hình kinh doanh, ngoại lệ thuộc về phần kỹ thuật.

Người dùng sẽ thấy ngay rằng có ngoại lệ khi anh xem gói và không cần phải đọc tệp của lớp foo, điều này tốt hơn cho việc bảo trì và lý do rõ ràng/dễ đọc/hiểu. Nó rất tốt để xác định ngoại lệ tùy chỉnh và cho người dùng API biết về nó!

Tôi chỉ sử dụng lớp bên trong khi rõ ràng là điều riêng tư của lớp học được đề cập.

Tuy nhiên, chúng tôi đang nói ở đây về một vấn đề chủ yếu là thông thường!

+0

Làm thế nào về một lớp mở rộng 'javax.swing.RowFilter.Entry'? –

+2

Các gói được sử dụng để nhóm các mô hình lôgic, vì vậy trong nhóm của chúng tôi, chúng tôi đồng ý với quy ước rằng mỗi lớp sẽ có tệp riêng của mình.Mô hình kinh doanh trong gói có nhiều khả năng kết hợp khá chặt chẽ, vì vậy tôi không thể thấy lợi ích khi sử dụng một lớp lồng nhau. Lớp lồng nhau khá nhiều thể hiện: Tôi không thể tách rời thuộc về lớp khác này. Đối với một số API, có thể tốt khi thiết kế nó như thế, ví dụ nếu toàn bộ mô hình bên trong gói được kết hợp là loại rời. – Falcon

+2

Bạn CÓ THỂ mở rộng các lớp bên trong tĩnh. –

9

Trong hơn 10 năm kinh nghiệm của tôi với Java, tôi không thể nhớ lại việc gặp một API trong đó một lớp ngoại lệ công khai được định nghĩa là lớp bên trong tĩnh. Tôi không thể cho bạn một lý do cụ thể tại sao nó sẽ là một ý tưởng tồi để làm điều này, nhưng nó chắc chắn sẽ làm cho mã của bạn bất thường.

Tại sao bạn cảm thấy cần phải làm điều này, cho rằng (dường như) không ai khác làm được? Tôi hy vọng bạn không chỉ làm điều đó để được "sáng tạo".

(BTW, tôi biết rằng một số API Java nổi tiếng sử dụng các lớp bên trong tĩnh công cộng và giao diện cho những thứ khác. Tôi đặc biệt nói về trường hợp của các lớp ngoại lệ ở đây.)

+2

Hãy xem lớp này từ Apache Lucene 3.5: [org.apache.lucene.search.BooleanQuery.TooManyClauses] (http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/api/all/org/ apache/lucene/search/BooleanQuery.TooManyClauses.html) – yegor256

+1

OK. Một ví dụ trong hơn 10 năm. (Nhưng tại sao họ làm điều đó?) –

+2

Vâng, tôi nghĩ rằng nó có ý nghĩa khi ngoại lệ được ném _only từ một class_. Trong trường hợp đó, nó phải được định nghĩa là một lớp bên trong tĩnh. Khi bạn xóa lớp học - ngoại lệ cũng sẽ bị tắt. Nói cách khác, chúng sẽ được "kết hợp chặt chẽ". – yegor256

-3

Exceptions như các lớp bên trong được một ý tưởng tồi nói chung bởi vì bản chất chúng có thể được nâng lên qua các cấp độ khác nhau, ngay cả trong các kiến ​​trúc đơn giản. Lớp ngoại lệ được nâng lên phải được tham chiếu từ lớp chứa của nó, và nếu lớp đó không được biết đến với classpath thì có thể một cái gì đó xấu sẽ xảy ra giống như một ClassCastException.

8

Tôi chắc chắn có thể nghĩ về các tình huống mà tôi muốn thích ngoại lệ là lớp bên trong tĩnh hơn là chỉ một lớp trong cùng một gói.

Những lý do không nên làm như vậy dường như là:

  • Khớp nối các ngoại lệ đối với lớp mà ném nó làm cho nó không thích hợp để tái sử dụng trong những bối cảnh khác
  • Không ai khác nó

Tôi không tìm thấy một trong những lập luận đó ở tất cả các thuyết phục.

Đối với điểm đầu tiên, tại sao cơ hội giả thuyết trong tương lai này để tái sử dụng trong cùng một gói? Lập luận này dẫn đến kết luận rằng chúng ta nên đặt tất cả các lớp ngoại lệ càng cao càng tốt trong phân cấp gói để khi chúng ta khám phá ra một cơ hội trong tương lai để tái sử dụng cùng một ngoại lệ, chúng ta không phải giới thiệu sự phụ thuộc vào nơi nó được định nghĩa ban đầu.

Nhưng ngay cả khi không có điểm "bị đưa đến cực đoan", hãy xem xét ngoại lệ nhằm truyền đạt lớp đó Foo được nhập sai. Nếu tôi gọi nó là Foo.InvalidInput, tên này ngắn và liên kết với Foo là không thể bỏ qua. Nếu tôi đặt nó bên ngoài lớp Foo và gọi nó là FooInvalidCriteria, thì tôi không thể sử dụng lại nó từ lớp Bar, mà không thay đổi tên của nó (tương đương với thay đổi vị trí của nó).

Nhưng điều tồi tệ nhất là nếu tôi để nó ở bên ngoài Foo và giữ tên chung như InvalidInput. Sau đó, khi tôi nhận ra rằng Bar cũng có thể có thông tin nhập không hợp lệ và làm cho nó bắt đầu ném ngoại lệ này. Mọi thứ biên dịch và chạy tốt, chỉ bây giờ tất cả các địa điểm bắt được InvalidInput và giả sử chúng xử lý các lỗi từ Foo bây giờ cũng có thể xử lý lỗi từ Bar nếu Foo xảy ra sử dụng Bar nội bộ theo cách có thể gây ra ngoại lệ này. Điều này có thể dễ dàng gây ra sự cố mã. Thực tế là lấy một ngoại lệ mà trước đây đã được hình thành như cụ thể cho thấy một tình huống phát sinh trong một lớp và tái sử dụng nó như là một lớp lỗi chung là một sự thay đổi giao diện, chứ không chỉ là thay đổi thực hiện nội bộ. Để làm như vậy một cách chính xác nói chung bạn phải truy cập lại tất cả các trang web nơi ngoại lệ bị bắt và đảm bảo chúng vẫn đúng, vì vậy trình biên dịch cho bạn biết về tất cả các trang web sử dụng (vì bạn phải thay đổi tên và/hoặc đường dẫn nhập) là một điều tốt. Bất kỳ ngoại lệ nào mà bạn có thể tạo một lớp bên trong tĩnh là không thích hợp để tái sử dụng trong các ngữ cảnh khác cho dù bạn thực sự biến nó thành một lớp bên trong hay không.

Và đối với điểm chấm thứ hai ... "không ai khác làm điều đó" không bao giờ chịu bất cứ điều gì. Hoặc nó thực sự là điều sai trái để làm, vì vậy sẽ có những lý do khác không để làm điều đó, do đó, "không ai khác làm nó" đối số là không cần thiết. Hay không. Và nó không giống như ví dụ cụ thể này thậm chí sẽ phức tạp và khó hiểu, vì vậy thậm chí không "nó bất ngờ để mọi người sẽ gặp rắc rối sau khi nó là một ý tưởng hay về lý thuyết" đối số rất mạnh.

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