paint-brush
Tầm quan trọng thực sự của các ngoại lệ: Xử lý lỗi trong PHP so với Golangtừ tác giả@shcherbanich
8,399 lượt đọc
8,399 lượt đọc

Tầm quan trọng thực sự của các ngoại lệ: Xử lý lỗi trong PHP so với Golang

từ tác giả Filipp Shcherbanich7m2023/10/20
Read on Terminal Reader
Read this story w/o Javascript

dài quá đọc không nổi

Nhìn lại, cách chúng tôi xử lý lỗi cho thấy nhu cầu và thách thức của nhà phát triển đã thay đổi như thế nào theo thời gian.
featured image - Tầm quan trọng thực sự của các ngoại lệ: Xử lý lỗi trong PHP so với Golang
Filipp Shcherbanich HackerNoon profile picture

Gần đây, tôi có một cuộc trò chuyện thú vị với một người bạn, giống như tôi, là nhà phát triển phần mềm. Chúng tôi đang thảo luận về cách các ngôn ngữ lập trình khác nhau xử lý lỗi và điều đó đã dẫn đến một số bất đồng. Chúng tôi tự hỏi phương pháp xử lý lỗi nào hoạt động tốt nhất, ưu và nhược điểm là gì và thậm chí liệu chúng tôi có thể sống mà không có ngoại lệ hay không. Cuộc trò chuyện này đã khơi dậy sự tò mò của tôi muốn khám phá sâu hơn cách xử lý lỗi trong các ngôn ngữ lập trình khác nhau và giờ tôi rất vui được chia sẻ những gì tôi đã học được.


Trong công việc hàng ngày, tôi sử dụng PHP và Golang - hai ngôn ngữ có cách tiếp cận riêng biệt để xử lý lỗi. Trong bài viết này, tôi muốn đưa bạn vào một hành trình mà chúng ta sẽ so sánh cách các ngôn ngữ này xử lý lỗi. Nhưng còn nhiều điều cần khám phá! Chúng ta cũng sẽ khám phá các phương pháp xử lý lỗi thay thế và tìm ra phương pháp nào phù hợp nhất cho các tác vụ khác nhau. Vì vậy, hãy sẵn sàng cho một cuộc khám phá hấp dẫn về cách xử lý lỗi trong thế giới mã hóa.

Phương pháp xử lý lỗi: Đi sâu vào PHP và Golang

Xử lý lỗi trong lập trình là cực kỳ quan trọng. Nhìn lại, cách chúng tôi xử lý lỗi cho thấy nhu cầu và thách thức của nhà phát triển đã thay đổi như thế nào theo thời gian.


Ban đầu, việc trả về mã lỗi chiếm ưu thế. Những giá trị đơn giản, thường dựa trên số nguyên này trả về thành công được chỉ định hoặc các loại lỗi cụ thể. Mặc dù chúng hiệu quả nhưng nhược điểm của chúng là thường khiến mã trở nên lộn xộn và khó đọc hơn. Để giải mã một lỗi, người ta phải liên tục tham khảo lại tài liệu hoặc định nghĩa mã lỗi.


Các ngoại lệ nổi lên như một giải pháp trực quan hơn: thay vì trả về mã, chương trình sẽ đưa ra một ngoại lệ bất cứ khi nào xảy ra lỗi, cho phép nhà phát triển nắm bắt lỗi đó trong một phần được chỉ định của mã. Cách tiếp cận này được chấp nhận vì tính rõ ràng và khả năng xử lý lỗi tập trung.


Ngay sau đó, các lệnh gọi lại lỗi đã xuất hiện, đặc biệt là trong môi trường không đồng bộ. Ý tưởng rất đơn giản: thay vì chờ đợi lỗi, tại sao không chuyển một hàm (gọi lại) để xử lý lỗi đó? Mẫu onError(callback) trở nên phổ biến trong JavaScript, giúp việc xử lý lỗi trở nên chủ động hơn.


