Jestem w projekcie systemu rozproszonego napisanym w Javie, w którym mamy klasy odpowiadające bardzo złożonym obiektom biznesowym w świecie rzeczywistym. Obiekty te mają wiele metod odpowiadających działaniom, które użytkownik (lub inny agent) może zastosować do tych obiektów. W rezultacie klasy te stały się bardzo złożone.
Ogólne podejście do architektury systemu doprowadziło do wielu zachowań skoncentrowanych na kilku klasach i wielu możliwych scenariuszach interakcji.
Jako przykład i dla jasności, powiedzmy, że Robot i Samochód były zajęciami w moim projekcie.
Tak więc w klasie Robot miałbym wiele metod według następującego wzoru:
- sen(); isSleepAvaliable ();
- obudzić(); isAwakeAvaliable ();
- spacer (kierunek); isWalkAvaliable ();
- strzelanie (kierunek); isShootAvaliable ();
- turnOnAlert (); isTurnOnAlertAvailable ();
- turnOffAlert (); isTurnOffAlertAvailable ();
- ładowanie (); isRechargeAvailable ();
- powerOff (); isPowerOffAvailable ();
- stepInCar (samochód); isStepInCarAvailable ();
- stepOutCar (samochód); isStepOutCarAvailable ();
- samozniszczenia(); isSelfDestructAvailable ();
- umierać(); isDieAvailable ();
- żyje(); jest obudzony(); isAlertOn (); getBatteryLevel (); getCurrentRidingCar (); getAmmo ();
- ...
W klasie samochodów byłoby podobnie:
- włączyć(); isTurnOnAvaliable ();
- wyłączyć(); isTurnOffAvaliable ();
- spacer (kierunek); isWalkAvaliable ();
- tankować(); isRefuelAvailable ();
- samozniszczenia(); isSelfDestructAvailable ();
- wypadek(); isCrashAvailable ();
- isOperational (); isOn (); getFuelLevel (); getCurrentPassenger ();
- ...
Każdy z nich (Robot i samochód) jest zaimplementowany jako maszyna stanu, w której niektóre działania są możliwe w niektórych stanach, a niektóre nie. Akcje zmieniają stan obiektu. Metody akcji rzucają, IllegalStateException
gdy są wywoływane w niepoprawnym stanie, a isXXXAvailable()
metody informują, czy akcja jest możliwa w danym momencie. Chociaż niektórych można łatwo wydedukować ze stanu (np. W stanie uśpienia dostępna jest funkcja czuwania), niektóre nie są (aby strzelać, musi być przebudzona, żywa, mając amunicję i nie jeżdżąc samochodem).
Co więcej, interakcje między obiektami są również złożone. Na przykład samochód może pomieścić tylko jednego pasażera robota, więc jeśli inny spróbuje wsiąść, należy zgłosić wyjątek; W przypadku awarii samochodu pasażer powinien umrzeć; Jeśli robot nie żyje w pojeździe, nie może wyjść, nawet jeśli sam Samochód jest w porządku; Jeśli robot jest w samochodzie, nie może wejść do innego przed wysiadaniem; itp.
Wynikiem tego jest, jak już powiedziałem, zajęcia te stały się naprawdę złożone. Co gorsza, istnieją setki możliwych scenariuszy interakcji Robota i Samochodu. Ponadto znaczna część tej logiki wymaga dostępu do zdalnych danych w innych systemach. W rezultacie testy jednostkowe stały się bardzo trudne i mamy wiele problemów z testowaniem, z których jeden powoduje drugie w błędnym kole:
- Konfiguracje przypadków testowych są bardzo złożone, ponieważ muszą stworzyć znacznie bardziej złożony świat do ćwiczeń.
- Liczba testów jest ogromna.
- Uruchomienie zestawu testowego zajmuje kilka godzin.
- Nasz zasięg testów jest bardzo niski.
- Kod testowy ma tendencję do pisania tygodni lub miesięcy później niż kod, który testuje lub wcale.
- Wiele testów jest również zepsutych, głównie dlatego, że zmieniły się wymagania testowanego kodu.
- Niektóre scenariusze są tak złożone, że przekroczą limit czasu podczas instalacji (skonfigurowaliśmy limit czasu w każdym teście, w najgorszych przypadkach 2 minuty, a nawet tak długo, limity czasu zapewniły, że nie jest to nieskończona pętla).
- Błędy regularnie wpadają do środowiska produkcyjnego.
Ten scenariusz robota i samochodu to rażące nadmierne uproszczenie tego, co mamy w rzeczywistości. Oczywiście ta sytuacja nie jest możliwa do opanowania. Proszę więc o pomoc i sugestie dotyczące: 1, Zmniejszenia złożoności zajęć; 2. Uprość scenariusze interakcji między moimi obiektami; 3. Skróć czas testu i ilość kodu do przetestowania.
EDYCJA:
Myślę, że nie miałem jasności co do automatów państwowych. Robot sam jest maszyną stanową, a stany „śpią”, „budzą się”, „ładują”, „martwe” itp. Samochód to kolejna maszyna stanowa.
EDYCJA 2: W przypadku, gdy jesteś ciekawy, czym naprawdę jest mój system, klasy, które oddziałują, to takie jak Serwer, Adres IP, Dysk, Kopia zapasowa, Użytkownik, Licencja oprogramowania, itd. Scenariusz Robot i samochód to tylko przypadek, który znalazłem to byłoby wystarczająco proste, aby wyjaśnić mój problem.