2010-04-20 33 views
8

Mã của chúng tôi bắt được ngoại lệ chung ở mọi nơi.Làm thế nào để sử dụng lại cấu trúc của Ngoại lệ chung?

Thông thường nó ghi lỗi vào bảng nhật ký trong cơ sở dữ liệu và hiển thị MessageBox cho người dùng để nói rằng thao tác được yêu cầu không thành công. Nếu có tương tác cơ sở dữ liệu, giao dịch sẽ được khôi phục.

Tôi đã giới thiệu lớp logic kinh doanh và lớp truy cập dữ liệu để làm sáng tỏ một số logic. Trong lớp truy cập dữ liệu, tôi đã chọn không để bắt bất cứ điều gì và tôi cũng ném ArgumentNullExceptions và ArgumentOutOfRangeExceptions để thông điệp được truyền lên ngăn xếp không đi thẳng từ cơ sở dữ liệu.

Trong lớp logic nghiệp vụ, tôi thử bắt. Trong giao dịch tôi quay lại giao dịch, hãy thực hiện quá trình ghi nhật ký và truy cập lại.

Trong lớp bản trình bày, có một lần thử bắt hiển thị MessageBox.

Tôi hiện đang suy nghĩ về việc bắt một DataException và một ArgumentException thay vì một ngoại lệ mà tôi biết mã chỉ truy cập vào cơ sở dữ liệu.

Trường hợp mã truy cập dịch vụ web, tôi nghĩ mình sẽ tạo "WebServiceException" của riêng mình, lớp này sẽ được tạo trong lớp truy cập dữ liệu bất cứ khi nào HttpException, WebException hoặc SoapException bị ném.

Vì vậy, bây giờ, nói chung tôi sẽ bắt được 2 hoặc 3 ngoại lệ, hiện tại tôi chỉ bắt được ngoại lệ chung và tôi nghĩ điều đó có vẻ ổn với tôi. Có ai bọc ngoại lệ lên một lần nữa để mang thông điệp đến lớp trình bày không? Tôi nghĩ rằng tôi có lẽ nên thêm một thử bắt để Main() bắt ngoại lệ, cố gắng để đăng nhập nó, hiển thị một thông báo "Ứng dụng đã gặp lỗi" và thoát khỏi ứng dụng. Vì vậy, câu hỏi của tôi là, có ai nhìn thấy bất kỳ lỗ hổng nào trong kế hoạch của tôi không? Có bất kỳ trường hợp ngoại lệ rõ ràng mà tôi nên bắt hoặc làm những người này khá nhiều bao gồm nó (ngoài truy cập tập tin - Tôi nghĩ rằng chỉ có 1 nơi mà chúng tôi đọc-ghi vào một tập tin cấu hình).

Trả lời

2

Tôi sẽ sử dụng try/finally (hoặc câu lệnh sử dụng tương đương) cho rollback của bạn, thay vì thực hiện nó trong khối catch. Đặc biệt nếu bạn chỉ bắt các trường hợp ngoại lệ cụ thể, bạn sẽ vẫn muốn khôi phục cơ sở dữ liệu diễn ra nếu loại ngoại lệ bất ngờ được ném.

Với vài ngoại lệ hiếm khi mẹ dùng một nắm bắt bất cứ nơi nào ngoại trừ:

  • Tại một ranh giới tầng vật lý tôi sử dụng try/catch với log/ném trong khối catch để trường hợp ngoại lệ có thể đăng nhập trên máy chủ. Với các công nghệ mới hơn như ngoại lệ WCF có thể được ghi lại mà không cần thử/nắm bắt (ví dụ: với WCF DispatchBehavior).

  • Trong trình xử lý cấp cao nhất trong cấp bản trình bày.

Trong các cấp doanh nghiệp và dữ liệu, sẽ có nhiều thử/cuối cùng (tức là sử dụng câu lệnh) nhưng hầu như không bao giờ bắt được.

+0

Điểm tuyệt vời về cuối cùng hoặc sử dụng câu lệnh. Tôi đã làm điều đó khi giao dịch ở trong DAL, nhưng một số giao dịch của tôi vẫn còn trong BLL, vì vậy tôi đoán tôi sẽ cần để lộ một phương thức MyDatabase.Dispose(), hoặc bọc SqlCeTransaction của tôi cho câu lệnh "using" – Colin

+0

Không chắc chắn ý bạn là gì bởi ranh giới vật lý. Không có ranh giới ở mọi phương thức gọi từ BLL đến DAL? Trong trường hợp đó, mọi cuộc gọi trong BLL sẽ có mẫu thử đăng nhập/thử. Nhưng nếu nó có nghĩa là ranh giới vật lý giữa ứng dụng và cơ sở dữ liệu, hoặc ứng dụng và dịch vụ web, hoặc ứng dụng và hệ thống tệp, thì tôi sẽ chuyển nhật ký của mình sang DAL không phải là BLL. Nhưng bạn nói rằng bạn hầu như không có bắt trong DAL hoặc BLL, và tất nhiên tôi đã chỉ cần twigged rằng bắt nên ngồi trong lớp "MyDatabase", nơi tất cả các cập nhật chèn và xóa được thực hiện. Điều đó nghe có vẻ tốt hơn nhiều. – Colin

2

Dường như bạn đang thực hiện một số cải tiến tốt cho ứng dụng của mình. Tôi cũng thường bọc lớp ngoài cùng nhất của ứng dụng trong khối try/catch Exception để các ngoại lệ không mong muốn (ví dụ: các trường hợp thời gian chạy) có thể cho phép ứng dụng thoát ra một cách duyên dáng.

Một câu hỏi dành cho bạn là có ý nghĩa khi ủy quyền cho logic nghiệp vụ trách nhiệm của khôi phục dữ liệu. Điều này dường như được đóng gói tốt hơn trong lớp truy cập dữ liệu. Sau đó bạn có thể ném ngoại lệ từ lớp dữ liệu thay vì mở lớp đó để ném bất kỳ ngoại lệ cũ nào, bởi vì điều gì sẽ xảy ra với lớp logic nghiệp vụ của bạn nếu lớp dữ liệu của bạn ném thứ gì đó bạn không mong đợi?

Hoặc điều gì sẽ xảy ra nếu bạn sau đó trích xuất lớp truy cập dữ liệu của mình và thay thế bằng lớp khác? Ít nhất, bạn sẽ phải loại bỏ tất cả logic rollback của bạn khỏi lớp logic nghiệp vụ.

+0

Cảm ơn bạn Chris. Tôi đã xem xét tiến thoái lưỡng nan đó. Có các phương thức trong logic nghiệp vụ kết hợp các cuộc gọi truy cập dữ liệu có thể hoàn toàn nằm trong lớp truy cập dữ liệu. Mặt khác, có một số phương pháp kết hợp các cuộc gọi dữ liệu có ý nghĩa với tôi để trở thành logic nghiệp vụ. Để có được xung quanh mà tôi gọi MyDatabase.BeginTransaction() trên DAL và MyDatabase.RollbackTransaction(). Tôi chắc chắn có những cách tốt hơn để xử lý các giao dịch "Kinh doanh", nhưng ít nhất là BLL không phụ thuộc vào một SqlCeTransaction ..... – Colin

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