12/08/2018, 13:42

Để phòng tránh code "thối", hãy đảm bảo 7 quy tắc sau

1. Nguồn クソコードにならない為に、これだけは守って欲しい7つのこと 2. Động cơ Một buổi sáng đẹp trời lên công ty, mở anh chàng Thunderbird ra, lục trong thùng rác thấy có mail từ Qiita. Anh chàng này vẫn đều đặn spam mình tuy nhiên thỉnh thoảng cũng có những bài viết rất hay và giúp ích nhiều trong công việc, đọc lướt ...

1. Nguồn

クソコードにならない為に、これだけは守って欲しい7つのこと

2. Động cơ

Một buổi sáng đẹp trời lên công ty, mở anh chàng Thunderbird ra, lục trong thùng rác thấy có mail từ Qiita. Anh chàng này vẫn đều đặn spam mình tuy nhiên thỉnh thoảng cũng có những bài viết rất hay và giúp ích nhiều trong công việc, đọc lướt qua thấy có chủ đề này hay và hữu ích quá liền đọc ngay và chia sẻ trên Viblo cho cả nhà Framgia ta cùng đọc.

3. Bài viết

3.1 Lời tựa

Bài viết lần này của tôi muốn hướng tới những lỗi mà kể cả các dev có nhiều kinh nghiệm vẫn có thể mắc phải, chính vì thế những thứ đương nhiên phải tránh như "không viết code trùng lặp" sẽ được bỏ qua.

3.2 Kế thừa là mối quan hệ is-a (là - một)

Đừng có coi thường bằng những câu kiểu "À, kế thừa chứ gì. Biết rồi biết rồi".

Vừa phải thôi!!!

Hầu hết các dev đều biết mối quan hệ is-a là gì, thực ra cũng phải thôi vì đây chính là khái niệm luôn xuất hiện trong các cuốn sách mang tư tưởng object.

Tuy nhiên với kinh nghiệm của tôi thì có rất nhiều người bỏ qua điều cốt lõi của khái niệm này.

[Một cảnh dễ thấy ở công ty]

Anh A:「Class này và class kia có method giống hệt nhau này」

Anh B:「Ừ đúng rồi. Vậy tạo một class cha để tóm gọn code lại, tránh để trùng lặp code nhé.」

Tôi:「Đừng có nghịch ngu!!!」

Thực ra điểm xuất phát cũng không phải quá tệ, tuy nhiên nếu 2 đồng nghiệp của tôi quên mất khái niệm quan trọng nhất của kế thừa is-a thì không thể tha thứ được.

is-a không phải là từ dành cho những người còn non kinh nghiệm, đây là khái niệm phải được sử dụng khi implement.

Nếu bạn phớt lờ điều trên thì chắc chắn sẽ tạo ra các class rất vô lý.

Nói một cách rõ ràng hơn, is-a là một khái niệm quá trừu tượng, cho nên khi bắt tay vào làm sẽ rất khó để áp dụng đúng được, hay nói chính xác hơn tuỳ theo mỗi người sẽ có một kiểu khác nhau..

Chính vì thế tôi sẽ giới thiệu cho các bạn một cách cụ thể để đánh giá việc này, rất mong sẽ giúp ích cho mọi người.

Tóm lại là

"Những property hay method trong class cha, tất cả có đang ở trạng thái sử dụng được hay không?"

Hãy chú ý kỹ, không phải là trạng thái đang sử dụng mà là CÓ THỂ SỬ DỤNG được hay không.

Tất nhiên sẽ có những lúc bạn không sử dụng chúng, nhưng hãy phán đoán dựa vào trạng thái có thể sử dụng được khi mình muốn hay không.

Nếu điều trên là đúng thì mới có thể nói là mối quan hệ is-a đúng nghĩa.

Vì vậy đầu tiên nếu bạn cần tạo class con, hãy kiểm tra xem class cha có đang ở trạng thái này hay không.

3.3 Làm rõ input và output của method

Tóm lại, hãy tuân thủ điều này!

Nếu không thể tuân thủ, hãy viết test đi! (do không tuân thủ không được)

