Có một số vấn đề với đoạn mã này, nhân tiện, có thể rút ngắn như thế này:
public List<Money> getMoneyByPersons() {
return persons.size() == 1 ?
moneyService.getMoneyIfHasOnePerson() :
moneyService.getMoney();
}
Không rõ tại sao một người là một trường hợp đặc biệt. Tôi cho rằng có một quy tắc kinh doanh cụ thể cho biết rằng nhận tiền từ một người hoàn toàn khác với nhận tiền từ nhiều người. Tuy nhiên, tôi phải đi và nhìn vào bên trong cả hai getMoneyIfHasOnePerson
, và getMoney
hy vọng hiểu tại sao có những trường hợp khác biệt.
Cái tên getMoneyIfHasOnePerson
không đúng. Từ tên, tôi sẽ mong đợi phương pháp kiểm tra nếu có một người duy nhất và, nếu đây là trường hợp, hãy lấy tiền từ anh ta; nếu không thì không làm gì cả Từ mã của bạn, đây không phải là điều đang xảy ra (hoặc bạn đang làm điều kiện hai lần).
Có bất kỳ lý do để trả lại một List<Money>
thay vì một bộ sưu tập?
Quay lại câu hỏi của bạn, vì không rõ lý do tại sao có một điều trị đặc biệt cho một người, nên thay thế một chữ số bằng một hằng số, trừ khi có một cách khác để làm cho các quy tắc rõ ràng. Ở đây, một người không khác lắm so với bất kỳ số ma thuật nào khác. Bạn có thể có các quy tắc kinh doanh nói rằng việc đối xử đặc biệt áp dụng cho một, hai hoặc ba người, hoặc chỉ với hơn mười hai người.
Làm thế nào tôi có thể phân biệt bối cảnh để chọn giải pháp tốt nhất?
Bạn làm bất cứ điều gì làm cho mã của bạn rõ ràng hơn.
ví dụ 1
Hãy tưởng tượng đoạn mã sau:
if (sequence.size() == 0) {
return null;
}
return this.processSequence(sequence);
Không có ở đây một giá trị ma thuật? Mã này khá rõ ràng: nếu không có phần tử nào trong chuỗi, chúng ta không xử lý nó và trả về một giá trị đặc biệt. Nhưng mã này cũng có thể được viết lại như thế này:
if (sequence.isEmpty()) {
return null;
}
return this.processSequence(sequence);
Ở đây, không còn hằng số, và mã thậm chí còn rõ ràng hơn.
Ví dụ 2
Lấy một đoạn mã khác:
const result = Math.round(input * 1000) / 1000;
Không mất quá nhiều thời gian để hiểu những gì nó làm trong các ngôn ngữ như JavaScript không bị round(value, precision)
quá tải.
Bây giờ, nếu bạn muốn giới thiệu một hằng số, nó sẽ được gọi như thế nào? Thuật ngữ gần nhất bạn có thể nhận được là Precision
. Vì thế:
const precision = 1000;
const result = Math.round(input * precision) / precision;
Nó cải thiện khả năng đọc? Có thể là. Ở đây, giá trị của hằng số khá hạn chế và bạn có thể tự hỏi mình có thực sự cần thực hiện tái cấu trúc không. Điều tuyệt vời ở đây là bây giờ, độ chính xác chỉ được khai báo một lần, vì vậy nếu nó thay đổi, bạn không có nguy cơ mắc lỗi như:
const result = Math.round(input * 100) / 1000;
thay đổi giá trị ở một vị trí và quên làm điều đó ở một vị trí khác.
Ví dụ 3
Từ những ví dụ đó, bạn có thể có ấn tượng rằng các số phải được thay thế bằng hằng số trong mọi trường hợp . Đây không phải là sự thật. Trong một số trường hợp, việc có một hằng số không dẫn đến cải tiến mã.
Lấy đoạn mã sau:
class Point
{
...
public void Reset()
{
x, y = (0, 0);
}
}
Nếu bạn cố gắng thay thế số không bằng một biến, khó khăn sẽ là tìm một tên có ý nghĩa. Làm thế nào bạn sẽ đặt tên cho nó? ZeroPosition
? Base
? Default
? Giới thiệu một hằng số ở đây sẽ không tăng cường mã theo bất kỳ cách nào. Nó sẽ làm cho nó dài hơn một chút, và chỉ vậy thôi.
Những trường hợp như vậy rất hiếm. Vì vậy, bất cứ khi nào bạn tìm thấy một số trong mã, hãy nỗ lực tìm cách làm thế nào mã có thể được tái cấu trúc. Hãy tự hỏi nếu có một ý nghĩa kinh doanh cho số. Nếu có, một hằng số là bắt buộc. Nếu không, bạn sẽ đặt tên cho số như thế nào? Nếu bạn tìm thấy một cái tên có ý nghĩa, đó là tuyệt vời. Nếu không, rất có thể bạn đã tìm thấy một trường hợp mà hằng số là không cần thiết.
persons
đến từ đâu và nó mô tả cái gì? Mã của bạn không có ý kiến gì vì vậy thật khó để đoán nó đang làm gì.