Cách viết clean code

Xin chào,
Em có một số câu hỏi về cách viết code, mong được các bác tư vấn và chia sẻ.

:one: Về cách đặt tên member của class như biến, field, properties, … các bác thường đặt tên properties của class có kèm theo tên của class đó luôn không?
VD : Tạo class sản phẩm:

Cách 1:

class Product {
private int productId;
private String productName;
private int productPrice;
}

const product = {
      productId : 1,
      productName : "Laptop",
      productPrice : 150,
   }

Cách 2:

class Product {
private int id;
private String name;
private int price;
}

const product = {
      id : 1,
      name : "Laptop",
      price : 150,
   }

:two: Khi viết biểu thức logic, đặt biến cần so sánh trước, hay giá trị đặt trước?

VD:
Cách 1: em thường dùng kiểu này

if( username != "" ) {
 console.log("Xin mời nhập tiếp mật khẩu")
} else {
   console.log("Không được bỏ trống")
}

Cách 2: Em thấy một số dev code C, C++ thường viết kiểu này

   if( "" != username ) {
     console.log("Xin mời nhập tiếp mật khẩu")
    } else {
       console.log("Không được bỏ trống")
    }

:three: Nếu tên biến chứa từ tiếng Anh dài : notifications, Incomprehensibilities, uncopyrightable, … thì nên viết đầy đủ hay viết tắt, viết tắt như thế nào?

public void markAllNotificationAsRead(int userId) { 
    // some code
}

hay

 public void markAllNotifAsRead(int userId) { 
    // some code
}

hay markNotifsAsRead

:four: if else chỉ 1 dòng code thì có nên dùng cặp ngoặc nhọn không?

 if( "" != username ) {
    console.log("Xin mời nhập tiếp mật khẩu")
 } else {
    console.log("Không được bỏ trống")
 }

hay

   if( "" != username ) 
      console.log("Xin mời nhập tiếp mật khẩu")
   else 
      console.log("Không được bỏ trống")
2 Likes

Theo ý cá nhân mình:

  1. Mình chọn cách 2, không cần kèm theo tên lớp, vì cách 1 dài dòng.
    Vẫn ổn và đủ dễ hiểu khi không có tên lớp.
    owner.shop.productList[0].name
    
    Còn thêm tên lớp thì…
    owner.ownerShop.shopProductList[0].productName
    
  2. Nói thật là nhiều khi viết mình toàn quen tay viết theo cách 1, nhưng khuyến khích cách 2, vì điều này tránh được vấn đề ===, trong một số ngôn ngữ. Thường thì nên dùng cách 2 khi so sánh giữa 1 biến và 1 hằng.
  3. Tùy theo từ đó có dạng thông dụng của viết tắt hay không, như ví dụ của bạn, khi dùng Noti thì hiểu ngay là Notification. Nhưng nếu định viết 1 thư viện hay một mã nguồn mở nào đó thì nên viết đầy đủ từ ngữ để người dùng dễ hiểu.
  4. Nên dùng cặp ngoặc nhọn. Dùng chả mất gì nhiều, nhưng nếu không dùng, tự nhiên đoạn mã bị lỗi lại chả biết từ đâu ra. Mình đã từng dính vấn đề này. Và cũng lưu ý luôn, trong Javascript, có thể viết 1 câu lệnh mà không cần dùng kí tự chấm phẩy (;) để kết thúc, nhưng nếu đã viết thế thì đừng bao giờ chuyển toàn bộ mã thành 1 dòng (minify). Vấn đề cũng sẽ xảy ra khi thiếu một số cặp ngoặc nhọn.

Chốt:
:one: 2
:two: 2
:three: 1
:four: 1

8 Likes

:one: Mình chọn cách 2 vì mình lười gõ cách 1 lắm.

:two: Mình không thích viết giống bạn, mình đưa vào hàm kiểm tra boolean. Sai đâu sửa đó, hạn chế những lỗi không đáng có.

function isValidUsername(username) {
    return username != "";
}

// ...

if (isValidUsername(username)) {
    // blah blah
} else {
    // bloh bloh
}

:three: Mình lựa chọn viết tắt những từ quá phổ biến, ví dụ notification -> noti, internationalization -> i18n, và luôn hạn chế những từ vừa dài vừa phức tạp, gây ức chế cho người khác (như với những người ghét tiếng Anh như mình). Còn IDE/ text editor đều hỗ trợ auto complete, bạn chỉ cần gõ 1 lần và sẽ có gợi ý cho bạn những lần sau, khỏi care :kissing:

:four: Rất nên dùng cặp ngoặc nhọn, đề phòng khi bạn muốn thêm logic gì mới. Còn dev Python như mình thì thấy không có cảm xúc gì.

10 Likes

Cho mình hỏi đoạn này, function 1 dòng như thế này có ổn không nhỉ? sếp chửi mình quá trời, mặc dù rõ ràng dùng lại ở nhiều chỗ ý

5 Likes

Function quá dài mới đáng sợ chứ ngắn thì càng tốt mà :stuck_out_tongue:

7 Likes

Sếp mình chửi quá trời, function dài thì bờm đầu chắc rồi, mà cứ lần nào function 1 dòng là y rằng mình thành trò cười, bực thiệt sự.

5 Likes

Trong context này thì chỉ check username có khác rỗng hay không, nhưng trong thực tế thì check username phải thoả mãn 1 pattern nào đó hay không, lúc đó code dài hơn 1 dòng :stuck_out_tongue:

