2008-11-30 23 views
8

Hãy cho tôi một số suy nghĩ của bạn về việc thực hành mã hóa tốt hơn/tạo mã hiệu quả hơn/trông đẹp hơn/bất cứ điều gì: Tăng và cải thiện khả năng sử dụng của bạn nếu các câu lệnh dự đoán và nắm bắt các vấn đề tiềm ẩn? Hoặc đơn giản là sử dụng tốt thử/nắm bắt nói chung?Sử dụng kỹ lưỡng các câu lệnh 'if' hoặc các khối 'try/catch'?

Hãy nói điều này là dành cho Java (nếu nó quan trọng).

Chỉnh sửa: Tôi hiện đang tự chuyển đổi khỏi một số thực tiễn mã hóa hiện tại đã bị thừa nhận và bị hạn chế, nhưng tôi hơi rách về sự cần thiết phải thực hiện một vài điểm (như thế này). Tôi chỉ đơn giản là yêu cầu một số quan điểm về điều này. Không phải là một cuộc tranh luận.

Trả lời

1

My 2p: Sử dụng try/catch là tốt nhất:

  • nó làm cho nó hoàn toàn rõ ràng đối với lập trình khác mà bạn đang làm xử lý
  • trình biên dịch ngoại lệ hiểu những gì bạn đang làm và có thể thực hiện biên dịch thích hợp hơn kiểm tra thời gian cho bạn

Theo kinh nghiệm của tôi, việc phân biệt xử lý lỗi từ logic nghiệp vụ trở nên khó khăn hơn.

+0

"Xử lý lỗi" và "Xử lý ngoại lệ" không giống nhau. – ThunderGr

4

if khối hơi nhanh hơn; nếu bạn không cần một tá trong số đó, thì đó là ý tưởng hay hơn try/catches. Ngoại lệ phải là ngoại lệ, không phải mỗi khi mã chạy. Tôi sử dụng Ngoại lệ cho các sự kiện hiếm gặp như ngắt kết nối máy chủ (mặc dù chúng xảy ra vài lần mỗi ngày) và các khối if cho bất kỳ biến có thể điều khiển nào của tôi.

+1

Nếu/nói chung thường nhanh hơn thử/nắm bắt, nhưng nó chậm hơn so với không có mã nào cả. Nếu bạn có nhiều mức độ gọi, một if/else tại mỗi trang gọi để truyền lỗi bằng giá trị trả về có thể chậm hơn một lần thử/nắm bắt ở đầu trong trường hợp không có lỗi nào xảy ra. –

2

Tôi nghĩ rằng nếu báo cáo là tốt hơn. Bạn không thể bao quanh tất cả các dòng mã với một try..catch (bạn cũng có thể nhưng bạn không nên làm điều đó). Bạn có thể bao quanh một khối mã với try catch nhưng không phải mọi dòng.

Và ngoại lệ làm chậm mọi thứ.

+2

Trường hợp ngoại lệ chỉ làm chậm mọi thứ khi chúng thực sự bị ném. Vì vậy, miễn là bạn đảm bảo chúng chỉ được ném trong trường hợp đặc biệt (nơi hiệu suất thường không còn quan trọng bởi vì bạn sẽ thất bại), nó không phải là một mối quan tâm. –

+0

@Steve Jessop Nếu thử/nắm bắt chậm hơn câu lệnh if, ngoại lệ làm những điều chậm xuống ngay cả khi không được ném (so với câu lệnh if). Xét cho cùng, một khối try/catch, ít nhất, phải kiểm tra xem trường hợp ngoại lệ có được ném vào phần mã này hay không. – ThunderGr

+1

@ThunderGr: điều này phụ thuộc vào ngôn ngữ lập trình và thực hiện (tất nhiên), nhưng đối với các ngôn ngữ biên dịch, * không * cần thiết cho khối try/catch để kiểm tra xem một ngoại lệ đã được ném vào điểm đó của mã hay chưa. Thay vào đó, tất cả các khối catch có thể được rút ra khỏi dòng (nói, thu thập chúng ở cuối hàm hoặc thậm chí ở cuối của tệp thực thi), cùng với một số siêu dữ liệu về các vùng mã được bao phủ bởi các lần thử tương ứng của chúng. Mã/dữ liệu này chỉ cần được truy cập khi một ngoại lệ được ném và thời gian chạy sẽ đi lên ngăn xếp. –

3

Bất kể bạn đang viết mã nào, bạn sẽ sử dụng cả hai. Tôi không thể nói cho thời gian chạy Java, nhưng trên thời gian chạy .NET có một hit hiệu suất liên quan đến việc sử dụng các khối try-catch. Kết quả là, tôi cố gắng sử dụng chúng chỉ trong các lĩnh vực mà tôi đã có một cách rõ ràng để xử lý các trường hợp ngoại lệ một lần bị bắt (ngay cả khi nó chỉ đăng nhập sự tồn tại của một vấn đề).

