Làm thế nào để giải quyết các phụ thuộc gói tròn


11

Tôi đang cấu trúc lại một cơ sở mã lớn trong đó hầu hết các lớp được đặt trong một gói. Để mô đun hóa tốt hơn, tôi đang tạo các gói con cho từng chức năng.

Tôi nhớ rằng đã học ở đâu đó rằng biểu đồ phụ thuộc gói không nên có các vòng lặp, nhưng tôi không biết cách giải quyết vấn đề sau: Figurelà trong gói figure, Layoutlà trong gói layout, Layoutyêu cầu hình để thực hiện bố cục, vì vậy gói layoutphụ thuộc vào gói figure. Nhưng mặt khác, một cái Figurecó thể chứa các Figures khác bên trong nó, có cái riêng của nó Layout, làm cho gói figurephụ thuộc vào gói layout.

Tôi có một số giải pháp, như tạo một Containergiao diện Figurethực hiện và đặt nó trong Layoutgói. Đây có phải là một giải pháp tốt? Còn khả năng nào khác không?

Cảm ơn


Đó là các mô-đun (ví dụ: các lọ khác nhau) không thể có phụ thuộc vòng tròn. Các gói CÓ THỂ và thường CÓ các khoản giảm giá tròn, miễn là chúng thuộc cùng một mô-đun.
điệp khúc

@lorus Vậy đây không phải là vấn đề thiết kế?
vainolo

2
Không có nó không phải là. Các gói thường chỉ là một không gian tên. Điều này chỉ có thể thay đổi khi chúng được sử dụng cho mục đích khác, ví dụ: để thay đổi mức độ hiển thị nội dung của chúng trong môi trường OSGi. Đừng bận tâm khác.
điệp khúc

1
Lưu ý rằng nhiều nhà chức trách lên án sự phụ thuộc theo chu kỳ và đôi khi có lý do chính đáng, nhưng trước khi bạn tái cấu trúc một cách mù quáng, bạn nên đảm bảo một trong những lý do đó thực sự áp dụng cho bạn. Nếu cấu trúc gói không gây rắc rối cho bạn, và trong lương tâm tốt, bạn có thể thấy, tại sao trong tương lai, đừng thay đổi thứ gì đó rất cơ bản chỉ để đáp ứng các giá trị kiến ​​trúc trừu tượng.
Kilian Foth

Câu trả lời:


9

Bạn nên nghĩ về Inversion of Control

Về cơ bản, bạn xác định một giao diện cho giao diện của bạn Layoutnằm ở đâu đó gần lớp Bố cục của bạn trong một gói riêng để bạn có gói triển khai và gói giao diện công cộng - ví dụ: gọi nó Layoutable(tôi không biết đó có phải là tiếng Anh đúng không). Bây giờ - Giao diện sẽ không thực hiện giao diện đó nhưng Figurelớp. Tương tự như vậy, bạn sẽ tạo một giao diện cho Hình đó Drawablechẳng hạn.

Vì thế

my.public.package.Layoutable
my.implementation.package.Layout
my.public.package.Drawable
my.implementation.package.Figure

Bây giờ - Hình thực hiện Bố cục và do đó có thể được Bố cục sử dụng và (Tôi chưa chắc đó có phải là điều bạn muốn không) - Bố cục thực hiện Drawable và có thể được vẽ trong Hình. Vấn đề là, lớp phơi bày một số dịch vụ làm cho nó có sẵn bởi một giao diện (ở đây: Bố cục và Bố cục) - lớp muốn sử dụng dịch vụ đó phải thực hiện giao diện.

Sau đó, bạn sẽ có một cái gì đó giống như một đối tượng người sáng tạo gắn kết cả hai lại với nhau. Vì vậy, các tác giả sẽ có một sự phụ thuộc tới Layoutcũng như để Figure, nhưng LayoutFiguremình sẽ độc lập.

Đó là ý tưởng sơ bộ.

Một nguồn tuyệt vời cho các giải pháp cho vấn đề này là cuốn sách Kiến trúc ứng dụng Java của Kirk Knoernschild.


Đây không phải là giống như Containergiao diện như được đề xuất trong câu hỏi?
vaughandroid

Có - và không - Tôi sẽ không đặt cả hai trong cùng một gói như tôi đã nêu. Và không có nhiều lý thuyết đằng sau nó. Và trong trường hợp này không đủ để làm điều đó một bên, bạn sẽ phải làm điều đó ở cả hai bên. Ổn thỏa?
michael_s

Rất tiếc, tôi đã bỏ lỡ một chút trong câu hỏi ban đầu về việc Containerđi trong cùng một gói như Layout. Điều đó sẽ không làm việc, trong khi giải pháp của bạn sẽ.
vaughandroid

ah - ok - Tôi dường như đã bỏ lỡ phần với Container mặc dù khi tôi hack - nên đã đặt tên cho nó là Container;)
michael_s

0

Tôi không quá rõ ràng về những gì a Figure, nhưng có lẽ nó nên ở trong cùng một gói với Layout?

ContainerGiải pháp giao diện được đề xuất của bạn sẽ không hoạt động - trừ khi bạn đặt Containergiao diện vào gói thứ 3 thì bạn vẫn sẽ có sự phụ thuộc vòng tròn giữa hai gói. Xem câu trả lời của michael_s cho một cái gì đó sẽ làm việc.

Một điều khác, như những người khác đã đề cập - nó có thể sẽ không bao giờ là một vấn đề. Bạn sẽ chỉ gặp vấn đề trong tương lai nếu FigureLayoutmuốn ở trong các mô-đun riêng biệt . Bạn có thể đối phó với điều này nếu và khi điều đó trở nên cần thiết, nhưng với điều kiện hai lớp có vẻ liên quan khá chặt chẽ thì điều này dường như rất khó xảy ra.

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.