Một số ngôn ngữ lập trình đã giới thiệu các chức năng đặc biệt cho phép bạn xử lý các lỗi và ngoại lệ. Ví dụ: trong LUA, có error()pcall() . Chúng cung cấp sự kết hợp giữa mã lỗi truyền thống và cơ chế ngoại lệ.


Song song với các phương pháp xử lý lỗi được mô tả trước đó, một khái niệm như đơn nguyên đã xuất hiện trong các ngôn ngữ lập trình hàm. Chúng bao bọc một giá trị trong ngữ cảnh biểu thị thành công hay thất bại, cho phép xử lý lỗi an toàn và biểu cảm hơn. Ngoài ra, chúng có thể được sử dụng với các mẫu chức năng khác nhau, cho phép xử lý lỗi và xâu chuỗi các hoạt động một cách mạnh mẽ và ngắn gọn.


Nhưng hãy chuyển trọng tâm sang PHP và Golang. PHP có khả năng xử lý lỗi sâu rộng. Trước phiên bản 5.0, không có ngoại lệ nào trong ngôn ngữ lập trình này. Các nhà phát triển đã sử dụng nhiều phương pháp xử lý lỗi khác nhau, chẳng hạn như hàm trigger_error , tạo ra thông báo lỗi/cảnh báo/thông báo ở cấp độ người dùng; hàm set_error_handler , cho phép bạn xác định lệnh gọi lại để xử lý lỗi trong tập lệnh, chủ động trả về 'false' hoặc 'null' do thực thi hàm không thành công, v.v.


Nhiều phương thức trong số này vẫn được sử dụng rộng rãi trong mã PHP. Tuy nhiên, với sự ra đời của các ngoại lệ và cấu trúc ngôn ngữ để xử lý chúng, chúng đã trở nên phổ biến rộng rãi trong các nhà phát triển vì chúng mang lại một số lợi thế so với các phương pháp xử lý lỗi truyền thống, chẳng hạn như thông tin chi tiết hơn về lỗi và nơi xảy ra lỗi, khả năng xử lý lỗi theo cách có cấu trúc và cải thiện khả năng đọc mã phức tạp.


Mặt khác, Golang xử lý mô hình nhiều trả về trong đó các hàm trả về cả kết quả và lỗi, nhấn mạnh việc kiểm tra lỗi rõ ràng trong việc xử lý ngoại lệ ngầm. Những người tạo ra Golang tuân thủ nguyên tắc ngôn ngữ lập trình phải rõ ràng và đơn giản nhất có thể. Mục tiêu chính của thiết kế của nó là cung cấp các cấu trúc ngôn ngữ rõ ràng và hiệu quả để viết mã, đặc biệt là trong các tổ chức lớn như Google. Bằng cách này, các nhà phát triển có thể tập trung vào giải quyết vấn đề mà không lãng phí thời gian tranh cãi về kiểu mã hoặc cố gắng hiểu mã phức tạp và khó hiểu.

Xử lý lỗi trong PHP và Golang: So sánh khả năng đọc

Cách tiếp cận ngoại lệ của PHP

Như đã lưu ý trước đó, PHP có rất nhiều khả năng xử lý lỗi, nhưng ngoại lệ là phương pháp phổ biến nhất hiện nay. Mặc dù cách tiếp cận này trực quan và phản chiếu nhiều ngôn ngữ lập trình khác, nhưng nó có thể dẫn đến các cấu trúc lồng nhau, tình huống khi một ngôn ngữ phải xử lý nhiều nguồn lỗi tiềm ẩn. Việc lồng "thử bắt" này có thể làm cho mã khó đọc hơn, đặc biệt đối với người mới. Hãy phá vỡ nó.

