Khi nào sử dụng một biến thể hiện đối tượng thay vì truyền một đối số cho phương thức


93

Làm thế nào để bạn quyết định giữa việc truyền các đối số cho một phương thức so với việc chỉ khai báo chúng dưới dạng các biến cá thể đối tượng hiển thị cho tất cả các phương thức của đối tượng?

Tôi thích giữ các biến cá thể trong một danh sách ở cuối Lớp, nhưng danh sách này sẽ dài hơn khi chương trình của tôi phát triển. Tôi nghĩ rằng nếu một biến được truyền đủ thường xuyên thì nó sẽ hiển thị cho tất cả các phương thức cần nó, nhưng sau đó tôi tự hỏi, "nếu mọi thứ là công khai thì sẽ không cần truyền bất cứ thứ gì cả!"


1
Nếu bạn có một ví dụ cụ thể, bạn có thể nhận trực tiếp câu trả lời hữu ích hơn
brabster

Câu trả lời:


55

Vì bạn đang đề cập đến các biến cá thể, tôi giả sử rằng bạn đang làm việc trong một ngôn ngữ hướng đối tượng. Ở một mức độ nào đó, khi nào sử dụng biến cá thể, cách xác định phạm vi của chúng và khi nào sử dụng biến cục bộ là chủ quan, nhưng có một số quy tắc bạn có thể tuân theo bất cứ khi nào tạo lớp của mình.

  • Các biến cá thể thường được coi là thuộc tính của một lớp. Hãy coi đây là những tính từ của đối tượng sẽ được tạo ra từ lớp của bạn. Nếu dữ liệu cá thể của bạn có thể được sử dụng để giúp mô tả đối tượng, thì có thể an toàn để đặt cược rằng đó là một lựa chọn tốt cho dữ liệu cá thể.

  • Các biến cục bộ được sử dụng trong phạm vi của các phương pháp để giúp chúng hoàn thành công việc của mình. Thông thường, một phương thức phải có mục đích lấy một số dữ liệu, trả về một số dữ liệu và / hoặc xử lý / chạy một thuật toán trên một số dữ liệu. Đôi khi, việc coi các biến cục bộ là cách giúp một phương pháp đi từ đầu đến cuối sẽ hữu ích.

  • Phạm vi biến phiên bản không chỉ dành cho bảo mật mà còn để đóng gói. Đừng cho rằng "mục tiêu phải là giữ cho tất cả các biến ở chế độ riêng tư." Trong trường hợp kế thừa, tạo các biến dưới dạng bảo vệ thường là một lựa chọn thay thế tốt. Thay vì đánh dấu tất cả dữ liệu cá thể là công khai, bạn tạo getters / setters cho những dữ liệu cần được truy cập ra thế giới bên ngoài. Đừng cung cấp tất cả chúng - chỉ những thứ bạn cần. Điều này sẽ xảy ra trong suốt vòng đời phát triển - thật khó đoán ngay từ đầu.

Khi nói đến việc truyền dữ liệu xung quanh một lớp, thật khó để nói rằng những gì bạn đang làm là thực hành tốt mà không cần xem một số mã. Đôi khi, hoạt động trực tiếp trên dữ liệu cá thể là tốt; những lần khác, nó không phải. Theo tôi, đây là điều đi kèm với kinh nghiệm - bạn sẽ phát triển một số trực giác khi kỹ năng tư duy hướng đối tượng của bạn được cải thiện.


Câu trả lời của tôi sẽ thêm câu trả lời này vào câu trả lời H-Man2 (trọn đời). Nó phải là một thuộc tính thành viên nếu và chỉ khi nó là một trạng thái liên tục của đối tượng. Có nghĩa là, giá trị có ý nghĩa tự nó nằm ngoài phạm vi của ngăn xếp phương thức hiện tại.
David Rodríguez - dribeas

Phản ứng của tôi là đồng ý với David và H-MAn2. Tuy nhiên, tôi đang đọc "mã sạch" của Robert c Martin và trong chương 3, anh ta đã cấu trúc lại mã để chuyển một cái gì đó từ một tham số phương thức sang một biến thành viên, bởi vì có nhiều tham số là không tốt. Về cân bằng, tôi đoán nếu lớp của bạn chỉ có một trách nhiệm duy nhất thì thời gian tồn tại của đối tượng cũng giống như thời gian tồn tại của phép tính đó, vì vậy có thể câu trả lời thực tế là nếu bạn phải hỏi câu hỏi này thì lớp của bạn quá lớn?
Andy

@ DavidRodríguez-dribeas Ý bạn là gì về ngăn xếp phương pháp?
committedandroider

