Mùi mã là một cổ điển.
Nó có mùi vì có thể có nhiều trường hợp có thể được chỉnh sửa hoặc cải thiện.
Hầu hết những mùi này chỉ là dấu hiệu của điều gì đó có thể không ổn. Chúng không được yêu cầu cố định mỗi ngày… (Tuy nhiên, bạn nên xem xét nó.)
Mã trước có mùi
- Phần I
- Phần II
- Phần III
- Phần IV
- Phần V
- Phần VI
- Phần VII
- Phần VIII
- Phần IX
- Phần X
- Phần XI
- Phần XII
- Phần XIII
- Phần XIV
- Phần XV
- Phần XVI
- Phần XVII
- Phần XVIII
- Phần XIX
- Phần XX
Tiếp tục đi...
Code Smell 101 - So sánh với Boolean
Khi so sánh với boolean, chúng tôi thực hiện phép đúc và nhận được kết quả bất ngờ.
TL; DR: Đừng so sánh với sự thật. Hoặc bạn đúng, hoặc sai hoặc bạn không nên so sánh
Các vấn đề
- Đúc ẩn
- Sự vi phạm nguyên tắc ít bất ngờ nhất.
- Không thành công nhanh vi phạm nguyên tắc
Các giải pháp
- Sử dụng boolean
- Không trộn boolean với các đối tượng có thể cast boolean
Định nghĩa bài văn
Nhiều ngôn ngữ truyền giá trị tới các miền giao nhau boolean.
Mã mẫu
Sai
#!/bin/bash if [ false ]; then echo "True" else echo "False" fi # this evaluates to true since # "false" is a non-empty string if [ false ] = true; then echo "True" else echo "False" fi # this also evaluates to true
Đúng
#!/bin/bash if false ; then echo "True" else echo "False" fi # this evaluates to false
Phát hiện
- [x] Tự động
Linters có thể kiểm tra các so sánh và cảnh báo rõ ràng.
Thẻ
- Đúc
Sự kết luận
Một thực tế phổ biến trong ngành là sử dụng nhiều boolean không phải boolean. Chúng ta nên rất nghiêm ngặt khi sử dụng boolean.
Quan hệ
Code Smell 69 - Big Bang (JavaScript Ridiculous Castings)
Thêm thông tin
Tín dụng
Ảnh của Michael Held trên Unsplash
Nếu nó không hoạt động, nó không có tác dụng nhanh như thế nào.
- Mich Ravera
Mã mùi 102 - Mã mũi tên
IF và Elses lồng nhau rất khó đọc và kiểm tra
TL; DR: Tránh các IF lồng nhau. Thậm chí tốt hơn: Tránh TẤT CẢ CÁC NẾU
Các vấn đề
- Khả năng đọc
Các giải pháp
- Phương pháp trích xuất
- Kết hợp các điều kiện Boolean
- Loại bỏ các IF không cố ý
Định nghĩa bài văn
Trong mã thủ tục, rất thường thấy các if lồng nhau phức tạp. Giải pháp này liên quan nhiều đến kịch bản hơn là lập trình hướng đối tượng.
Mã mẫu
Sai
if (actualIndex < totalItems) { if (product[actualIndex].Name.Contains("arrow")) { do { if (product[actualIndex].price == null) { // handle no price } else { if (!(product[actualIndex].priceIsCurrent())) { // add price } else { if (!hasDiscount) { // handle discount } else { // etc } } } actualIndex++; } while (actualIndex < totalCounf && totalPrice < wallet.money); } else actualIndex++; } return actualIndex; }
Đúng
foreach (products as currentProduct) addPriceIfDefined(currentProduct) addPriceIfDefined() { //Several extracts }
Phát hiện
- [x] Tự động
Vì nhiều linters có thể phân tích cú pháp cây, chúng tôi có thể kiểm tra thời gian biên dịch cho các cấp độ lồng nhau.
Thẻ
- Khả năng đọc
- Sự phức tạp
Sự kết luận
Theo lời khuyên của chú bob , chúng ta nên để mã sạch hơn chúng ta đã tìm thấy.
Tái cấu trúc vấn đề này rất dễ dàng.
Quan hệ
Code Smell 78 - Địa ngục gọi lại
Code Smell 03 - Các hàm quá dài
Code Smell 36 - Câu lệnh switch / case / elseif / else / if
Thêm thông tin
Mục đích của kỹ thuật phần mềm là kiểm soát độ phức tạp, không phải để tạo ra nó.
- Pamela Zave
Code Smell 103 - Double Encapsulation
Gọi các phương thức truy cập của riêng chúng tôi có vẻ là một ý tưởng đóng gói tốt. Nhưng nó không phải như vậy.
TL; DR: Không sử dụng setters và getters, ngay cả khi sử dụng cho mục đích cá nhân
Các vấn đề
- Người định cư
- Getters
- Tiết lộ các thuộc tính riêng tư
Các giải pháp
- Xóa người định vị
- Loại bỏ các mối quan hệ
- Bảo vệ các thuộc tính của bạn
Định nghĩa bài văn
Sử dụng đóng gói kép là một quy trình tiêu chuẩn trong những năm 90.
Chúng tôi muốn ẩn chi tiết triển khai ngay cả khi sử dụng riêng tư.
Điều này đang che giấu một mùi khác khi có quá nhiều chức năng dựa vào cấu trúc dữ liệu và việc triển khai ngẫu nhiên.
Ví dụ, chúng ta có thể thay đổi biểu diễn bên trong của một đối tượng và dựa vào giao thức bên ngoài của nó.
Chi phí / lợi ích không đáng là bao.
Mã mẫu
Sai
contract MessageContract { string message = "Let's trade"; function getMessage() public constant returns(string) { return message; } function setMessage(string newMessage) public { message = newMessage; } function sendMessage() public constant { this.send(this.getMessage()); // We can access property but make a self call instead } }
Đúng
contract MessageContract { string message = "Let's trade"; function sendMessage() public constant { this.send(message); } }
Phát hiện
- [x] Bán tự động
Chúng ta có thể suy ra getters và setters và kiểm tra xem chúng có được gọi từ cùng một đối tượng hay không.
Thẻ
- Đóng gói
Sự kết luận
Đóng gói kép là một ý tưởng hợp thời để bảo vệ việc thực hiện ngẫu nhiên, nhưng nó lộ ra nhiều thứ hơn là được bảo vệ.
Quan hệ
Code Smell 37 - Thuộc tính được bảo vệ
Thêm thông tin
Tín dụng
Ảnh của Ray Hennessy trên Unsplash
Đóng gói khái niệm thay đổi.
- Erich Gamma
Mã mùi 104 - Khẳng định đúng
Khẳng định chống lại boolean làm cho việc theo dõi lỗi khó khăn hơn.
TL; DR: Không khẳng định đúng trừ khi bạn đang kiểm tra boolean
Các vấn đề
- Nguyên tắc nhanh không thành công
Các giải pháp
- Kiểm tra xem điều kiện boolean có thể được viết lại tốt hơn không
- Khẳng định ủng hộ
Định nghĩa bài văn
Khi xác nhận boolean, công cụ kiểm tra của chúng tôi không thể giúp chúng tôi nhiều.
Họ chỉ cho chúng tôi biết một cái gì đó không thành công.
Theo dõi lỗi trở nên khó khăn hơn.
Mã mẫu
Sai
<? final class RangeUnitTest extends TestCase { function testValidOffset() { $range = new Range(1, 1); $offset = $range->offset(); $this->assertTrue(10 == $offset); // No functional essential description :( // Accidental description provided by tests is very bad } } // When failing Unit framework will show us // // 1 Test, 1 failed // Failing asserting true matches expected false :( // () <-- no business description :( // // <Click to see difference> - Two booleans // (and a diff comparator will show us two booleans)
Đúng
<? final class RangeUnitTest extends TestCase { function testValidOffset() { $range = new Range(1, 1); $offset = $range->offset(); $this->assertEquals(10, $offset, 'All pages must have 10 as offset'); // Expected value should always be first argument // We add a functional essential description // to complement accidental description provided by tests } } // When failing Unit framework will show us // // 1 Test, 1 failed // Failing asserting 0 matches expected 10 // All pages must have 10 as offset <-- business description // // <Click to see difference> // (and a diff comparator will help us and it will be a great help // for complex objects like objects or jsons)
Phát hiện
- [x] Bán tự động
Một số linters cảnh báo chúng tôi nếu chúng tôi đang kiểm tra boolean sau khi thiết lập điều kiện này.
Chúng tôi cần thay đổi nó thành một kiểm tra cụ thể hơn.
Thẻ
- Kiểm tra mùi
Sự kết luận
Cố gắng viết lại các xác nhận boolean của bạn và bạn sẽ sửa lỗi nhanh hơn nhiều.
Quan hệ
Code Smell 101 - So sánh với Boolean
Thêm thông tin
Tín dụng
Ảnh của Joël de Vriend trên Unsplash
Cuối cùng tôi đã học được 'tương thích trở lên' nghĩa là gì. Nó có nghĩa là chúng ta phải giữ tất cả những sai lầm cũ của chúng ta.
- Dennie van Tassel
Code Smell 105 - Phương pháp diễn viên hài
Sử dụng tên chuyên nghiệp và có ý nghĩa
TL; DR: Không thân mật hoặc xúc phạm
Các vấn đề
- Khả năng đọc
- Làm việc không chuyên nghiệp
Các giải pháp
- Chọn những cái tên hay và chuyên nghiệp.
Định nghĩa bài văn
Nghề nghiệp của chúng tôi có một mặt sáng tạo.
Đôi khi chúng ta cảm thấy buồn chán và cố gắng trở nên hài hước.
Mã mẫu
Sai
function erradicateAndMurderAllCustomers(); // unprofessional and offensive
Đúng
function deleteAllCustomers(); // more declarative and professional
Phát hiện
- [x] Bán tự động
Chúng tôi có thể có một danh sách các từ bị cấm.
Chúng tôi cũng có thể kiểm tra chúng trong các bài đánh giá mã.
Tên là theo ngữ cảnh, vì vậy sẽ là một nhiệm vụ khó khăn đối với một người viết thư tự động.
Các quy ước đặt tên phải chung chung và không được bao gồm các biệt ngữ văn hóa.
Thẻ
- Đặt tên
Sự kết luận
Hãy chuyên nghiệp trong cách bạn đặt tên cho mọi thứ trong mã của mình.
Đừng cố gắng trở thành một diễn viên hài bằng cách đặt cho một biến thể một cái tên ngớ ngẩn.
Bạn nên viết mã sản xuất để các nhà phát triển phần mềm tương lai (kể cả bạn) có thể dễ dàng hiểu được.
Quan hệ
Thêm thông tin
Tín dụng
Ảnh của Stewart Munro trên Unsplash
Tâm lý 'người dùng là những kẻ ngốc và bị nhầm lẫn bởi chức năng' của Gnome là một căn bệnh. Nếu bạn nghĩ rằng người dùng của mình là những kẻ ngốc, thì chỉ những kẻ ngốc mới sử dụng nó.
- Linus Torvalds
Trích dẫn tuyệt vời về kỹ thuật phần mềm
Và đó là tất cả cho bây giờ…
Bài sau sẽ giải thích thêm về 5 mùi mã nhé!