THUẬN LỢI:

  • Ngắn gọn . Việc xử lý ngoại lệ của PHP có thể mang lại mã ngắn gọn, giảm bớt các dòng tổng thể cần thiết. Điều này đặc biệt có lợi khi xử lý các loại lỗi khác nhau trong một đoạn mã. Nó cung cấp một cơ chế xử lý lỗi tập trung.
  • Tính phổ quát. Tương tự như nhiều ngôn ngữ khác, cơ chế ngoại lệ của PHP quen thuộc với nhiều nhà phát triển và giúp dễ dàng chuyển đổi sang PHP từ các nền tảng mã hóa khác. Ngôn ngữ lập trình phổ biến nhất hiện nay đều có cách xử lý lỗi này.

NHƯỢC ĐIỂM:

  • Sự gián đoạn dòng chảy. Thiếu sót chính là khả năng che khuất luồng logic của mã. Khi các ngoại lệ lan truyền, việc truy tìm lại nguồn lỗi ban đầu có thể gặp khó khăn, điều này làm phức tạp việc gỡ lỗi.
  • Quá phụ thuộc. Dựa quá nhiều vào các ngoại lệ cũng có thể dẫn đến việc sử dụng quá mức, trong đó các lỗi nhỏ được coi là ngoại lệ, từ đó làm phức tạp mã một cách không cần thiết.

Xử lý lỗi rõ ràng của Golang

Golang có một cách tiếp cận khác biệt. Thay vì có ngoại lệ, các hàm trả về giá trị lỗi cùng với giá trị trả về thông thường của chúng. Khi đó trách nhiệm của nhà phát triển là kiểm tra và xử lý lỗi này. Mặc dù điều này có thể làm cho mã Go dài hơn nhưng nó mang lại sự hiểu biết rõ ràng về thời điểm và vị trí có thể xảy ra lỗi.


THUẬN LỢI:

  • Kiểm soát luồng đơn giản. Vì Go không sử dụng ngoại lệ để xử lý lỗi nên không cần khối “thử bắt” — nó làm giảm độ phức tạp của luồng điều khiển.
  • Tính linh hoạt . Cách tiếp cận của Golang cho phép các nhà phát triển quyết định cách xử lý từng lỗi trong từng trường hợp cụ thể, cho dù đó là bằng cách phát tán, ghi nhật ký hay thực hiện các biện pháp khắc phục. Kiểm soát này có thể dẫn đến các ứng dụng mạnh mẽ hơn.

NHƯỢC ĐIỂM:

  • Độ dài. Một trong những lời chỉ trích phổ biến nhất là việc xử lý lỗi của Go có thể dẫn đến mã dài dòng. Các hàm có thể bị lỗi phải trả về một giá trị lỗi bổ sung và việc xử lý các lỗi này thường có thể dẫn đến bản tóm tắt kiểm tra lỗi lặp đi lặp lại.
  • Tiềm năng giám sát. Vì việc xử lý lỗi rất rõ ràng nên có thể có rủi ro là nhà phát triển có thể quên hoặc cố tình chọn không kiểm tra lỗi.
  • Thiếu bối cảnh . Mặc dù loại lỗi tiêu chuẩn của Go rất đơn giản và nhất quán nhưng nó thường thiếu thông tin theo ngữ cảnh về vị trí và lý do xảy ra lỗi. Mặc dù có các gói và mẫu để thêm nhiều ngữ cảnh hơn nhưng nó không được tích hợp như một số nhà phát triển mong muốn.

Sự khác biệt về hiệu suất và mức tiêu thụ tài nguyên

Cuộc tranh luận giữa PHP và Golang thường liên quan đến nhiều lĩnh vực lập trình khác nhau, nhưng một trong những lĩnh vực tranh chấp quan trọng nhất là sự khác biệt về hiệu suất và mức tiêu thụ tài nguyên, đặc biệt là khi xử lý lỗi.


