Đại diện cho các quy tắc kinh doanh với các ngoại lệ


16

Tôi biết nó đắt tiền nhưng (IMO) Tôi tin rằng đó là một thực hành rất tốt. Tôi đang nói về các quy tắc như nói, bạn không thể lưu Hóa đơn nếu bạn không phải là người bán hàng ... vì vậy, trong trường hợp đó, hãy ném một ngoại lệ với nội dung 'bạn không được ủy quyền' hoặc ...

Một cách tiếp cận khác là nó sẽ có các đối tượng có trạng thái hoặc một cái gì đó tương tự

Có cách tiếp cận nào khác không? bạn cảm thấy thế nào

Câu trả lời:


15

Nếu bạn có nghĩa là đại diện cho kiểm tra quy tắc kinh doanh cá nhân với các ngoại lệ, thì tôi không nghĩ đó là một ý tưởng rất tốt. Nhiều lần bạn phải báo cáo nhiều hơn một điều kiện thất bại, và không dừng lại ở điều kiện đầu tiên.

Mặt khác, tôi tin rằng kiểm tra tất cả các quy tắc và sau đó ném một ngoại lệ với bản tóm tắt là một thực hành tốt.


1
Đó chính xác là cách tôi xử lý nó trong các ứng dụng của mình. Sử dụng FluentValidation để làm cho cuộc sống của tôi trở nên dễ dàng và phương thức ValidateAndThrow giúp tôi tiết kiệm một ngày.
Matteo Mosca

Trong một ứng dụng UI tôi hoàn toàn đồng ý, nhưng trong một ứng dụng cấp dịch vụ, tôi sẽ tạo ra một ngoại lệ nếu tôi được thông qua một đối tượng không tuân thủ các quy tắc kinh doanh. Nếu bạn đang sử dụng kết hợp cả hai thì đôi khi bạn và thêm một chức năng xác nhận hoặc một lỗi phức tạp như matiasha mô tả trong câu cuối cùng.
Hóa đơn

8
Ném một tên miền cụ thể ngoại lệ. Điều này cho phép bạn tách biệt giữa chúng takhông - chúng ta lên cao hơn.

@ Thorbjørn Ravn Andersen +1 "đặc thù tên miền" bổ sung tuyệt vời
Justin Ohms

1
@JamesPoulson có thể đủ để tạo JamesPoulsonExceptionthành một lớp con RuntimeExceptionvà sau đó cung cấp ngoại lệ ban đầu là cause. Sau đó, bạn có thể chỉ cần nói if (exception instanceof JamesPoulsonException)... để phân biệt. Sử dụng getCause()phương pháp để đạt được ngoại lệ ban đầu.

9

Trong ví dụ bạn đã cho chúng tôi, tôi nghĩ rằng việc đưa ra một ngoại lệ là một ý tưởng tồi. Nếu bạn biết rằng người dùng không được ủy quyền trước khi họ bắt đầu làm việc và bạn vẫn cho phép họ thực hiện một số chức năng và sau đó đập chúng bằng một thông báo SAU KHI họ đã hoàn thành nhiệm vụ, đó chỉ là một thiết kế tồi.

Sử dụng ngoại lệ để thực thi các quy tắc kinh doanh không phải là một thiết kế tốt.


Điều tôi hiểu về những gì bạn nói, là bạn không đồng ý với UI. Tôi ok với điều đó. Tôi đồng ý với bạn rằng một giao diện người dùng thân thiện hơn nhiều sẽ không cho phép bạn cố cập nhật những thứ bạn không được phép. Nhưng điều đó không có nghĩa là việc xác nhận và kiểm tra ngoại lệ trong cốt lõi kinh doanh là không cần thiết. Ngược lại, tôi tin rằng họ là phải. Bạn cần chúng để đảm bảo rằng giao diện người dùng được lập trình kém không cho phép sử dụng sai BL.
Fede

8
@Fede: đó là một câu hỏi về sự quan tâm. UI có trách nhiệm thu thập ý định của người dùng và báo cáo phản hồi từ tầng doanh nghiệp. Công việc của lớp nghiệp vụ là phân tích thông tin được thu thập bởi UI, phân tích nó và báo cáo lại cho UI và / hoặc yêu cầu lớp dữ liệu lưu lại một số dữ liệu. Chỉ nên có khớp nối lỏng lẻo giữa các lớp này. Ngoại lệ là một cách tiếp cận nghèo nàn, nghèo nàn để khớp nối lỏng lẻo. Nó không chỉ có nghĩa là chia sẻ các lớp thực tế giữa các lớp mà nó còn gọi một cơ chế có nghĩa là để xử lý các lỗi không mong muốn.
Adam Crossland

@Adam - Nói tốt và chính xác về điểm.
Walter

