私はJavaで書かれた分散システムプロジェクトに参加しています。このプロジェクトには、非常に複雑な現実のビジネスオブジェクトに対応するクラスがいくつかあります。これらのオブジェクトには、ユーザー(または他のエージェント)がそのオブジェクトに適用できるアクションに対応する多くのメソッドがあります。その結果、これらのクラスは非常に複雑になりました。
システムの一般的なアーキテクチャアプローチにより、多くの動作がいくつかのクラスに集中し、多くの可能な相互作用シナリオが発生します。
例として、わかりやすくするために、ロボットと車が私のプロジェクトのクラスであったとしましょう。
したがって、Robotクラスには、次のパターンで多くのメソッドが含まれます。
- 睡眠(); isSleepAvaliable();
- 起きている(); isAwakeAvaliable();
- walk(方向); isWalkAvaliable();
- シュート(方向); isShootAvaliable();
- turnOnAlert(); isTurnOnAlertAvailable();
- turnOffAlert(); isTurnOffAlertAvailable();
- recharge(); isRechargeAvailable();
- 電源を切る(); isPowerOffAvailable();
- stepInCar(Car); isStepInCarAvailable();
- stepOutCar(Car); isStepOutCarAvailable();
- 自己破壊(); isSelfDestructAvailable();
- die(); isDieAvailable();
- 生きている(); isAwake(); isAlertOn(); getBatteryLevel(); getCurrentRidingCar(); getAmmo();
- ...
Carクラスでも同様です。
- オンにする(); isTurnOnAvaliable();
- 消す(); isTurnOffAvaliable();
- walk(方向); isWalkAvaliable();
- refuel(); isRefuelAvailable();
- 自己破壊(); isSelfDestructAvailable();
- クラッシュ(); isCrashAvailable();
- isOperational(); isOn(); getFuelLevel(); getCurrentPassenger();
- ...
これら(ロボットと車)はそれぞれ状態マシンとして実装されており、一部のアクションは一部の状態で可能であり、一部のアクションは不可能です。アクションはオブジェクトの状態を変更します。アクションメソッドIllegalStateException
は、無効な状態で呼び出されたときにスローされ、isXXXAvailable()
メソッドはその時点でアクションが可能かどうかを通知します。状態から簡単に推測できるものもありますが(たとえば、眠っている状態では、目が覚めている状態です)、そうでないものもあります(発射するには、起きていて、生きていて、弾薬があり、車に乗っていない)。
さらに、オブジェクト間の相互作用も複雑です。たとえば、車はロボットの乗客を1人しか保持できないため、別の人が乗ろうとすると、例外がスローされます。車がクラッシュした場合、乗客は死ぬはずです。ロボットが車内で死んでいる場合、たとえ車自体に問題がなくても、ロボットは外に出られません。ロボットが車の中にある場合、彼は脱出する前に別のロボットに入ることはできません。等
その結果、すでに述べたように、これらのクラスは非常に複雑になりました。さらに悪いことに、ロボットと車が相互作用するシナリオは何百とあります。さらに、そのロジックの多くは、他のシステムのリモートデータにアクセスする必要があります。その結果、単体テストが非常に難しくなり、テストの問題がたくさんあります。
- テストケースのセットアップは、非常に複雑な世界を作成して実行する必要があるため、非常に複雑です。
- テストの数は膨大です。
- テストスイートの実行には数時間かかります。
- 私たちのテストカバレッジは非常に低いです。
- テストコードは、テストするコードよりも数週間または数か月遅れて記述されるか、まったく記述されない傾向があります。
- テストされたコードの要件が変更されたことが主な原因です。
- 一部のシナリオは非常に複雑で、セットアップ中にタイムアウトで失敗します(各テストでタイムアウトを構成しましたが、最悪の場合、2分間、さらにこの時間タイムアウトしても、無限ループではないことを確認しました)。
- バグは定期的に本番環境に侵入します。
そのロボットと車のシナリオは、私たちが実際に持っているものを大幅に単純化しすぎています。明らかに、この状況は管理できません。ですから、私はヘルプと提案を求めています:1、クラスの複雑さを減らします。2.オブジェクト間の相互作用シナリオを簡素化します。3.テスト時間とテストするコードの量を減らします。
編集:
私は状態機械について明確ではなかったと思います。ロボットはそれ自体がステートマシンであり、「スリープ」、「覚醒」、「再充電」、「デッド」などの状態を持ちます。車は別のステートマシンです。
編集2:私のシステムが実際に何であるかに興味がある場合、相互作用するクラスは、サーバー、IPアドレス、ディスク、バックアップ、ユーザー、ソフトウェアライセンスなどです。ロボットと車のシナリオは、私が見つけた単なるケースですそれは私の問題を説明するのに十分簡単です。