+15

JAVA BEST PRACTICES - lời khuyên từ các chuyên gia hàng đầu

Trước khi bắt đầu bài viết lần này, 15 JAVA CODING BEST PRACTICES mà mình nhắc tới trong bài viết trước cũng đều là những best practices hay nhất được các chuyên gia nằm lòng, tuy nhiên mình sẽ không nhắc lại trong bài viết lần này. Nào giờ cùng mình tìm hiểu xem các lời khuyên giá trị lần này sẽ là gì nhé.

1. Sử dụng quy ước đặt tên rõ ràng và trực quan

Điều đầu tiên trước tiên. Trước khi đi sâu vào dự án, bạn nên bắt đầu bằng cách đặt quy ước đặt tên thích hợp cho mọi lớp, giao diện, phương thức và biến.

Hãy nhớ rằng các dự án phát triển phần mềm nâng cao hơn có thể có sự tham gia của nhiều nhóm nhà phát triển. Do đó, điều quan trọng là phải thống nhất và tuân theo một quy ước đặt tên để duy trì tính đồng nhất và tránh nhầm lẫn. Dưới đây là một số mẹo để thiết lập các sơ đồ đặt tên rõ ràng và dễ hiểu:

  • (Classes) Lớp – Tên chỉ nên bao gồm danh từ và bắt đầu bằng chữ in hoa,
  • (Packages) Gói – Tên phải được viết hoàn toàn bằng chữ thường,
  • (Interfaces) Giao diện – Tên phải theo Camel Case,
  • (Variables) Biến – Tên có thể tuân theo quy ước viết hoa hỗn hợp,
  • (Methods) Phương pháp – Tên nên bao gồm các động từ với mỗi từ được viết hoa

Bạn có thể nghĩ rằng những khuyến nghị này khá không đáng kể. Tuy nhiên, trên thực tế, sau nhiều lần hợp nhất và bổ sung thêm các chức năng mới, sự tiện lợi sẽ được thể hiện rõ ràng. Xét cho cùng, một sơ đồ đặt tên phù hợp thậm chí còn quan trọng hơn những code comments xuất sắc. Điều này là do các lập trình viên Java thường bỏ qua phần công việc đó và quên cập nhật nhận xét khi thay đổi code, dẫn đến nhầm lẫn thêm.

2. Nhớ comment

Vì chúng ta đã nói đến vấn đề này ở trên nên bây giờ hãy chuyển sang một trong những phần thường bị bỏ qua nhất trong quy trình phát triển phần mềm – comment.

Làm sao người đọc codebase có thể hiểu được nó? Đầu tiên, họ cần biết code đó “phải làm gì”. Đó là nơi các comment xuất hiện.

Comment là một phương pháp đặt các mô tả mà con người có thể đọc được bên trong code để giải thích chức năng của một phần cụ thể của chương trình. Vì code của bạn sẽ được đọc bởi các thành viên khác trong nhóm có kiến ​​thức khác nhau về Java nên các nhận xét phải cung cấp cho họ cái nhìn tổng quan rõ ràng về các phương pháp đã chọn và cung cấp thông tin bổ sung không dễ hiểu nếu chỉ nhìn vào code. Những comment tốt có thể đơn giản hóa đáng kể việc bảo trì code Java, cũng như giúp chẩn đoán và sửa lỗi nhanh hơn nhiều.

Đây là một ví dụ về một comment thông thường trong code Java:

image.png

Thông qua comment, bạn sẽ có thời gian đánh giá mã dễ dàng hơn nhiều. Và ngoài ra, nếu bạn phải quay lại một dự án trong tương lai và bạn không nhớ bất cứ điều gì về nó, thì đoạn mã đó rất có giá trị, vì nó giúp nắm bắt chủ đề nhanh hơn và nó không khiến bạn tức điên với bản thân hay người khác vì sự phức tạp của một đoạn mã tưởng chừng như đơn giản.

3. Đảm bảo các commit được mô tả rõ ràng

Mã và các biến không phải là những yếu tố duy nhất của quá trình phát triển phần mềm cần được mô tả chính xác. Quy tắc tương tự cũng áp dụng cho các commit.

Bên cạnh nội dung chính của code, một commit còn lưu trữ nhiều thông tin bổ sung khác như tác giả, thời gian và message. Nó cũng sẽ là những thông tin hết sức có ích cho team của bạn,.

