Zacząłem refaktoryzować aplikację napisaną w C# (WinForms) i zastanawiałem się jak rozsądnie podzielić prace i sam kod.
Niestety nie mam doświadczenia jak podejść do tego tematu i wydaje się dość trudny.
Obecnie cała logika a dodatkowo tworzenie/zarządzanie wątkami jest w jednej klasie a dokładniej MainForm.cs.
Czyli w jednym pliku mamy:
- około 9 tys. linii kodu
- wątki, które mają współdzielone zasoby bez żadnych locków
- locki przy zapytaniach do bazy danych, bo współdzielone jest połączenie do bazy danych
- locki przy komunikacji z urządzeniami, które są zbędne
Architektura wygląda tak, że mamy (od dołu):
- modele z bazy danych
- coś w stylu UberGigaDataProvider.cs, który zapisuje i odczytuje modele z bazy danych
- coś w stylu UberGigaService.cs, które robi wszystko co chcemy przy użyciu modeli i UberGigaDataProvider.cs
- MainForm.cs, która używa UberGigaService.cs, UberGigaDataProvider.cs i swojej logiki do wykonania określonego zadania
Co robi FormMain.cs:
- wyświetla dane i statystyki z urządzeń
- tworzy wątek, który pisze do bazy, że aplikacja działa
- tworzy wątek, który obsługuje zdarzenia z bazy danych np. programuj urządzenia, przerwij odczyt z urządzeń, wykonaj akcje x na urządzeniach
- tworzy np. 10 wątków, które np. odczytują dane z urządzeń, zapisują do bazy danych i programują urządzenia
Obecnie co zrobiłem:
- wyciągnąłem metody, które były niezwiązane z MainForm.cs do osobnych klas - pozwoliło to zredukować plik do około ~5 tys. linii kodu
- usunąłem locki - ma to na celu, aby każdy wątek miał swoją instancję UberGigaDataProvider.cs i UberGigaService.cs
Dalej chciałbym:
- stworzyć prostą klasę abstrakcyjną np. BaseThreadManager (albo sam interfejs, który będzie punktem startowym wątku i zarządzać nim z innego poziomu), która będzie hermetyzować proces tworzenia, startu i zatrzymania wątku z abstrakcyjną metodą ThreadFn (ta metoda to po prostu funkcja startu wątku)
- dla każdego typu wątku stworzyć nową klasę np. LifeThreadManager, która będzie dziedziczyć po BaseThreadManager i tam będzie cały proces obsługi pisania do bazy danych
- dalej np. ReadThreadManager, która będzie cały czas odczytywać dane z urządzeń (chociaż ta klasa będzie musiała być inna, bo będzie zarządzać pulą wątków, a nie tylko jednym wątkiem)
- dalej np. EventThreadManager która będzie dziedziczyć po BaseThreadManager i będzie tam cały proces obsługi zdarzeń z bazy danych
Zastanawiam się, w jaki sposób zrobić obsługę tych zdarzeń z EventThreadManager.
Myślałem żeby zrobić dodatkową fasadę, która będzie reagowała na zdarzenia z EventThreadManager i zarządzała klasami ReadThreadManager, LifeThreadManager a dodatkowo wypuszczała zdarzenia do kontrolek np. poprzez eventy.
Celem jest ogólna poprawa programu.
Chcę to zrobić prosto i spróbować uniknąć over-engineeringu.
Pytanie, czy idę w dobrą stronę?
Thread.currentThread()
. (to taka libka która umie podmienić implementacje metod statycznych).