Đôi khi bạn cần thay đổi cách mổ xẻ logic, sắp xếp các hàm chứ không phải là độ dài của hàm.

7 Likes

Ừa trường hợp khác thì nói mà chi. Mình focus trường hợp như này thôi, trường hợp mà thật sự nó chỉ có 1 dòng

4 Likes

Không biết ý sếp của bạn như thế nào nhưng mình đoán là khi viết quá nhiều hàm ngắn thì tổng thể code sẽ rất tủn mủn, không tận dụng được tính reusable. Tất nhiên không phải lúc nào cũng viết hàm ngắn (vì có khi nó không đáng viết), nhưng nếu không viết hàm nào thì code rất khó đọc.

7 Likes

Anh có thể giải thích rõ hơn giúp em được không, em suy nghĩ mãi mà vẫn không hiểu 2 ý này.

if( username != "" ) {
 // blah blah
} else {
   // blah blah
}

Em thấy viết kiểu này đọc từ trái sang phải thuận miệng hơn :sweat_smile: “Nếu username khác rỗng thì,…” tập trung nhấn mạnh vào username còn “” chỉ là phụ. Tại sao lại viết ngược lại vậy anh @SITUVN.gcd ?

if( "" != username ) {
     // blah blah
    } else {
       // blah blah
    }
1 Like

Cốt tránh lỗi = và == thôi.

6 Likes

Function 1 dòng như vậy ổn mà cậu? :smile:
Có một số lý do tốt cho function đó:

  • Code của cậu dễ đọc hơn (ở đoạn gọi function).
  • Cậu có thể tái sử dụng function đó.

Tất nhiên, cậu chỉ nên sử dụng function 1 dòng kiểu này thay cho điều kiện trong 1 số TH:

  • Điều kiện đó lặp đi lặp lại trong source code.
    Khi đó, tách function ra là quyết định hợp lý.
  • Điều kiện ở dòng if tương đối phức tạp và khó hiểu.
    Việc tách function với 1 tên dễ hiểu sẽ giúp code readability của cậu tăng lên rất nhiều.

Cậu không nhất thiết phải luôn luôn tách function như vậy, đặc biệt khi code của cậu đủ dễ hiểu rồi. Trong code ví dụ của cậu, điều kiện này hơi khó hiểu (kiểm tra username có rỗng không nghĩa là gì?), nên tách hàm mới với tên dễ hiểu là quyết định hợp lý.

Hope it helps!

9 Likes

Cậu đúng đó, viết cách trên dễ đọc hơn một chút.
Cách dưới được gọi là Yoda notation, thường dùng trong C/C++ để tránh bug này:

// This will be always true
if (value = 1) { // assignment
  ...
}
// Compiler will scream in case of using Yoda notation
if (1 = value) { // cannot assign
  ...
}

Nếu cậu không code ngôn ngữ coi 0 = false, !0 = true như C/Cpp, cậu không cần dùng Yoda notation.

Hope it helps!

9 Likes
  1. Ai rảnh đâu mà viết lại tên class cho từng field :V :V
  2. Biến trước. Ai đặt giá trị trước là ko biết/ko thèm bật/đọc warnings, thói hư tật xấu :V
  3. Nên viết đủ, chỉ tránh đặt tên có nghĩa phủ định là được. Vd incomprehensibilities uncopyrightable tìm từ khác mà xài, tự dưng thêm cái phủ định vô làm gì khó đọc lắm :V
  4. Nên dùng. Có else là nên dùng ngoặc nhọn :V Trừ phi if ko có else và 1 dòng thì có thể ko cần.
10 Likes

Khi code javascript thì các bác có thường sử dụng trailing commas như này không ạ?

Có chứ cậu.
Làm thế cậu sẽ:

  • Thêm 1 dòng mới dễ dàng hơn, khi cậu không phải thêm dấu ‘,’ vào cuối dòng trước.
  • Pull request diff sẽ gọn hơn, khi cậu không phải sửa dòng trước.

Hope it helps!

10 Likes

Project thực tế lúc đi làm người ta code arrow function trong javascript thường dùng kiểu nào vậy ạ?


Kiểu này

const func = () => { 
 // 
 }

hay kiểu này

const func = _ => {
//
}

2 cách mà bạn nói có khác biệt.

Hàm không chứa tham số có tên.

Hàm chứa 1 tham số có tên là _.

Thích dùng cách nào thì dùng.
Thế này cũng được:

const func = $=> { 
 // 
 }
const func = ă=> { 
 // 
 }
a = [1,2,3,4];
console.log(a.reduce((_,$)=>_+=$));
5 Likes

Thôi toang rồi :cold_face:, đọc phát giật hết cả mình, trước giờ em toàn dùng _ cho function không có tham số, lúc trước em nhớ có đọc trên một blog nào đó bảo const func = () => { }const func = _ => { } giống nhau @@ ai ngờ đọc nhầm blog lậu, bản chất nó cũng là một tham số bình thường chỉ là không dùng ký tự alphabet

const func = _ => {
    return _ + 1;
}
console.log(func(12)) //13

Nhưng dùng sao cũng cảm ơn anh nhiều, anh không nói em cũng không để ý.

3 Likes

Nó giống như là 1 tips để mình có thể giả vờ bỏ qua nó thôi :stuck_out_tongue:

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?