Trong một số ngôn ngữ lập trình, thứ tự có vấn đề vì bạn không thể sử dụng mọi thứ cho đến khi chúng được khai báo. Nhưng việc chặn rằng, đối với hầu hết các ngôn ngữ, nó không quan trọng đối với trình biên dịch. Vì vậy, sau đó, bạn còn lại với nó quan trọng với con người.
Câu nói yêu thích của Martin Fowler của tôi là: Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Vì vậy, tôi muốn nói rằng việc sắp xếp thứ tự lớp học của bạn nên phụ thuộc vào điều gì giúp con người dễ hiểu.
Cá nhân tôi thích cách đối xử từ từ mà Bob Martin đưa ra trong Clean Code
cuốn sách của mình . Các biến thành viên ở đầu lớp, sau đó là constructor, sau đó là tất cả các phương thức khác. Và bạn ra lệnh cho các phương thức gần nhau với cách chúng được sử dụng trong lớp (thay vì tự ý đặt tất cả công khai rồi riêng tư sau đó được bảo vệ). Ông gọi nó là tối thiểu hóa "khoảng cách dọc" hoặc một cái gì đó tương tự (hiện tại không có cuốn sách nào cho tôi).
Chỉnh sửa:
Ý tưởng cơ bản của "khoảng cách dọc" là bạn muốn tránh làm cho mọi người nhảy xung quanh mã nguồn của bạn chỉ để hiểu nó. Nếu mọi thứ có liên quan, họ nên gần nhau hơn. Những thứ không liên quan có thể xa nhau hơn.
Chương 5 của Clean Code (cuốn sách tuyệt vời, btw) đi sâu vào rất nhiều chi tiết về cách ông Martin gợi ý mã đặt hàng. Ông gợi ý rằng việc đọc mã nên hoạt động giống như đọc một bài báo: các chi tiết cấp cao xuất hiện trước (ở trên cùng) và bạn sẽ có được nhiều chi tiết hơn khi bạn đọc xuống. Ông nói, "Nếu một chức năng gọi một chức năng khác, chúng nên được đóng theo chiều dọc và người gọi nên ở trên mức trung bình, nếu có thể." Ngoài ra, các khái niệm liên quan nên gần nhau.
Vì vậy, đây là một ví dụ giả định rất tệ theo nhiều cách (thiết kế OO kém; không bao giờ sử dụng double
tiền) nhưng minh họa ý tưởng:
public class Employee {
...
public String getEmployeeId() { return employeeId; }
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public double calculatePaycheck() {
double pay = getSalary() / PAY_PERIODS_PER_YEAR;
if (isEligibleForBonus()) {
pay += calculateBonus();
}
return pay;
}
private double getSalary() { ... }
private boolean isEligibleForBonus() {
return (isFullTimeEmployee() && didCompleteBonusObjectives());
}
public boolean isFullTimeEmployee() { ... }
private boolean didCompleteBonusObjectives() { ... }
private double calculateBonus() { ... }
}
Các phương thức được sắp xếp sao cho chúng gần với các phương thức gọi chúng, làm việc theo cách của chúng tôi từ trên xuống. Nếu chúng ta đã đặt tất cả các private
phương thức bên dưới các phương thức public
, thì bạn sẽ phải nhảy nhiều hơn để theo dòng chảy của chương trình.
getFirstName
và getLastName
có liên quan về mặt khái niệm (và getEmployeeId
có lẽ là quá), vì vậy chúng gần nhau. Chúng ta có thể di chuyển tất cả chúng xuống phía dưới, nhưng chúng ta sẽ không muốn nhìn thấy getFirstName
ở phía trên và getLastName
phía dưới.
Hy vọng điều này cung cấp cho bạn những ý tưởng cơ bản. Nếu bạn quan tâm đến loại điều này, tôi thực sự khuyên bạn nên đọc Clean Code
.