1
@Adam - Đừng theo bạn với sự phân tách các vấn đề quan tâm. Tôi không mong đợi bất kỳ ai trong giao diện người dùng xử lý một CustomerNameInLowercaseException (xin vui lòng, tôi cũng hy vọng rằng ngoại lệ thậm chí không tồn tại!). Bạn chỉ có thể xử lý một ExceptionException chung. Ngoài ra, tôi 100% với bạn rằng UI chỉ nên thu thập thông tin và tất cả những thứ đó. Điều tôi đã nói trước đó là bất kể bạn làm gì trong UI, BL không nên cho rằng mọi đầu vào đều ổn. Nó chỉ là một số chương trình phòng thủ.
Fede

@Fede: công việc của Layer doanh nghiệp là đảm bảo rằng mọi đầu vào đều ổn. Nếu UI đang làm điều đó thì nó đang thực hiện logic kinh doanh. Bây giờ, nếu nó là trường hợp mà một lĩnh vực đầu vào bị hạn chế đến chữ số và BL thấy alpha nhân vật, bởi tất cả các phương tiện ném một ngoại lệ . Bất cứ khi nào một thành phần nhận được đầu vào không hợp lệ từ một thành phần khác, việc ném một ngoại lệ là hợp lý và đúng đắn. Giao diện đã bị hỏng, và hệ thống bị hỏng. Tuy nhiên, xác nhận đầu vào rất khác so với thực hiện logic kinh doanh. Hai điều rất khác nhau.
Adam Crossland

5

Tôi không thấy giá trị của ngoại lệ trong việc tạo ra logic kinh doanh tốt. Có hàng tá cách tiếp cận để xử lý logic kinh doanh không liên quan đến việc sử dụng một hệ thống nhằm giải quyết các điều kiện bất ngờ trong hoạt động của một hệ thống.

Dự kiến trong logic kinh doanh, các điều kiện sẽ không được đáp ứng; đó là lý do để có nó ở vị trí đầu tiên và bạn không muốn cõng trên cùng một cơ chế xử lý các lỗi I / O bất ngờ, lỗi bộ nhớ và tham chiếu null. Đó là những thất bại của hệ thống, nhưng phát hiện các điều kiện kinh doanh chưa được đáp ứng là hoạt động thành công của hệ thống.

Ngoài ra, nó là một hệ thống đã chín muồi cho những hậu quả không lường trước được. Bởi vì một số ngoại lệ phải được bắt gặp tại một số điểm, bạn có nguy cơ có một ngoại lệ quy tắc kinh doanh mới xảy ra khi bị bắt ở một nơi nào đó mà nó không có ý định hoặc bạn có thể có mã tìm quy tắc kinh doanh bắt những ngoại lệ không thực sự có nghĩa cho nó. Đúng, những điều kiện này có thể được giải thích với các thực tiễn mã hóa tốt, nhưng trong bất kỳ hệ thống không tầm thường nào mà hơn một nhà phát triển đang làm việc, sẽ xảy ra lỗi và bạn chỉ cần hy vọng rằng chúng sẽ không phải là những sai lầm tốn kém.


1
Tôi đồng ý, các trường hợp ngoại lệ được gọi là ngoại lệ vì chúng không được dự kiến ​​sẽ xảy ra. Mặt khác, việc thực thi các quy tắc kinh doanh trong tầng dịch vụ của bạn với một ngoại lệ không nhất thiết là sai. Bạn không mong đợi nó được sử dụng, bạn mong muốn khách hàng chỉ gọi các hoạt động và chỉ gửi dữ liệu đáp ứng các điều kiện hợp lệ; nhưng bạn muốn xây dựng một lớp bảo vệ vì bạn biết lỗi cũng có thể xảy ra trong mã hóa máy khách. Giống như sử dụng các ràng buộc khóa ngoại trong cơ sở dữ liệu: bạn mong đợi mọi người chèn và cập nhật dữ liệu chính xác nhưng biết rằng họ có thể thất bại do lỗi lập trình.
Jeremy

2

thể hiện các quy tắc kinh doanh là một chuyện, thực hiện chúng là một việc khác

suy nghĩ về trải nghiệm người dùng; nếu người dùng không phải là nhân viên bán hàng, tại sao lại cung cấp cho họ nút 'tạo hóa đơn' ở tất cả ?


1
Chỉ vì bạn không đưa ra một nút, điều đó không có nghĩa là họ sẽ không gửi cho bạn tin nhắn để làm gì đó. Hãy nghĩ rằng các quy tắc bảo mật sẽ dễ dàng như thế nào nếu đó là tất cả những gì nó đã xảy ra ..
jmoreno

Nếu người dùng không được phép làm X, đừng cung cấp cho họ nút "Làm X". Bảo mật tốt nhất là sự thiếu hiểu biết - đừng nói với người dùng về những điều họ không thể làm;)
Steven A. Lowe

1

Điều đó phụ thuộc hoàn toàn vào những gì đang được thực hiện.

