2013-05-14 14 views
8

Używam platformy zarządzania jakością Sonar od jakiegoś czasu, aw większości przypadków uważam, że jest ona bardzo pomocna w ujawnianiu ukrytych wad projektowych mojej bazy kodu.Czy wszystkie odniesienia cykliczne między pakietami Java są złe?

Jednak istnieje jedna zasada, która daje mi więcej irytacji niż pomocy, i jest to sprawdzanie naruszeń "cyklicznych odwołań do pakietu".

Sądzę, że w pełni rozumiem, gdzie taka depedencja między pacakami jest zła. Na przykład w typowym trójwarstwowym layoucie prezentacji/usługi/trwałości, prawie zawsze jest złym pomysłem, aby kod obsługi bazy danych miał odniesienie do klas powiązanych z UI. Nie mam problemu z nazwaniem go "naruszeniem".

Ale rozważmy inne przypadki, np. Projektowanie aplikacji typu IDE. Powiedzmy, że mamy pakiet główny, który zawiera interfejs Application, który definiuje List Application.getViews() metodę odwoływania się do widoków aplikacji.

Jednak gdy Zobacz interfejs ma Application getApplication() sposób odnieść z powrotem do aplikacji nadrzędnej, która moim zdaniem jest to dość powszechne projekt, będzie to wprowadzenie cyklicznego odniesienia, o ile każdy z interfejsów są oddzielone odpowiednio com.myapp.ui i com.myapp.ui.view.

Oczywiście, można po prostu umieścić Zobacz interfejs do com.myapp.ui przerwać cykl. Ale kiedy masz różne inne View Related APIS w com.myapp.ui.view, wiele z nich kolejne abstrakcyjne API jak AbstractView, contentView, AbstractContentView, itp, zastanawiam się, czy jest to bardziej wskazane, aby je zachować w osobnych pakietach dla celów zarządzania.

I rozważyć wspomnianą aplikację ma wiele innych podobnych przypadków, takich jak com.myapp.ui.action, com.myapp.ui.perspective, itp, które naprawdę com.myapp.ui pacakge zatłoczone jeśli mamy je wszystkie tam umieścić.

Jakie podejście sugerujesz, aby poradzić sobie z taką sytuacją? Czy naprawdę każdy pakiet cykliczny odnosi się do czegoś złego? A jeśli muszę z nimi żyć, jak skonfigurować Sonar, aby sprawdzał tylko rzeczywiste, problematyczne cykle?

Dzięki!

Odpowiedz

6

Każdy absolut - poza tym;) - będzie przez jakiś czas niesłuszny. Czy każdy cykliczny odnośnik jest zły? Nie. Musisz użyć swojego osądu.

Ale jeśli wprowadzisz cykliczną zależność, warto zapytać, czy naprawdę jej potrzebujesz i dlaczego. Często zdarza się, że złamanie cyklu może poprawić twoją modułowość, a w szczególności zdolność do testowania komponentów oddzielnie.

Aby użyć tego przykładu, czy widok naprawdę potrzebuje getApplication(), który prawdopodobnie zwraca stosunkowo "ciężki" obiekt (tj. Taki, który sam potrzebuje bazy danych, sieci itp.)? Może ... ale może nie.Jeśli to, czego naprawdę potrzebujesz od tego getApplication jest czymś z kilkoma wywołań zwrotnych (np. Gdy użytkownik inicjuje jakąś akcję), może być przydatne utworzenie interfejsu w jakimś typowym pakiecie dla tego wywołania zwrotnego. Tak więc, zamiast:

com.foo.app.Application 
com.foo.view.View 
    Application getApplication() 

Musiałbyś:

com.foo.common.Callback // maybe just a Callable, Runnable, etc? 
com.foo.app.Application 
    provides a Callback for some action foo 
com.foo.view.View 
    Callback getFooCallback() 

Pytanie powinno być pytanie brzmi: co to ma mi dać? Może być tak, że musisz tak bardzo się ubrudzić, że nie daje ci zbyt wiele - choć może to sugerować, że możesz rozdzielić niektóre klasy. Ale może być tak, że w rzeczywistości ułatwia to przetestowanie twojego widoku, ponieważ teraz twój test jednostki może (1) przetestować widok bez obracania całej aplikacji i (b) dostarczyć "fałszywego" wywołania zwrotnego, które robi coś takiego jak zapisywanie ciąg opisujący akcję, a następnie test jednostki potwierdza, że ​​zapisano właściwy ciąg znaków.

+0

Pozwól mi spróbuj wymyślić przypadek gdzie View.getApplication() może być uzasadnione. Przypuszczam, że może to być powszechny wymóg, aby widok odwoływał się do innych zasobów zwykle związanych z aplikacją, takich jak pakiet wiadomości i18n lub źródło danych JDBC itp. Może wszyscy możemy je uporządkować w sposób dwukierunkowy, ale wierzę, że Definicja, widok w tym przypadku jest częścią złożonej całości, której nie można myśleć w oddzielnym kontekście. Tak więc źródło danych JDBC nie może być arbitralne, ale takie, które zapewnia jego aplikacja nadrzędna. czy nie byłoby bardziej oczywiste, aby pokazać takie zależności w projektowaniu? – mysticfall

Powiązane problemy