Trong trường hợp PHP, các ngoại lệ cho phép tạo dấu vết ngăn xếp, giúp theo dõi chuỗi lệnh gọi dẫn đến lỗi. Dấu vết này cung cấp thông tin có giá trị để gỡ lỗi. Tuy nhiên, việc tạo ra một dấu vết như vậy, đặc biệt là trong các ứng dụng phức tạp, đòi hỏi tài nguyên tính toán và bộ nhớ. Do đó, khi các ngoại lệ được đưa ra thường xuyên, chúng có thể làm chậm ứng dụng và tăng mức sử dụng tài nguyên của ứng dụng.


Mặt khác, phương pháp của Golang tránh được chi phí tạo dấu vết ngăn xếp ngoại lệ. Thay vào đó, các hàm trả về các giá trị lỗi phải được lập trình viên kiểm tra rõ ràng. Cách tiếp cận này mang lại hiệu suất tốt hơn và giảm mức tiêu thụ tài nguyên. Tuy nhiên, nó chuyển trách nhiệm trực tiếp lên vai nhà phát triển, điều này cũng tiêu tốn nhiều tài nguyên theo một cách nào đó.


Quyết định giữa việc sử dụng phương pháp dựa trên ngoại lệ của PHP hay cách xử lý lỗi rõ ràng của Golang không chỉ đơn thuần là về hiệu suất và tài nguyên mà còn là về sự đánh đổi. Các ngoại lệ cung cấp rất nhiều thông tin gỡ lỗi, nhưng chúng phải trả giá; Ngược lại, cách tiếp cận của Golang thân thiện với tài nguyên nhưng đòi hỏi sự siêng năng trong quản lý lỗi.

Kết luận: Có thể và cần thiết để sống không có ngoại lệ?

PHP, ra đời từ nhu cầu phát triển web, ưu tiên sự đơn giản và lưu trữ chia sẻ. Việc xử lý lỗi của nó làm cho nó thân thiện với nhà phát triển đối với các ứng dụng web. Mặt khác, Golang, được tạo ra bởi gã khổng lồ phần mềm Google, được thiết kế để lập trình hệ thống hiện đại. Nó nhấn mạnh việc xử lý lỗi rõ ràng bằng cách sử dụng nhiều giá trị trả về: mô hình này thúc đẩy luồng mã rõ ràng hơn và coi lỗi là giá trị thông thường, mang lại khả năng kiểm soát chính xác hơn.


Nguồn gốc và mục tiêu khác nhau đã định hình nên triết lý xử lý lỗi của họ. PHP nhằm mục đích áp dụng rộng rãi trong số các nhà phát triển web, đánh giá cao khả năng truy cập và sự khoan hồng. Ngược lại, Golang tìm kiếm hiệu suất, sự rõ ràng và mạnh mẽ, lý tưởng cho các hệ thống có thể mở rộng và bảo trì.


Cách tiếp cận của họ chắc chắn sẽ gây ra tranh luận về sự cần thiết của các ngoại lệ.


Mặc dù mã hóa không có ngoại lệ có vẻ khó khăn nhưng nó thúc đẩy các nhà phát triển hướng tới mã minh bạch hơn, dễ đoán hơn. Tuy nhiên, nó có thể không phù hợp trên toàn cầu và nó nhấn mạnh sự cần thiết phải hiểu ý định và ứng dụng ngôn ngữ cụ thể.


Đối với tôi, bất chấp những nhược điểm có thể xảy ra của các trường hợp ngoại lệ, tôi là một trong những nhà phát triển thích sử dụng chúng trong công việc của mình hơn, nếu điều này có thể. Cách tiếp cận Golang khiến tôi cảm thấy không thoải mái hơn nhưng nó cũng buộc tôi phải suy nghĩ nhiều hơn về những gì tôi đang làm và những gì tôi muốn đạt được. Bạn thích sử dụng phương pháp nào hơn? Tôi sẽ rất vui nếu bạn chia sẻ thông tin này trong phần bình luận!