Các lớp lồng nhau được đánh giá thấp?


9

Tôi không cố nói rằng tôi biết một số thứ mà mọi người khác không biết nhưng tôi đã giải quyết ngày càng nhiều thiết kế hơn bằng cách sử dụng các lớp lồng nhau, vì vậy tôi tò mò muốn có cảm giác chấp nhận sử dụng thứ dường như hiếm khi được sử dụng này cơ chế thiết kế.

Điều này dẫn tôi đến câu hỏi: tôi đang đi xuống một con đường xấu vốn có vì những lý do tôi sẽ khám phá khi họ quay lại cắn tôi, hoặc các lớp lồng nhau có thể là thứ gì đó bị đánh giá thấp?

Đây là hai ví dụ tôi vừa sử dụng chúng cho: https://gist.github.com/3975581 - lần đầu tiên giúp tôi giữ chặt những thứ bá đạo cùng nhau, lần thứ hai cho phép tôi tiếp cận với các thành viên được bảo vệ cho công nhân ...


Tôi chỉ muốn nói cảm ơn về câu trả lời / thông tin chi tiết - Tôi không biết cách chọn câu trả lời vì vậy tôi sẽ bỏ qua trong khi tôi xem xét lời khuyên tôi nhận được và xem lại ...
Aaron Anodide

Câu trả lời:


6

Tôi sẽ không gọi đây là "cơ chế thiết kế hiếm khi được sử dụng" - ít nhất, không phổ biến: mặc dù có những cửa hàng mà một số người đóng góp có thể nhăn mặt khi sử dụng các lớp lồng nhau, đây hoàn toàn không phải là một tính năng tối nghĩa.

Mặc dù sự tồn tại của các lớp với khả năng hiển thị lắp ráp và giới thiệu lambdas đã làm giảm đáng kể nhu cầu đối với các lớp lồng nhau * , chúng vẫn là một lựa chọn thiết kế hợp lệ. Mặc dù có một số trùng lặp với các lớp bên trong trong một không gian tên, tính năng các lớp lồng nhau là duy nhất trong việc cho phép bạn ẩn một lớp hoàn toàn bên trong một lớp khác.


* Việc sử dụng một tính năng tương tự trong Java cao hơn nhiều, vì các lựa chọn thay thế khác có sẵn trong C # không có trong Java.


Vì vậy, có tốt không khi ẩn một lớp hoàn toàn trong một lớp khác theo bản chất của thiết kế OOP?
Maxood

1
@Maxood Thật tốt khi ẩn một lớp nếu bạn có thể ẩn nó. Người dùng API của bạn nên biết càng ít càng tốt về cách triển khai API của bạn.
dasblinkenlight

3

Hãy xem xét một lúc rằng bạn đang viết một lớp bên trong một lớp khác, điều đó sẽ không bao giờ được sử dụng ở bất kỳ nơi nào khác trong chương trình của bạn. Bởi vì nếu bạn đang sử dụng nó ở nơi khác, bạn sẽ biến nó thành một lớp công khai bình thường, giống như tất cả những người khác.

Vì vậy, thứ được cho là làm cho OOP trở nên tuyệt vời (tái sử dụng) không có ở đây. Ngoài ra, bạn có thể đạt được gì với một lớp lồng mà bạn không thể đạt được bằng các phương thức thông thường và các thành viên riêng trong lớp cha?

Đối với một mẫu phần mềm hữu ích sử dụng các lớp lồng nhau, xem tại đây .


10
Tôi chưa bao giờ mua thứ tái sử dụng, ít nhất là cách nó thường được đặt. (1) Gọi vào mã / lớp hiện có (mà bạn dường như nói đến và tôi thường thấy là định nghĩa tái sử dụng) hoàn toàn không liên quan gì đến OOP, đó chỉ là mô đun cơ bản. (2) Đa hình con, là một đặc điểm xác định của OOP, cho phép tái sử dụng mã máy khách bằng cách thực hiện cụ thể không liên quan , nghĩa là nó hoạt động chính xác theo cách mà lớp cụ thể có thể truy cập được hay không. IOW đó là tái sử dụng tôi mua, nhưng nó cũng hoạt động với các lớp lồng nhau.

