Gần đây, chúng tôi đã xem xét mã. Một trong các lớp của tôi đã được sử dụng để tôi có thể trả về/chuyển nhiều loại dữ liệu từ/sang phương thức. Các phương pháp duy nhất mà lớp học có được là getters/setters. Một trong những thành viên của nhóm (có quan điểm tôi tôn trọng) nói rằng có một lớp học như vậy là thực hành không tốt (và không phải là rất OOP). Tại sao vậy ?Tại sao sử dụng một lớp như là một thực hành cấu trúc xấu trong Java?
Trả lời
Có một đối số là lớp "cấu trúc dữ liệu" (nghĩa là tập trung vào lưu trữ dữ liệu không có chức năng) hoặc "định hướng chức năng" (nghĩa là tập trung thực hiện các hành động nhất định trong khi lưu trữ trạng thái tối thiểu). Nếu bạn làm theo lập luận đó (có ý nghĩa nhưng không phải lúc nào cũng dễ dàng để làm) thì không có gì nhất thiết phải sai với điều đó.
Thực tế, người ta cho rằng hạt đậu và thực thể về cơ bản là - các thùng chứa dữ liệu với các getters và setters.
Tôi đã thấy một số nguồn nhất định (ví dụ: sách "mã sạch") cho rằng người ta nên tránh các phương pháp có nhiều tham số và thay vào đó chuyển chúng thành một đối tượng duy nhất với getters và setters. Điều này cũng gần gũi hơn với "mô hình smalltalk" của các tham số được đặt tên khi thứ tự không quan trọng.
Vì vậy, tôi nghĩ rằng khi được sử dụng một cách thích hợp, thiết kế của bạn có ý nghĩa.
Nói chung, bạn sẽ muốn cô lập các kiến thức cần thiết để hoạt động theo một lớp vào chính lớp đó. Nếu bạn có một lớp như thế này, hoặc nó được sử dụng ở nhiều nơi, và do đó có thể thực hiện một số chức năng ở cả hai nơi đó, hoặc nó ở một nơi duy nhất, và phải là một lớp bên trong. Nếu nó được sử dụng theo nhiều cách, nhưng theo những cách hoàn toàn khác nhau, chẳng hạn như không có chức năng chia sẻ, có nó là một lớp duy nhất là gây hiểu lầm, chỉ ra một chức năng được chia sẻ mà không có.
Tuy nhiên, thường có những lý do cụ thể về nơi các quy tắc chung này có thể hoặc có thể không áp dụng, do đó, điều đó phụ thuộc vào những gì lớp học của bạn được cho là đại diện.
Tôi nghĩ rằng anh ấy có thể gây nhầm lẫn "không phải là rất OOP" vì thực hành không tốt. Tôi nghĩ anh ấy mong bạn cung cấp một số phương pháp mà mỗi người sẽ trả về 1 giá trị cần thiết (vì bạn sẽ phải sử dụng chúng trong lớp mới của bạn dù sao cũng không quá tệ).
Lưu ý rằng trong trường hợp này, có thể bạn không nên sử dụng getters/setters, chỉ cần đặt dữ liệu ở chế độ công khai. Không có điều này là "không phải là rất OOP" nhưng là đúng cách để làm điều đó.
Có thể Josh Bloch cung cấp một số thông tin chi tiết về số here này.
Lưu ý rằng có hai vấn đề riêng biệt ở đây.
Lớp học có cấu trúc "hợp lý" không?
Tạo một lớp để trả về nhiều giá trị từ một phương pháp có hợp lý không? lớp
Struct giống như
Một lớp đối tượng nên - cho hầu hết các phần - đại diện cho một lớp học của các đối tượng thực tế. Một hạt giống java thụ động, giống cấu trúc (tất cả các getters và setters) có thể đại diện cho một điều thực tế.
Tuy nhiên, hầu hết mọi thứ trong thế giới thực đều có quy tắc, ràng buộc, hành vi và động từ cơ bản mà chúng tham gia. Một lớp cấu trúc giống như hiếm khi là một kết hợp tốt cho một điều thế giới thực, nó thường là một số điều kỹ thuật. Điều đó làm cho nó ít hơn thiết kế OO lý tưởng.
Nhiều lợi nhuận từ một phương pháp
Trong khi Python có này, Java thì không. Nhiều giá trị trả lại không phải là câu hỏi OO, mỗi se. Đó là một câu hỏi làm việc thông qua các hạn chế ngôn ngữ.
Nhiều giá trị trả về có thể có nghĩa là một đối tượng đã thay đổi trạng thái. Có lẽ một phương pháp thay đổi trạng thái và một số nhóm getters trả về các giá trị xuất phát từ sự thay đổi trạng thái này.
Python không thực sự cho phép nhiều giá trị trả về, nó kết thúc thành một kiểu, tuple và cho phép bộ/danh sách được gán cho nhiều biến trong một câu lệnh. –
@he_the_great: trong khi sự thật, đó là một sự phân biệt rất tinh tế như hầu như không có giá trị cho tình huống này. Vấn đề ở đây là một trong những hạn chế về thiết kế OO và Java. Python là OO nhưng có cách tiếp cận khác với một số thứ. –
Thành thật mà nói, nó có vẻ ổn với tôi. Người đánh giá đề xuất thay thế nào?
Theo dõi OOP "thực tiễn tốt nhất" và tất cả đều ổn, nhưng bạn phải thực dụng và thực sự hoàn thành công việc.
Sử dụng các đối tượng giá trị như thế này (OO nói cho 'struct') là một cách tiếp cận hoàn toàn hợp pháp trong một số trường hợp.
- 1. Sao chép một cấu trúc sang một cấu trúc khác
- 2. JSF sao lưu cấu trúc đậu (thực hành tốt nhất)
- 3. Phạm vi lớp typedef thực hành xấu?
- 4. Sử dụng cấu trúc C trong Java
- 5. Tại sao mọi người tạo cấu trúc thư mục như edu.mit.stk trong Java?
- 6. Là typedef bên trong của một cơ quan chức năng một thực hành lập trình xấu?
- 7. Đang cố gắng bắt chước một giao diện/lớp trừu tượng trong thực hành javascript xấu
- 8. Thực hiện hàng đợi C bằng cách sử dụng void * - thực hành tốt hay xấu?
- 9. Làm thế nào để thực hiện cấu trúc này như là một lớp mà không có con trỏ trong C#?
- 10. Tại sao nó xấu để sử dụng một biến lặp trong một biểu thức lambda
- 11. Breaking the Build, Tại sao nó là một điều xấu?
- 12. Tại sao Void cấu trúc?
- 13. Tại sao lại sử dụng các tác dụng phụ xấu trong các nhà xây dựng JavaScript?
- 14. Hủy bỏ một chủ đề bằng cách sử dụng pthread_cancel: tốt thực hành hoặc xấu
- 15. Có sử dụng dấu ngắt có ghi là một thực hành tốt trong Java không?
- 16. Tại sao cấu trúc không được quản lý không phải là thành viên của một lớp được quản lý?
- 17. Có sử dụng các lớp CSS để đánh dấu JS là một thực hành không tốt?
- 18. Tại sao LinkedList trong Java không phải là một Danh sách Liên kết thực sự?
- 19. Mẹo của bạn để thực hành tốt nhất cho cấu trúc ứng dụng web là gì?
- 20. Giữ lại chu kỳ: Tại sao điều xấu như vậy?
- 21. Việc sử dụng tạo một hàm tạo cho một lớp trừu tượng trong Java là gì?
- 22. Tại sao Objective-C sử dụng tệp tiêu đề thay vì các lớp một tệp như Java?
- 23. Tại sao String là một lớp học?
- 24. là một thực hành tốt để sử dụng mysql_free_result ($ result)?
- 25. Tại sao Cấu trúc tĩnh không được phép trong C#?
- 26. Nếu cấu trúc không thể kế thừa một lớp hoặc cấu trúc khác, tại sao Int32 có một phương thức ToString()?
- 27. Tại sao '//' kiểu nhận xét nhiều dòng (xấu trong Java)?
- 28. Bạn có thể sử dụng các biến cục bộ luồng trong một lớp hoặc cấu trúc
- 29. Tạo cấu trúc dữ liệu như cấu trúc dữ liệu trong Java
- 30. Sao chép tập tin với cấu trúc chính xác vào một thư mục sử dụng Xcopy
Mặc dù tôi không nhất thiết không đồng ý với phân chia "trạng thái" so với "chức năng" của lớp học, tôi cảm thấy cần phải chỉ ra rằng đây là việc lấy OO ra khỏi OO. – Zarkonnen
Tôi nghĩ ý tưởng chung đằng sau sự tách biệt này là tránh quá tải một đối tượng có chức năng noncore và thay vào đó hãy nghĩ đến những loại "functors" như là các lớp. – Uri
Tôi sẽ chỉ sử dụng cấu trúc khi các trường/thuộc tính không phải là loại tham chiếu. Bằng cách này, truyền dữ liệu dưới dạng tham số, phương thức được gọi sẽ nhận được một bản sao của dữ liệu thay vì một tham chiếu (giống như thể hiện của một lớp) và không thể thay đổi dữ liệu gốc. Vì vậy, việc tái sử dụng cùng một cá thể struct trên nhiều cuộc gọi sẽ không ảnh hưởng lẫn nhau. Ví dụ tốt về cấu trúc có thể giống như: Vector (là tập hợp các phao hiển thị một véc tơ) –