Một ví dụ về mô tả commit git là:

git commit -m “Cải thiện hiệu suất khi lấy dữ liệu từ bảng transaction”

Có một số cách tốt nhất liên quan đến việc viết một thông điệp commit tốt mà mọi lập trình viên Java nên làm quen:

  • Viết hoa chữ cái đầu tiên của mô tả commit.
  • Giữ nó ngắn gọn và đi thẳng vào vấn đề. Thông thường nên giữ một mô tả commit dưới 50 ký tự.
  • Trong mô tả commit của bạn, hãy tập trung vào những gì đã thay đổi hơn là lý do tại sao bạn thay đổi nó.

4. Dừng ngay việc Hardcoding

Nếu bạn là một lập trình viên, rất có thể bạn đã mắc phải lỗi hardcoding. Chắc các bạn cũng biết mình đang nói tới điều gì - đó là khi bạn đặt các giá trị bằng chữ vào code của mình thay vì sử dụng các biến. Ví dụ: giả sử bạn đang viết một chương trình để tính tuổi của ai đó. Nếu bạn mã hóa năm hiện tại vào chương trình thì mỗi khi ai đó chạy chương trình, họ sẽ có cùng độ tuổi. Nhưng nếu bạn sử dụng một biến cho năm hiện tại thì tuổi sẽ luôn được tính chính xác.

Việc mã hóa cứng các giá trị vào code của bạn thường được coi là cách làm không tốt vì một số lý do. Trước hết, nó có thể làm cho mã của bạn khó đọc và khó hiểu hơn. Thứ hai, nó có thể làm cho mã của bạn ít được sử dụng lại hơn — nếu cần sử dụng cùng một đoạn mã với các giá trị khác nhau, bạn sẽ phải vào và thay đổi các giá trị được mã hóa cứng theo cách thủ công. Và cuối cùng, điều này có thể dẫn đến lỗi nếu các giá trị bạn mã hóa cứng vào code của mình tình cờ thay đổi (ví dụ: nếu năm hiện tại thay đổi).

Vì vậy, lần tới khi bạn muốn mã hóa cứng thứ gì đó vào code của mình, hãy suy nghĩ kỹ! Thay vào đó, tốt hơn hết bạn nên sử dụng các biến.

5. Tuân theo nguyên tắc SOLID

image.png

Về cơ bản, đây là một số khái niệm thiết kế hướng đối tượng liên quan đến phát triển phần mềm mà mọi lập trình viên Java trong chúng ta đều cần phải biết . Nguyên tắc SOLID là một bộ nguyên tắc lập trình hướng đối tượng được đề xuất bởi Robert C. Martin để giúp phát triển phần mềm linh hoạt, dễ bảo trì và mở rộng. Đã có rất nhiều bài viết giải thích và hướng dẫn về những nguyên tắc này, các bạn có thể tham khảo chúng thông qua Google.

6. Nguyên tắc DRY và KISS

DRYKISS là hai nguyên tắc quan trọng trong lập trình, được thiết lập để hướng dẫn, giúp tăng tính hiệu quả và dễ dàng trong việc bảo trì của mã nguồn.

DRY - Don't Repeat Yourself (Không Lặp Lại):

  • Ý nghĩa: Nguyên tắc này khuyến khích việc tránh lặp lại mã nguồn. Thay vì sao chép và dán cùng một đoạn code vào nhiều nơi, hãy tạo ra một phần hoặc hàm để thực hiện công việc đó và sau đó sử dụng nó ở nhiều địa điểm cần thiết.

  • Tác dụng:

    • Giảm nguy cơ xuất hiện lỗi, vì chỉ cần sửa một nơi khi có thay đổi.
    • Tăng tính duy trì và bảo trì mã nguồn.
    • Cải thiện độ đọc hiểu của code, vì logic chỉ cần hiểu ở một nơi.