@comiledandroider: nếu giá trị tồn tại lâu hơn lệnh gọi hàm hiện tại
David Rodríguez - dribeas

46

Điều này chủ yếu phụ thuộc vào thời gian tồn tại của dữ liệu bạn lưu trữ trong biến. Nếu dữ liệu chỉ được sử dụng trong quá trình tính toán, hãy chuyển nó làm tham số. Nếu dữ liệu được ràng buộc với thời gian tồn tại của đối tượng, hãy sử dụng một biến thể hiện.

Khi danh sách các biến của bạn quá dài, có lẽ bạn nên nghĩ đến việc cấu trúc lại một số phần của lớp thành một lớp mới.


21

Theo ý kiến ​​của tôi, các biến cá thể chỉ cần thiết khi dữ liệu sẽ được sử dụng trên các cuộc gọi.

Đây là một ví dụ:

myCircle = myDrawing.drawCircle(center, radius);

Bây giờ cho phép tạo ảnh lớp myDrawing sử dụng 15 hàm trợ giúp để tạo đối tượng myCircle và mỗi hàm đó sẽ cần tâm và bán kính. Chúng vẫn không nên được đặt làm biến cá thể của lớp myDrawing. Bởi vì chúng sẽ không bao giờ cần thiết nữa.

Mặt khác, lớp myCircle sẽ cần lưu trữ cả tâm và bán kính dưới dạng các biến thể hiện.

myCircle.move(newCenter);
myCircle.resize(newRadius);

Để đối tượng myCircle biết được bán kính và tâm của nó khi các lệnh gọi mới này được thực hiện, chúng cần được lưu trữ dưới dạng các biến thể hiện, chứ không chỉ được truyền cho các hàm cần chúng.

Vì vậy, về cơ bản, biến cá thể là một cách để lưu "trạng thái" của một đối tượng. Nếu một biến không cần thiết để biết trạng thái của một đối tượng, thì nó không nên là một biến thể hiện.

Và đối với việc công khai mọi thứ. Nó có thể làm cho cuộc sống của bạn dễ dàng hơn trong thời điểm này. Nhưng nó sẽ quay lại ám ảnh bạn. Pease đừng.


Tuy nhiên, bạn chỉ có thể xác định chuyển để sử dụng các tham số (oldCenter, newCenter).
obesechicken 13

4

IMHO:

Nếu biến tạo thành một phần của trạng thái của cá thể, thì nó phải là một biến thể hiện - classinstance HAS-A instancevariable.

Nếu tôi thấy mình chuyển một cái gì đó liên tục vào các phương thức của một phiên bản hoặc tôi thấy rằng tôi có một số lượng lớn các biến phiên bản, tôi có thể sẽ thử và xem xét thiết kế của mình trong trường hợp tôi bỏ sót một cái gì đó hoặc tạo ra một sự trừu tượng không tốt ở đâu đó.

Hy vọng nó giúp


3

Tất nhiên, thật dễ dàng để giữ một danh sách lớn các biến công khai trong lớp. Nhưng ngay cả bằng trực giác, bạn cũng có thể biết rằng đây không phải là cách để đi.

Xác định từng biến ngay trước khi bạn sử dụng nó. Nếu một biến hỗ trợ chức năng của một phương thức cụ thể, chỉ sử dụng nó trong phạm vi của phương thức.

Cũng hãy nghĩ về bảo mật, một biến lớp công khai dễ bị thay đổi không mong muốn từ mã "bên ngoài". Mục tiêu chính của bạn phải là giữ cho tất cả các biến ở chế độ riêng tư và bất kỳ biến nào không phải, đều phải có lý do chính đáng để làm như vậy.

Về việc chuyển tất cả các tham số lên ngăn xếp, điều này có thể trở nên xấu đi rất nhanh. Một nguyên tắc chung là giữ cho chữ ký phương pháp của bạn sạch sẽ và trang nhã. Nếu bạn thấy nhiều phương thức sử dụng cùng một dữ liệu, hãy quyết định xem nó có đủ quan trọng để trở thành thành viên lớp hay không, và nếu không, hãy cấu trúc lại mã của bạn để nó có ý nghĩa hơn.

Nó tổng hợp thành lẽ thường. Hãy suy nghĩ chính xác vị trí và lý do bạn khai báo mỗi biến mới, chức năng của nó là gì, và từ đó đưa ra quyết định về phạm vi mà nó sẽ tồn tại.


Bạn thường muốn các phương pháp được công khai để bạn có thể kiểm tra đơn vị chúng.
obesechicken 13
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.