Đối số đầu ra là gì, như được giới thiệu trong Bộ luật sạch của Martin?


14

Trên trang 45 của Bộ luật sạch của Robert C. Martin: Cẩm nang về thủ công phần mềm linh hoạt, Martin viết rằng nên tránh các đối số đầu ra. Tôi gặp khó khăn trong việc hiểu ý nghĩa của "đối số đầu ra" và tại sao chúng nên được tránh.

Ví dụ của Martin cho một đối số đầu ra appendFooter(s);gọi hàm public void appendFooter(StringBuffer report). Cải tiến mã của anh ấy làreport.appendFooter();

Có thể đó là do thiếu bối cảnh mã, nhưng tôi không thấy cách sử dụng các đối số đầu ra được coi là mã hóa kém. Ai đó có thể giải thích khái niệm hoặc đưa ra ví dụ bổ sung của mã để hiểu điều này?

Các chức năng sau đây cũng sẽ được coi là một ví dụ về mã ô uế theo nguyên tắc trên?

int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);

Nếu ở trên là vi phạm nguyên tắc không sử dụng đối số đầu ra của Martin, thì tốt hơn là có một đối tượng có một mảng là một trường và một hàm có thể được gọi để sắp xếp mảng?

ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();

Câu trả lời:


10

Bob Martin chỉ đơn giản là nói về khả năng đọc .

Vấn đề với appendFooterví dụ là, nếu bạn tìm thấy dòng mã appendFooter(s)ở đâu đó trong một chương trình, sẽ không rõ ràng ngay lập tức nếu cuộc gọi đó sđầu vào và nối nó ở đâu đó, hoặc nếu sđược chuyển qua để lấy đầu ra của hàm đó. Để chắc chắn, bạn cần kiểm tra tài liệu của chức năng. report.appendFooter()Tuy nhiên, một cuộc gọi như thế sẽ tránh được vấn đề đó: bây giờ rõ ràng hơn nhiều những gì xảy ra.

Tuy nhiên, lưu ý, Bob Martin không nói "không bao giờ sử dụng đối số đầu ra", ông nói "nói chung, bạn nên tránh nó, bởi vì nó sẽ giúp bạn giữ mã của mình sạch hơn một chút". Vì vậy, đây không phải là một quy tắc sùng bái hàng hóa dũng cảm người ta nên tuân theo một cách mù quáng.

Sortphương pháp cho mảng và bộ sưu tập tiêu chuẩn hơi khác một chút. Có sortphương pháp một hàm thành viên của mỗi kiểu dữ liệu mảng tiêu chuẩn sẽ có một vài hạn chế từ quan điểm của nhà thiết kế ngôn ngữ của xem, ví dụ, có một phương pháp như Array.sortcho phép để giữ này trong thư viện chuẩn, ngoài thời gian chạy Java. Nhưng nếu bạn sẽ tạo một loại bộ sưu tập riêng lẻ đôi khi phải được sắp xếp, thêm vào sortnhư một hàm thành viên có thể thực sự là một ý tưởng tốt hơn so với việc đưa nó vào một lớp riêng biệt.


2
sortArray(numberArray), tất nhiên, sắp xếp numberArraytại chỗ. Hoặc nó tạo một bản sao numberArray, sắp xếp bản sao và trả lại bản sao đã sắp xếp mà không thay đổi numberArraygì cả?
8bittree

@ 8bittree: điều đó đúng, nhưng đó không phải là vấn đề khó khăn ở đây - một sort()phương pháp của một container có thể hoạt động tại chỗ, mà không cần sử dụng "đối số đầu ra". Vì vậy, chỉ vì sortArray(numberArray)một phương thức tại chỗ hoàn toàn không có lý do nào biện minh cho "mẫu đối số đầu ra".
Doc Brown

1
Quan điểm của tôi là nhiều hơn rằng nó không hoàn toàn rõ ràng những gì sortArray(numberArray)đang làm. Có thể rõ ràng nếu nó không trả về cùng loại mà nó chấp nhận, thì nó phải được đặt đúng chỗ. Nhưng không nhìn thấy kiểu trả về, hoặc nếu kiểu trả về khớp với kiểu đầu vào, thì nó không rõ ràng mà không nhìn vào định nghĩa.
8bittree

1
@ 8bittree: Ok, bạn hiểu ý tôi rồi, tôi đã gỡ bỏ tuyên bố bị đe dọa khỏi câu trả lời của tôi. Tuy nhiên, vấn đề mà mô tả của bạn không biến mất khi sử dụng hàm thành viên - ngay cả hàm thành viên "sắp xếp" cũng có thể hành xử theo cách đó.
Doc Brown

10

Đó là vấn đề sử dụng một cơ chế không mong muốn để trả về một giá trị từ hàm, thường là kết quả của việc thực hiện quá nhiều chức năng hoặc có các trách nhiệm sai lệch. Cho đến nay, cách tốt nhất để truyền đạt kết quả của hàm là sử dụng giá trị trả về. Tôi hy vọng đó là hiển nhiên. Trong các ngôn ngữ hướng đối tượng, phương pháp tốt thứ hai là biến đổi đối tượng.

Giữa hai tùy chọn đó, có rất nhiều cách rõ ràng để truyền đạt kết quả của hàm mà nếu bạn thấy mình muốn thay đổi các đối số như là phương tiện duy nhất, thì có gì đó không ổn trong kiến ​​trúc của bạn. Bạn cần sắp xếp lại các trách nhiệm trong lớp để người thực hiện việc đột biến sở hữu dữ liệu ngay từ đầu.

Một ngoại lệ là cho các thuật toán rất chung chung. Ví dụ, thuật toán sắp xếp có thể tách biệt khỏi các thùng chứa mà nó sắp xếp, nếu nó có thể được áp dụng chung cho bất kỳ loại container nào sử dụng giao diện chung của nó. Hàm one-shot appendFooterkhông có lý do đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.