KISS - Keep It Simple, Stupid (Giữ Nó Đơn Giản, Ngốc Nghếch):

  • Ý nghĩa: Nguyên tắc này khuyến khích giữ cho mã nguồn và thiết kế của chương trình đơn giản và dễ hiểu nhất có thể. Đừng thêm vào những phức tạp không cần thiết.

  • Tác dụng:

    • Giảm độ phức tạp, dễ dàng hiểu và bảo trì.
    • Giảm nguy cơ xuất hiện lỗi do sự phức tạp không cần thiết.
    • Tăng tính linh hoạt và mở rộng của mã nguồn.

    Cả hai nguyên tắc này thường được coi là nguyên tắc cơ bản để viết mã nguồn hiệu quả và dễ bảo trì. Tuy nhiên, cũng cần lưu ý rằng áp dụng chúng không đồng nghĩa với việc loại bỏ mọi sự phức tạp hoặc lặp lại mọi nơi mà không cần thiết. Điều quan trọng là tìm ra sự cân bằng phù hợp giữa đơn giản và linh hoạt, giữa tránh lặp lại và giữ được sự rõ ràng và dễ hiểu.

7. Xử lý exception đúng cách

Xử lý exception một cách đúng đắn là một phần quan trọng của việc phát triển ứng dụng, và nó mang lại nhiều lợi ích quan trọng cho quá trình phát triển và bảo trì mã nguồn

  • Thông báo rõ ràng cho người phát triển và người sử dụng: Khi xảy ra lỗi, việc xử lý exception đúng cách giúp cung cấp thông báo rõ ràng về nguyên nhân của lỗi, giúp người phát triển và người sử dụng dễ dàng hiểu và xử lý.

  • Gỡ lỗi dễ dàng: Khi exception được xử lý chính xác, thông tin chi tiết về lỗi thường được ghi vào logs. Điều này giúp người phát triển dễ dàng theo dõi, gỡ lỗi, và sửa lỗi khi cần thiết.

  • Tăng khả năng duy trì: Xử lý exception đúng cách giúp giảm lượng mã nguồn được thay đổi khi xảy ra lỗi. Việc này giúp dễ dàng duy trì mã nguồn, vì mỗi lần sửa lỗi không làm ảnh hưởng đến toàn bộ hệ thống.

  • Đảm bảo tính ổn định của hệ thống: Việc xử lý exception đúng cách giúp đảm bảo tính ổn định của hệ thống. Các exception được kiểm soát và xử lý giúp tránh tình trạng chương trình "crash" đột ngột và người dùng nhận được thông báo lỗi thay vì gặp lỗi không kiểm soát.

  • Bảo vệ dữ liệu quan trọng: Khi xử lý exception một cách chính xác, có thể thực hiện các biện pháp như hồi phục từ trạng thái lỗi hoặc bảo vệ dữ liệu quan trọng khỏi bị mất mát.

  • Cải thiện trải nghiệm người dùng: Thông báo lỗi và xử lý exception một cách chính xác giúp cải thiện trải nghiệm người dùng. Người dùng sẽ nhận được thông báo lỗi rõ ràng và được hướng dẫn về cách xử lý vấn đề, thay vì gặp các thông báo lỗi không thông tin.

  • Duy trì mã nguồn dễ dàng: Việc xử lý exception một cách đúng đắn giúp duy trì mã nguồn dễ dàng hơn bằng cách giảm thiểu sự phức tạp và mối quan hệ giữa các thành phần của hệ thống.

Mình sẽ hướng dẫn cách để xử lý exception đúng cách và hiệu quả nhất trong một bài viết gần nhất nhé😘♥️. Đây nhé các bạn - Xử lý exception đúng cách trong Java

8. Quá nhiều tham số phương thức (hoặc hàm tạo - constructor) hoặc phương thức quá dài

Quá nhiều tham số (và hầu hết chúng có cùng kiểu dữ liệu) trong một phương thức hoặc hàm tạo sẽ gây ra nhiều nhầm lẫn cho người gọi và làm cho nó trở nên rất phức tạp.

Vậy bao nhiêu là quá nhiều? Không có câu trả lời chính xác nhưng nếu chịu khó suy nghĩ, chắc chắn bạn sẽ tìm ra câu trả lời. Theo mình, tầm 3 hoặc 4 là giới hạn. Nếu có quá nhiều tham số, thì phương thức của bạn đang thực hiện quá nhiều thứ (vi phạm single responsibility rule) hoặc có phạm vi để đóng gói các tham số đó vào một hoặc hai lớp. Đừng cố thêm chúng vào Map<String, Object> , đây cũng là một cách làm tồi.

image.png

Cố gắng tránh có quá nhiều tham số ngay từ đầu trong luồng, chẳng hạn như trong Bộ điều khiển, hãy sử dụng các trình phân tích cú pháp nội dung có sẵn trong framework của bạn để chuyển đổi nội dung yêu cầu thành POJO (Plain Old Java Object - hiểu đơn giản là một đối tượng do bạn định nghĩa).

