Nó có mùi vì có thể có nhiều trường hợp nó 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à gợi ý về điều gì đó có thể không ổn. Do đó, bản thân chúng không bắt buộc phải sửa… (Tuy nhiên, bạn nên xem xét nó.)
Bạn có thể tìm thấy tất cả các mùi mã trước đó (Phần i - XXIX) tại đây
Tiếp tục đi...
Nhận xét là một mã Mùi. Getters là một mùi mã khác. Đoán xem?
TL; DR: Không sử dụng getters. Không nhận xét getters
Một vài thập kỷ trước, chúng tôi đã từng bình luận về mọi phương pháp. Ngay cả những thứ tầm thường.
Nhận xét chỉ nên mô tả một quyết định thiết kế quan trọng.
pragma solidity >=0.5.0 <0.9.0; contract Property { int private price; function getPrice() public view returns(int) { /* returns the Price */ return price; } }
pragma solidity >=0.5.0 <0.9.0; contract Property { int private _price; function price() public view returns(int) { return _price; } }
Chúng tôi có thể phát hiện xem một phương thức có phải là phương thức thu thập hay không và có nhận xét hay không.
Chức năng cần một nhận xét, đó vô tình là một getter và nhận xét có liên quan đến một quyết định thiết kế
Đừng bình luận getters.
Họ không thêm giá trị thực và phình to mã của bạn.
Mã Mùi 05 - Kẻ Lạm Dụng Bình Luận
Mã Mùi 01 - Người Mẫu Thiếu Máu
Ảnh của Reimond de Zuñiga trên Bapt
Mã phải có tính biểu cảm rõ ràng để tránh hầu hết các nhận xét. Sẽ có một vài trường hợp ngoại lệ, nhưng chúng ta nên coi các nhận xét là 'không diễn đạt được' cho đến khi được chứng minh là sai.
Robert Martin
Báo giá tuyệt vời về kỹ thuật phần mềm
Các lớp sử dụng là tuyệt vời để thu thập giao thức.
TL; DR: Đừng thêm giao thức ngẫu nhiên vào lớp học của bạn
Tái cấu trúc 007 - Trích xuất lớp
Chúng tôi có xu hướng đặt một giao thức trong lớp đầu tiên mà chúng tôi tìm thấy.
Đó không phải là một vấn đề.
Chúng ta chỉ cần cấu trúc lại.
public class MyHelperClass { public void print() { } public void format() { } // ... many methods more // ... even more methods public void persist() { } public void solveFermiParadox() { } }
public class Printer { public void print() { } } public class DateToStringFormatter { public void format() { } } public class Database { public void persist() { } } public class RadioTelescope { public void solveFermiParadox() { } }
Hầu hết các phương pháp linters đếm và cảnh báo chúng tôi.
Mã Mùi 124 - Thay Đổi Khác Biệt
Mã Mùi 34 - Quá Nhiều Thuộc Tính
Tách các lớp và giao thức là một cách thực hành tốt để ưu tiên các đối tượng nhỏ và có thể tái sử dụng.
Ảnh của Marcin Simonides trên Bapt
Không có mã nào quá lớn, xoắn hoặc phức tạp đến mức việc bảo trì không thể làm cho nó trở nên tồi tệ hơn.
Gerald M. Weinberg
Chúng ta mua nợ cho chính chúng ta trong tương lai. Đó là thời gian hoàn vốn.
TL; DR: Đừng để TODO trong mã của bạn. Sửa chúng!
Chúng tôi gặp TODO trong mã của chúng tôi. Chúng tôi đếm chúng.
Chúng tôi hiếm khi giải quyết nó.
Chúng tôi bắt đầu mắc nợ kỹ thuật.
Sau đó, chúng tôi trả nợ + lãi.
Vài tháng sau, chúng tôi trả lãi nhiều hơn nợ gốc.
public class Door { private Boolean isOpened; public Door(boolean isOpened) { this.isOpened = isOpened; } public void openDoor() { this.isOpened = true; } public void closeDoor() { // TODO: Implement close door and cover it } }
public class Door { private Boolean isOpened; public Door(boolean isOpened) { this.isOpened = isOpened; } public void openDoor() { this.isOpened = true; } public void closeDoor() { this.isOpened = false; } }
Chúng ta có thể đếm TODO.
Chúng ta có thể đếm TODO.
Hầu hết các linters làm điều đó.
Chúng ta cần chính sách để giảm thiểu chúng.
Nếu chúng tôi đang sử dụng TDD, chúng tôi sẽ viết mã bị thiếu ngay lập tức.
Trong bối cảnh này, TODO chỉ hợp lệ khi thực hiện phát triển Depth First để ghi nhớ các đường dẫn mở để truy cập.
Ảnh của Eden Constantino trên Bapt
Sau khi bạn hoàn thành 90% đầu tiên của dự án, bạn phải hoàn thành 90% còn lại.
Micheal Abrash
Mã của chúng tôi mạnh mẽ và dễ đọc hơn. Nhưng chúng tôi giấu NULL dưới tấm thảm.
TL; DR: Tránh Nulls và không xác định. Nếu bạn tránh chúng, bạn sẽ không bao giờ cần Tùy chọn.
Chuỗi tùy chọn , Tùy chọn, Hợp nhất và nhiều giải pháp khác giúp chúng tôi xử lý các giá trị rỗng khét tiếng.
Không cần sử dụng chúng khi mã của chúng tôi đã hoàn thiện, mạnh mẽ và không có giá trị rỗng.
const user = { name: 'Hacker' }; if (user?.credentials?.notExpired) { user.login(); } user.functionDefinedOrNot?.(); // Seems compact but it is hacky and has lots // of potential NULLs and Undefined
function login() {} const user = { name: 'Hacker', credentials: { expired: false } }; if (!user.credentials.expired) { login(); } // Also compact // User is a real user or a polymorphic NullUser // Credentials are always defined. // Can be an instance of InvalidCredentials // Assuming we eliminated nulls from our code if (user.functionDefinedOrNot !== undefined) { functionDefinedOrNot(); } // This is also wrong. // Explicit undefined checks are yet another code smell
Đây là một Tính năng Ngôn ngữ .
Chúng tôi có thể phát hiện nó và loại bỏ nó.
Nhiều nhà phát triển cảm thấy an toàn khi làm ô nhiễm mã với xử lý null.
Trên thực tế, điều này an toàn hơn là không xử lý NULL.
Nullish Values , Truthy và Falsy cũng là mùi mã.
Chúng ta cần nhắm mục tiêu cao hơn và làm cho mã sạch hơn.
Điều tốt : xóa tất cả các giá trị rỗng khỏi mã của bạn.
Nhược điểm : sử dụng chuỗi tùy chọn.
Điều xấu xí : hoàn toàn không xử lý null.
Code Smell 69 - Big Bang (JavaScript Ridiculous Castings)
Làm thế nào để thoát khỏi IF khó chịu mãi mãi
Ảnh của engin akyurt trên Bapt
Anh ta chiến đấu với quái vật có thể cẩn thận kẻo anh ta trở thành một con quái vật. Và nếu bạn nhìn lâu vào một vực thẳm, thì vực thẳm cũng nhìn chằm chằm vào bạn.
Nietzsche
Mọi nhà phát triển đều so sánh các thuộc tính như nhau. Họ đã nhầm.
TL;DR: Không export rồi so sánh, chỉ so sánh thôi.
So sánh thuộc tính được sử dụng nhiều trong mã của chúng tôi.
Chúng ta cần tập trung vào hành vi và trách nhiệm.
Trách nhiệm của một đối tượng là so sánh với các đối tượng khác. Không phải của riêng chúng tôi.
Trình tối ưu hóa sớm sẽ cho chúng tôi biết điều này kém hiệu quả hơn.
Chúng ta nên yêu cầu họ cung cấp bằng chứng xác thực và đối chiếu giải pháp dễ duy trì hơn.
if (address.street == 'Broad Street') { if (location.street == 'Bourbon St') { // 15000 usages in a big system // Comparisons are case sensitive
if (address.isAtStreet('Broad Street') { } // ... if (location.isAtStreet('Bourbon St') { } // 15000 usages in a big system function isAtStreet(street) { // We can change Comparisons to // case sensitive in just one place. }
Chúng ta có thể phát hiện các so sánh thuộc tính bằng cách sử dụng cây cú pháp.
Có thể có những cách sử dụng tốt cho các loại nguyên thủy cũng như với nhiều mùi khác.
Chúng ta cần đặt trách nhiệm ở một nơi duy nhất.
So sánh là một trong số đó.
Nếu một số quy tắc kinh doanh của chúng tôi thay đổi, chúng tôi cần thay đổi một điểm duy nhất .
Mã mùi 101 - So sánh với Booleans
Mã Mùi 122 - Ám Ảnh Nguyên Thủy
Ảnh của Piret Ilver trên Bapt
Hành vi là điều quan trọng nhất về phần mềm. Đó là những gì người dùng phụ thuộc vào. Người dùng thích khi chúng tôi thêm hành vi (miễn là đó là điều họ thực sự muốn), nhưng nếu chúng tôi thay đổi hoặc xóa hành vi mà họ phụ thuộc vào (giới thiệu lỗi), họ sẽ ngừng tin tưởng chúng tôi.
michael lông vũ
Bài tiếp theo: 5 mùi code nữa.