2008-11-23 33 views
13

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

14

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.

+0

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

+0

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

+0

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ơ) –

1

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.

0

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 đó.

0

Có thể Josh Bloch cung cấp một số thông tin chi tiết về số here này.

4

Lưu ý rằng có hai vấn đề riêng biệt ở đây.

  1. Lớp học có cấu trúc "hợp lý" không?

  2. 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.

+0

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. –

+0

@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ứ. –

3

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.

Các vấn đề liên quan