Làm cách nào để xử lý quá nhiều tham số trong hàm tạo? Gọi 10 setters thay vì truyền 10 tham số cũng tệ không kém. Builder Pattern có thể là thứ mà bạn đang cần.

9. Tránh sử dụng biến toàn cục

Ưu tiên sử dụng biến cục bộ và tránh sử dụng biến toàn cục khi không cần thiết để tránh xung đột và làm tăng độ phức tạp của chương trình. Việc tránh sử dụng biến toàn cục (global variables) là một nguyên tắc quan trọng trong lập trình vì nó giúp kiểm soát phạm vi của biến và giảm thiểu rủi ro xung đột và phức tạp trong quá trình phát triển và bảo trì mã nguồn. Dưới đây là một số lợi ích và ví dụ minh họa:

  • Nguyên tắc Đóng gói (Encapsulation): Biến cục bộ giúp bảo vệ dữ liệu bằng cách giới hạn phạm vi của biến chỉ trong phạm vi của phương thức hoặc lớp mà nó được khai báo.
  • Tránh xung đột (Avoiding Conflicts): Việc sử dụng biến toàn cục tăng rủi ro xung đột giữa các phần của chương trình, đặc biệt là trong các dự án lớn có nhiều người phát triển.
  • Dễ bảo trì (Easier Maintenance): Biến cục bộ thường dễ bảo trì hơn do nó được sử dụng trong phạm vi cụ thể và không ảnh hưởng đến các phần khác của chương trình.
  • Tăng tính tái sử dụng: Việc sử dụng biến cục bộ thường làm cho mã nguồn linh hoạt hơn và có thể tái sử dụng trong các phương pháp và lớp khác nhau mà không làm ảnh hưởng đến các biến khác.

Sử dụng biến cục bộ

image.png

Sử dụng biến toàn cục

image.png

Trong ví dụ này, globalVar là biến toàn cục, và mọi phương thức trong lớp có thể truy cập và sửa đổi giá trị của nó. Điều này có thể tạo ra rủi ro xung đột và làm tăng độ phức tạp của mã nguồn.

Việc sử dụng biến toàn cục nên được tránh khi có thể, và thay vào đó, ưu tiên sử dụng biến cục bộ để giữ cho mã nguồn có tính đóng gói, dễ bảo trì và ít xung đột hơn.

10. Các best practices tổng hợp giúp bạn trở nên đẳng cấp hơn trên con đường trở thành Master

  • Phong cách đặt dấu ngoặc và khoảng trắng:

    • Sử dụng khoảng trắng để làm cho mã nguồn dễ đọc hơn.
    • Đặt dấu ngoặc đóng trên dòng mới.
    • Giữ một số khoảng trắng giữa các toán tử và dấu ngoặc để tăng độ đọc hiểu.
  • Đọc và viết mã nguồn dễ hiểu:

    • Chú thích mã nguồn một cách rõ ràng và chính xác.
    • Tạo ra mã nguồn có cấu trúc, có tổ chức, giảm thiểu độ phức tạp.
  • Quản lý bộ nhớ hiệu quả:

    • Tránh tạo ra các tham chiếu không cần thiết để giảm bớt áp lực lên bộ nhớ.
    • Sử dụng Garbage Collection một cách hiệu quả.
  • Sử dụng các thư viện tiêu chuẩn:

    • Sử dụng các thư viện Java chuẩn để giảm độ phức tạp và tăng độ ổn định của ứng dụng.
  • Kiểm tra Null (Null Checks) cẩn thận:

    • Tránh sử dụng quá nhiều kiểm tra null bằng cách sử dụng Optional (trong Java 8 trở lên) hoặc sử dụng thiết kế an toàn với null.
  • Thực hiện Logging đúng cách

    • Ghi log thông tin một cách chính xác để theo dõi hành vi của ứng dụng và giúp gỡ lỗi (điều này khá là cần thiết đó).

Nhớ rằng, những best practices này không phải là quy tắc tuyệt đối và có thể thay đổi tùy thuộc vào ngữ cảnh cụ thể của dự án. Điều quan trọng là hiểu rõ mục đích và áp dụng chúng một cách linh hoạt. Chúc các bạn may mắn 👋😘


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí