Я в проекті розподіленої системи, написаному на Java, де у нас є кілька класів, що відповідають дуже складним об'єктам реального бізнесу. Ці об'єкти мають безліч методів, що відповідають діям, які користувач (або якийсь інший агент) може застосувати до цих об'єктів. В результаті ці заняття стали дуже складними.
Загальний підхід до архітектури системи спричинив багато поведінки, сконцентрованої на кількох класах, і безліч можливих сценаріїв взаємодії.
Як приклад, щоб зробити речі легкими та зрозумілими, скажімо, що Робот і Авто були моїми проектами.
Отже, у класі Robot у мене було б багато методів за такою схемою:
- сон (); isSleepAvaliable ();
- прокидатися (); isAwakeAvaliable ();
- прогулянка (напрямок); isWalkAvaliable ();
- стріляти (Напрям); isShootAvaliable ();
- turnOnAlert (); isTurnOnAlertAvailable ();
- turnOffAlert (); isTurnOffAlertAvailable ();
- заряджати (); isRechargeAvailable ();
- powerOff (); isPowerOffAvailable ();
- stepInCar (Автомобіль); isStepInCarAvailable ();
- stepOutCar (Автомобіль); isStepOutCarAvailable ();
- самознищення(); isSelfDestructAvailable ();
- die (); isDieAvailable ();
- живий(); isAwake (); isAlertOn (); getBatteryLevel (); getCurrentRidingCar (); getAmmo ();
- ...
У класі Car це було б так:
- ввімкнути(); isTurnOnAvaliable ();
- вимкнути(); isTurnOffAvaliable ();
- прогулянка (напрямок); isWalkAvaliable ();
- заправка (); isRefuelAvailable ();
- самознищення(); isSelfDestructAvailable ();
- крах (); isCrashAvailable ();
- isOperational (); isOn (); getFuelLevel (); getCurrentPassenger ();
- ...
Кожна з них (Робот і Автомобіль) реалізована як державна машина, де деякі дії можливі в деяких штатах, а деякі - ні. Дії змінюють стан об’єкта. Методи дії кидає, IllegalStateException
коли викликається в недійсному стані, і isXXXAvailable()
методи повідомляють, чи можлива дія в той час. Хоча деякі легко виводяться із штату (наприклад, у сплячому стані наявний режим пробудження), деякі - ні (щоб стріляти, він повинен бути неспаним, живим, боєприпасами та не їздить на машині).
Крім того, взаємодія між об'єктами теж є складною. Наприклад, автомобіль може утримувати лише одного пасажира-робота, тому якщо інший спробує в'їхати, слід викинути виняток; Якщо автомобіль врізається, пасажир повинен загинути; Якщо робот мертвий всередині транспортного засобу, він не може вийти, навіть якщо сама машина в порядку; Якщо Робот знаходиться в автомобілі, він не може увійти до іншого, перш ніж вийти; тощо.
Результатом цього, як я вже говорив, ці заняття стали справді складними. Що ще гірше, існує сотні можливих сценаріїв взаємодії Робота та Автомобіля. Крім того, велика частина цієї логіки дійсно потребує доступу до віддалених даних в інших системах. Результат полягає в тому, що тестування приладів стало дуже важким, і у нас багато проблем з тестуванням, одна викликала іншу в порочному колі:
- Налаштування тестів дуже складні, тому що їм потрібно створити значно складний світ для здійснення.
- Кількість тестів величезна.
- Набір тестів займає кілька годин.
- Покриття нашого тесту дуже низьке.
- Код тестування, як правило, пишеться на тижні чи місяці пізніше, ніж код, який вони перевіряють, або взагалі ніколи.
- Багато тестів теж порушено, головним чином через те, що вимоги до тестового коду змінилися.
- Деякі сценарії настільки складні, що вони не спрацьовують під час встановлення часу (ми налаштовували тайм-аут у кожному тесті, в гірших випадках - 2 хвилини і навіть цей час тривалий час, ми переконалися, що це не нескінченний цикл).
- Клопи регулярно ковзають у виробничі умови.
Цей сценарій роботи і автомобіля - це грубе надмірне спрощення того, що ми маємо насправді. Зрозуміло, що ця ситуація не піддається управлінню. Отже, я прошу допомогу та пропозиції щодо: 1, зменшення складності занять; 2. Спростіть сценарії взаємодії між моїми об'єктами; 3. Скоротіть час тестування та кількість коду для тестування.
EDIT:
Я думаю, що я не був зрозумілий про стан машин. Робот сам по собі є державною машиною, зі штатами «сплячий», «неспаний», «підзарядний», «мертвий» тощо. Автомобіль - ще одна державна машина.
EDIT 2: Якщо вам цікаво, що насправді є моєю системою, класи, які взаємодіють, - це такі як сервер, IPAddress, диск, резервне копіювання, користувач, SoftwareLicense та ін. це було б досить просто, щоб пояснити мою проблему.