Tôi nghĩ rằng tất cả các câu trả lời giải thích rằng bạn không nên có một lá cờ kiểm soát xem một ngoại lệ có được ném hay không là tốt. Lời khuyên của họ sẽ là lời khuyên của tôi cho bất cứ ai cảm thấy cần phải hỏi câu hỏi đó.
Tôi đã làm, tuy nhiên, muốn chỉ ra rằng có một ngoại lệ có ý nghĩa đối với quy tắc này. Khi bạn đủ tiến bộ để bắt đầu phát triển API mà hàng trăm người khác sẽ sử dụng, có những trường hợp bạn có thể muốn cung cấp một cờ như vậy. Khi bạn đang viết một API, bạn không chỉ viết cho những người theo chủ nghĩa thuần túy. Bạn đang viết thư cho những khách hàng thực sự có ham muốn thực sự. Một phần công việc của bạn là làm cho họ hài lòng với API của bạn. Điều đó trở thành một vấn đề xã hội, thay vì một vấn đề lập trình, và đôi khi các vấn đề xã hội chỉ ra các giải pháp ít lý tưởng hơn là các giải pháp lập trình.
Bạn có thể thấy rằng bạn có hai người dùng API riêng biệt, một trong số họ muốn có ngoại lệ và một người không có ngoại lệ. Một ví dụ thực tế trong đó điều này có thể xảy ra là với một thư viện được sử dụng cả trong phát triển và trên một hệ thống nhúng. Trong môi trường phát triển, người dùng có thể sẽ muốn có ngoại lệ ở mọi nơi. Các ngoại lệ rất phổ biến để xử lý các tình huống bất ngờ. Tuy nhiên, chúng bị cấm trong nhiều tình huống nhúng vì chúng quá khó để phân tích các ràng buộc thời gian thực xung quanh. Khi bạn thực sự quan tâm không chỉ là thời gian trung bình cần thiết để thực hiện chức năng của mình, mà là thời gian cần thiết cho bất kỳ một niềm vui riêng lẻ nào, ý tưởng tháo gỡ ngăn xếp tại bất kỳ vị trí tùy ý nào là rất không mong muốn.
Một ví dụ thực tế cho tôi: một thư viện toán học. Nếu thư viện toán học của bạn có một Vector
lớp hỗ trợ nhận một vectơ đơn vị theo cùng một hướng, bạn phải có thể chia cho độ lớn. Nếu cường độ bằng 0, bạn có một chia cho tình huống bằng không. Trong sự phát triển bạn muốn bắt những thứ này . Bạn thực sự không muốn chia đáng ngạc nhiên cho 0 xung quanh. Ném một ngoại lệ là một giải pháp rất phổ biến cho việc này. Nó gần như không bao giờ xảy ra (đó là hành vi thực sự đặc biệt), nhưng khi nó xảy ra, bạn muốn biết điều đó.
Trên nền tảng nhúng, bạn không muốn những ngoại lệ đó. Nó sẽ có ý nghĩa hơn để làm một kiểm tra if (this->mag() == 0) return Vector(0, 0, 0);
. Trong thực tế, tôi thấy điều này trong mã thực.
Bây giờ nghĩ từ quan điểm của một doanh nghiệp. Bạn có thể thử dạy hai cách sử dụng API khác nhau:
// Development version - exceptions // Embeded version - return 0s
Vector right = forward.cross(up); Vector right = forward.cross(up);
Vector localUp = right.cross(forward); Vector localUp = right.cross(forward);
Vector forwardHat = forward.unit(); Vector forwardHat = forward.tryUnit();
Vector rightHat = right.unit(); Vector rightHat = right.tryUnit();
Vector localUpHat = localUp.unit() Vector localUpHat = localUp.tryUnit();
Điều này thỏa mãn ý kiến của hầu hết các câu trả lời ở đây, nhưng từ góc độ công ty thì điều này là không mong muốn. Các nhà phát triển nhúng sẽ phải học một kiểu mã hóa và các nhà phát triển phát triển sẽ phải học một kiểu khác. Điều này có thể khá phiền phức và buộc mọi người phải suy nghĩ một cách. Có khả năng tệ hơn: làm thế nào để bạn chứng minh rằng phiên bản nhúng không bao gồm bất kỳ mã ném ngoại lệ nào? Phiên bản ném có thể dễ dàng hòa trộn, ẩn ở đâu đó trong mã của bạn cho đến khi Hội đồng Đánh giá Thất bại đắt tiền tìm thấy nó.
Mặt khác, nếu bạn có một cờ bật hoặc tắt xử lý ngoại lệ, cả hai nhóm có thể học cùng một kiểu mã hóa chính xác. Trong thực tế, trong nhiều trường hợp, bạn thậm chí có thể sử dụng mã của một nhóm trong các dự án của nhóm khác. Trong trường hợp sử dụng mã này unit()
, nếu bạn thực sự quan tâm đến những gì xảy ra trong phép chia cho 0, bạn nên tự mình viết bài kiểm tra. Do đó, nếu bạn di chuyển nó sang một hệ thống nhúng, nơi bạn vừa nhận được kết quả xấu, thì hành vi đó là "lành mạnh". Bây giờ, từ góc độ kinh doanh, tôi đào tạo các lập trình viên của mình một lần và họ sử dụng cùng các API và cùng một phong cách trong tất cả các phần của doanh nghiệp của tôi.
Trong phần lớn các trường hợp, bạn muốn làm theo lời khuyên của người khác: sử dụng các thành ngữ giống tryGetUnit()
hoặc tương tự cho các hàm không đưa ra ngoại lệ và thay vào đó trả về giá trị sentinel như null. Nếu bạn nghĩ rằng người dùng có thể muốn sử dụng cả mã xử lý ngoại lệ và mã xử lý không ngoại lệ cạnh nhau trong một chương trình, hãy sử dụng tryGetUnit()
ký hiệu. Tuy nhiên, có một trường hợp góc mà thực tế kinh doanh có thể làm cho nó tốt hơn để sử dụng cờ. Nếu bạn thấy mình trong trường hợp góc đó, đừng ngại ném "quy tắc" bên đường. Đó là những quy tắc dành cho!