Nếu bạn thấy mình sử dụng nhiều khối try-catch hoặc if-else chặn trong mã của bạn, hoặc phương pháp của bạn có xu hướng khá dài, hãy xem xét tái cấu trúc mã vào một số lượng lớn các phương thức nhỏ hơn. Mục đích của logic của bạn sẽ dễ theo dõi hơn - cũng như kiểm tra đơn vị dễ dàng hơn.

1

Từ những gì tôi đã được các nhà phát triển và nhà phân tích có kinh nghiệm phát biểu, thử/nắm bắt được hướng đối tượng hơn và nếu có nhiều thủ tục hơn.

Cá nhân tôi không quan tâm.

Tôi biết thực tế là thử/bắt chậm hơn và gây ra hiệu suất, nhưng nếu tôi sử dụng một tá ifs để xác thực trước khi tôi có thể làm những gì tôi muốn, tôi sẽ luôn sử dụng try/catch để lưu vào số dòng mã.

Nó làm cho cuộc sống của tôi dễ dàng hơn nhiều để không phải xác nhận bất cứ điều gì và nếu tuyên bố không thành công, chỉ cần làm những gì tôi đã làm trong khối 'khác' của tôi ... trong khối 'catch' của tôi.

Đôi khi, tôi rõ ràng kèm theo một số câu lệnh if trong try/catch, nhưng anyways.

Tôi sử dụng nếu khi chỉ có một số ít thứ để xác thực (1 hoặc 2) trước khi thực hiện những gì tôi cần làm.

+0

Cuối cùng, câu trả lời ở đây nói về việc truyền đạt ý tưởng hiệu quả và làm cho mọi thứ dễ hiểu và dễ hiểu hơn. Tôi cảm thấy nhiều câu trả lời trên trang web này quên rằng thực tế quan trọng về mã hóa và nói về mã trong một thế giới hoàn hảo. Những câu trả lời này thường đưa ra lời khuyên thực hành tốt nhất về tốc độ chạy hoặc sự an toàn nhưng không tính đến câu hỏi và liệu giải pháp đó có hợp lý để thực hiện hay không. Các phương pháp hay nhất thường nhanh và dễ dàng, nhưng trong các trường hợp góc phần mềm thực sự phát sinh, nơi các thực hành này có thể trở nên dài và phức tạp; và đơn giản hóa mã là cần thiết –

0

Có một điều chưa được đề cập ở đây.

Với câu lệnh if-else, mỗi khi mã chạy, ít nhất 1 điều kiện được đảm bảo sẽ được đánh giá được thực thi. Tôi chắc rằng tất cả chúng ta đều biết cách hoạt động của if-else-elseif, nhưng phải rõ ràng ... nếu phần của câu lệnh sẽ luôn được đánh giá, nếu sai thì sau đó khác-nếu được đánh giá, và cứ thế cho đến khi chỉ có khác thì còn lại để đánh giá.

Vì vậy, việc sử dụng câu lệnh if-else sẽ ảnh hưởng đến hiệu suất của bạn. Không đáng kể (trong hầu hết các trường hợp), nhưng nó mất thời gian CPU để thực hiện các đánh giá.

câu lệnh try-catch và sửa tôi nếu tôi sai, không được xem xét trong thời gian chạy cho đến khi chúng được yêu cầu (nghĩa là ngoại lệ được ném). Vì vậy, chỉ đơn giản là gói mã của bạn trong một thử-catch sẽ không ảnh hưởng đến hiệu suất cho đến khi một ngoại lệ thực sự bị bắt bởi nó.

Ngoài ra, nó không phải là đánh bắt gây ra hiệu suất trúng, nhưng ném.

Và một điểm chính cần làm là, các câu lệnh try-catch KHÔNG BAO GIỜ được sử dụng cho logic điều kiện. Chúng chỉ nên được sử dụng cho những gì chúng được thiết kế cho: xử lý ngoại lệ!

Bắt ngoại lệ là điều cần thiết, nếu bạn biết phải làm gì với chúng. Nếu bạn không có cách xử lý đúng ngoại lệ thì bạn nên để nó đi, vì một số mã tiếp tục chuỗi có thể có cách tốt hơn để xử lý nó.

Một ý tưởng hay là có trình xử lý ngoại lệ ở cấp cao nhất tuyệt đối của ứng dụng để bắt ngoại lệ trước khi người dùng nhìn thấy. Trong ASP.NET bạn có thể làm điều này trong sự kiện Application_Error của global.asax. Trong các ngôn ngữ khác/môi trường bạn sẽ làm như vậy trong vòng lặp chính của bạn, bất cứ điều gì có thể được.