Trên đời có quá nhiều method mà input và output không rõ ràng. Hơn nữa khi phải đi sửa những method này, bạn sẽ cảm thấy vô cùng nhức nhối, chính vì thế hãy tuân thủ nó.

Ngoài ra nó còn làm bạn không thể viết test nữa. Đau đớn quá

A a a a a a !!!

Hãy làm sao để tạo ra những method khi người khác hỏi bạn input và output là gì thì có thể trả lời được ngay.

Cụ thể hơn một chút, những xử lý dưới đây nhất quyết không được viết chung vào một method.

[Tính toán xong một thứ gì đó → lưu kết quả tính toán]

Tóm lại là, sau khi trả ra kết quả tính toán phải lưu giá trị tại nơi gọi method đó.

3.4 Có start thì phải có stop

Tôi cũng rất hay gặp phải điều trên.

"tại sao thấy có start mà chẳng thấy stop đâu vậy?"

Dẫu biết không chỉ đơn thuần là start và stop không, tuy nhiên có các method theo kiểu đối nhau đúng không.

Start thì được làm trong constructor của instance, stop thì lại cho xử lý từ bên ngoài, các bạn đã từng gặp class kiểu đó chưa?

Tóm lại hãy đảm bảo tính nhất quán cho code của mình.

3.5 Hẹp, Mạnh

Phạm vi scope hẹp thôi, nhưng hạn chế thì phải mạnh.

Tóm lại cho toàn bộ các method là private. Sau đó chỉ public những method cần thiết ra ngoài mà thôi.

Có rất nhiều các method chỉ sử dụng trong class thôi nhưng cũng bị public ra ngoài, thực sự tôi nhìn mà hết chịu nổi.

Property cũng hãy set cho là readOnly, sau đó nếu cần thì mới cho cả quyền write nữa.

Gắn const cho tất cả các biến, đối số của method cũng gắn const. Những chỗ có thể hạn chế được thì phải hạn chế hết.

3.6 Callback không được lẫn với logic

Không được gọi callback trong một method có viết logic gì đó.

Đây là trường hợp khi bản thân trả callback tới nơi gọi.

Tóm lại là không cho lẫn phần từ con trả về cha với logic được.

3.7 Tuyệt đối không được tham chiếu lẫn nhau

Tôi đã hết sức rồi, điều muốn nói y hệt như tựa đề mà thôi.

Tôi đã từng nhìn thấy một đoạn code như sau:

Trong một mối quan hệ has-a, instance của cha là singleton, instance con đưa chính bản thân vào property của instance cha lấy được thông qua singleton.

Không phải cứ không giữ property tham chiếu trực tiếp instance cha là xong đâu.

Đây cũng chính là tham chiếu lẫn nhau đấy.

3.8 Đừng cố viết comment thật đẹp làm gì, vấn đề là đưa suy nghĩ của mình vào đấy

Hôm trước tôi có xem được một comment như sau

// Chạy tại main thread

Tôi đã ngay lập tức có câu hỏi "tại sao?".

Đúng thế, chỉ một câu thôi:

"Đừng viết những comment làm người khác phải hỏi tại sao"

Với comment đó, nếu được sửa thành comemnt tốt sẽ là như sau:

// Tại nơi được gọi, do có xử lý vẽ cho nên sẽ gọi bằng main thread

Tiếp theo là ví dụ comment có đưa suy nghĩ vào

// Không hiểu lắm tuy nhiên nếu gọi bằng main thread thì không bị crash nữa

Khi nhìn comment này thì chúng ta cũng hiểu được level của engineer đó, ngoài ra cũng biết được vấn đề là sửa comment này cũng không sao, cho nên người nắm được vấn đề có thể sửa bổ sung.

Các bạn thử nhìn lại một lần nữa comment dưới đây có thấy vấn đề gì không

// Thực hiện tại main thread

Ngay từ đoạn không hiểu tại sao lại thế này thì người đọc cũng rất khó để sửa chữa được.

Ngoài ra chính vì đoạn comment kiểu thế này nên mới ngày càng sinh ra những đoạn code khó hiểu.

0