Đầu tiên, hành vi thực tế bạn muốn là gì? Nếu ai đó đang nhập thông tin của riêng họ, thì từ chối và hộp thoại nói, về cơ bản, "Bạn không thể làm điều đó" có lẽ là chính xác. Nếu đây là người nhập dữ liệu, làm việc từ một đống biểu mẫu, hộp thoại có thể cũng tốt và người nhập dữ liệu có thể đặt các biểu mẫu không hợp lệ vào một đống đặc biệt. Nếu bạn đang xử lý hàng loạt, bạn không muốn tạm dừng mọi thứ, nhưng hãy gắn cờ và chuyển sang phần tiếp theo.

Khi bạn có hành vi, bạn cần quyết định cách bạn sẽ thực hiện nó. Có một trình kiểm tra quy tắc kinh doanh mà ném một ngoại lệ có lẽ là một ý tưởng tốt. Trả lại mã trả về và để nó đi cùng là một điều khác có thể sai và bạn chắc chắn không muốn các mục sai lầm ngày càng xa hơn.

Đừng lo lắng về chi phí hiệu suất. Trong trường hợp một cá nhân nhập dữ liệu, nó không đáng kể so với các lần khác có liên quan. Thông thường, con người sẽ mất nhiều thời gian nhất trong hệ thống đó. Trong trường hợp của một công việc hàng loạt, nếu các trường hợp ngoại lệ là một vấn đề về hiệu suất, thì bạn đang nhập quá nhiều hồ sơ xấu, và trong thực tế xử lý và nhập lại tất cả những điều đó sẽ là một vấn đề nhiều hơn so với các ngoại lệ.


0

Có một API ngoại lệ mạnh mẽ và được thiết kế phù hợp là rất phù hợp. Sử dụng điều này để thực thi các quy tắc kinh doanh cũng có thể phù hợp. Trong thực tế theo kinh nghiệm của tôi, quy tắc kinh doanh càng phức tạp thì càng có nhiều khả năng nó sẽ bị xử lý theo cách này. Nó thường dễ dàng như vậy nếu không dễ dàng hơn để viết một hệ thống trong đó các trường hợp ngoại lệ được mong đợi hơn là viết logic phân nhánh có thẩm quyền.

Điều này có nghĩa là các quy tắc đơn giản có thể được mô tả trong một câu nói chung nên được thực hiện theo cách phòng ngừa hoặc có thẩm quyền tùy thuộc vào đó là gì. Tuy nhiên, nếu bạn có một quy tắc đa chiều và yêu cầu nhiều hơn ba hoặc bốn yếu tố (đặc biệt nếu việc lựa chọn các yếu tố này dựa trên một hoặc nhiều yếu tố khác) thì mã hóa ngoại lệ có thể được duy trì nhiều hơn. Thông thường trong các trường hợp này, đường dẫn logic sẽ có nhiều ngoại lệ cần phải được ném, (kiểm tra lý do tại sao hành động không thể được thực hiện) sau đó (hoặc ngược lại) có một sự sụp đổ đối với bảo mật (để kiểm tra xem hành động đó có được phép không ), đôi khi sẽ có một số logic tích lũy có thẩm quyền cần được kiểm tra (tính sẵn có của hậu duệ / tổ tiên, tiền thân nói rằng các đối tượng phải được đưa vào, v.v.

Một lợi ích bắt nguồn từ kiểu ném ngoại lệ này là nó cho phép bạn tách ra và sử dụng lại các ngoại lệ tiền thân trên nhiều lĩnh vực trong dự án của bạn. (Đây là bản chất của Lập trình hướng theo khía cạnh.) Bằng cách này, bạn đang gói gọn một khía cạnh cụ thể của các quy tắc kinh doanh chung của bạn trong một thành phần khép kín và có thể duy trì. Nói chung, các thành phần này sẽ tương ứng 1-1 với các thông báo lỗi được ném. (Mặc dù đôi khi bạn sẽ có một thành phần đưa ra một số ngoại lệ khác nhau, nhưng bạn hầu như không bao giờ có cùng một ngoại lệ được ném từ nhiều thành phần.)

Theo tôi, việc thiết kế các hệ thống ngoại lệ dựa trên khó khăn hơn và thời gian phát triển ban đầu dài hơn vì bạn phải xây dựng quy trình ngoại lệ trên tất cả các cấp độ N. Tuy nhiên, những hệ thống này thường ổn định hơn nhiều. Mặc dù không bao giờ có thể thiết kế một hệ thống 'sẽ không thất bại', lợi ích của thiết kế dựa trên ngoại lệ là bạn luôn lường trước được sự thất bại. Đối với hầu hết mọi người, quá trình này có thể phản trực giác. Nó giống như hỏi đường và có ai đó nói với bạn tất cả các đường phố mà bạn không nên bật.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.