Nhưng lưu ý, có một số trường hợp ngoại lệ luôn bị bỏ rơi tốt nhất. Đôi khi, khi ngoại lệ xảy ra, đó là chỉ báo cho biết trạng thái đơn đăng ký của bạn đã bị xâm phạm nghiêm trọng và không thể tin cậy được. Điều an toàn duy nhất cần làm là giết và khởi động lại.

+0

Làm thế nào bạn có thể nói rằng một try/catch * không được xem xét trong thời gian chạy cho đến khi chúng được yêu cầu *? Điều này nghe giống như một loại ma thuật lập trình. Không có những thứ như mã * không được xem xét cho đến khi cần thiết *. Bạn cần phải có * ít nhất * một kiểm tra xem nó có cần thiết hay không. – ThunderGr

+0

Câu trả lời của Steve ở trên, để bình luận của tôi, cung cấp một lời giải thích hợp lý tại sao một khối try/catch sẽ không được xem xét ở tất cả cho đến khi một ngoại lệ xảy ra.Nó đòi hỏi một máy ảo để chạy trên, mặc dù và nó trông giống như * runtimes * của các ngôn ngữ cung cấp máy ảo này. Tôi nghi ngờ kiến ​​trúc CPU có bất kỳ hỗ trợ cho trường hợp ngoại lệ. Phải không? – ThunderGr

+0

@ThunderGr Tôi không thể nói cho tất cả các ngôn ngữ nhưng mikesigs là chính xác ít nhất là cách C++ xử lý ngoại lệ. Trong C++ phần bắt của khối được bỏ qua cho đến khi một ngoại lệ được ném và ngăn xếp bắt đầu giãn ra. Khi ngăn xếp thư giãn, mã tìm kiếm một khối catch để ngăn chặn quá trình thư giãn. Nếu không có gì được tìm thấy có khả năng ngoại trừ ngoại lệ. chương trình thoát. –

0

@PersonalPerson - Xin lỗi, nhưng đây chỉ là viết mã lười. Thay vì sử dụng try-catch vì có quá nhiều câu lệnh if, tại sao không refactor mã của bạn (tức là đặt logic xác nhận của bạn theo phương thức riêng của nó). Điều này sẽ giữ cho mã của bạn sạch hơn và dễ đọc hơn và duy trì các phương pháp hay nhất để thực hiện.

Không bao giờ cố gắng viết mã của bạn để đạt được ít nhất số dòng. Điều này sẽ luôn luôn kết thúc tồi tệ. Chắc chắn bạn có thể tìm thấy một cách thanh lịch hơn để viết một cái gì đó mà bạn bè coder của bạn sẽ ooh và aah tại, nhưng nó chỉ làm cho mọi thứ ít dễ đọc hơn.

Tôi xin thề, tôi đã làm việc với mã của bạn trước đây và nó làm tôi đau đầu.

+0

Thật không may tuyên bố này thực sự phụ thuộc vào ngôn ngữ. Trong một số ngôn ngữ có câu lệnh if với nhiều kiểm tra, như 6 hoặc 10+ kiểm tra, trong đó câu lệnh if sẽ được gọi là 90 +% thời gian có thể mất nhiều thời gian xử lý tùy thuộc vào cách mã được tối ưu hóa. Trong trường hợp này, sử dụng khối catch try sẽ cho cả bộ xử lý và các bộ lập trình khác biết đây là mã tôi muốn chạy hầu hết thời gian có khả năng tăng tốc độ chạy tùy thuộc vào ngôn ngữ. Trong bất kỳ trường hợp nào khác, tôi đồng ý với bạn, trừ khi bạn sử dụng ngôn ngữ gõ vịt như python. –

0

Sử dụng ngoại lệ là phương pháp phổ biến để thông báo cho một phần mã khác có điều gì đó sai xảy ra theo cách được kết hợp lỏng lẻo. Hãy tưởng tượng rằng nếu bạn muốn xử lý một số điều kiện đặc biệt bằng cách sử dụng nếu .. nad else .. bạn cần phải chèn vào một phần khác nhau của mã của bạn một số biến tùy ý và các công cụ khác mà có lẽ sẽ dễ dàng dẫn đến có mã spaghetti ngay sau đó.

Hãy tưởng tượng rằng bạn đang sử dụng bất kỳ thư viện/gói bên ngoài nào và tác giả đã quyết định đặt mã của mình theo cách tùy ý khác để xử lý các trạng thái sai - nó sẽ buộc bạn phải điều chỉnh theo cách của nó. ví dụ bạn sẽ cần phải kiểm tra xem các phương thức cụ thể có trả về true hay false hay bất cứ thứ gì.

Sử dụng ngoại lệ khiến lỗi xử lý dễ dàng hơn nhiều - bạn chỉ giả định rằng nếu xảy ra lỗi - mã khác sẽ ném ngoại lệ, vì vậy bạn chỉ cần quấn mã trong khối thử và xử lý ngoại lệ có thể theo cách của riêng bạn.

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