1
Tôi muốn nói cũng có cách nhiệt không gian tên do lớp cha cung cấp - vì vậy nếu bạn muốn, cả hai lớp A và B có thể có lớp "Params" lồng nhau và quyền truy cập vào các thành viên không công khai của lớp chứa. Cả hai lý do không có lớp bên trong được sử dụng bên ngoài lớp?
Aaron Anodide

@AaronAnodide Đó phải là một câu trả lời về một cách tốt để sử dụng các lớp lồng nhau. Đó chính xác là cách / lý do tại sao tôi sử dụng chúng, nó giúp tổ chức mã.
Izkata

2

am I going down an inherintly bad path

Tôi nghĩ trong ví dụ thứ hai của bạn (các lớp con worker) bạn chắc chắn là như vậy. Bạn đã ánh xạ mỗi lớp con đến một trạng thái cụ thể trong siêu lớp. Vì vậy, bây giờ mỗi lần bạn muốn thêm một trạng thái vào siêu lớp, bạn sẽ cần thực hiện thay đổi ở ba vị trí (thêm trạng thái vào siêu lớp, thêm một lớp con mới và thay đổi hàm tạo của lớp dẫn xuất để thêm lớp phụ vào danh sách ).

Việc sử dụng các lớp lồng nhau để truy cập các thành viên tư nhân dường như là một cách sử dụng hợp lệ (tôi chưa bao giờ tự mình thực hiện nó) nhưng trường hợp cụ thể của bạn không hoạt động ở đây.

Đối với ví dụ về phần cơ thể. Bởi vì tất cả các lớp lồng nhau là công khai, bạn không thực sự làm gì nhiều ngoài việc đặt tên. Nếu các lớp này phát triển để bao gồm nhiều chức năng hơn, bạn có thể thấy rằng các lớp lồng nhau chỉ làm lộn xộn các giao diện và bạn đang lọc qua mã để tìm thứ gì đó cụ thể. Tôi cũng nhận thấy rằng vì bạn có các lớp lồng nhau, bạn buộc phải phá vỡ các quy ước đặt tên và đặt tên cho các lớp của bạn với chữ thường (có thể đây là một lựa chọn). Nhưng những lập luận này hời hợt hơn bất cứ điều gì thực sự sai.

Trừ khi, tất nhiên, bạn cần phải thực hiện một cánh tay bị biến dạng. Sau đó, tạo ra một cánh tay bằng cách làm như sau là khó hiểu vì không có cơ thể / thân / bên. (Cũng chú ý vỏ bọc khó hiểu).

arm newArm = new Body.torso.side.arm("");

1

Lợi thế duy nhất tôi có thể nghĩ về các lớp lồng nhau là chúng có thể được đặt ở chế độ riêng tư (hoặc được bảo vệ). Tôi muốn nói trong trường hợp này các lớp lồng nhau có thể giúp bạn đóng gói chức năng nếu một lớp được dự định sẽ được sử dụng bởi lớp bên ngoài và lớp đó một mình.


1

Theo kinh nghiệm của tôi, các lớp lồng nhau

  • Trở lại ám ảnh tôi
  • Đã được sử dụng khi tôi muốn cắt góc
  • Thử nghiệm một cơn ác mộng
  • Có tác động tiêu cực đến việc tách mối quan tâm và thiết kế tổng thể

Có một cái nhìn ngắn gọn về lớp học của bạn, và ngay lập tức tôi nghĩ rằng:

  • Thật đau đớn khi nhìn vào nó bởi vì lớp học rất lớn
  • Tôi không thể kiểm tra "ngón tay" mà không tạo ra toàn bộ cơ thể
  • Tôi không thể có nhiều triển khai thân. Không có vẻ rõ ràng trong bối cảnh "cơ thể con người", nhưng trong một kịch bản khác, điều này sẽ trở nên rõ ràng.

Tại sao không tách lớp của bạn thành nhiều lớp và cung cấp cho chúng các không gian tên riêng biệt. Ví dụ

WindowsGame1.PhysicalModel.UpperBody
WindowsGame1.PhysicalModel.LowerBody
WindowsGame1.PhysicalModel.UpperBody.Arms
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.