オブジェクト指向プログラミングにアプローチする2つの異なる方法を区別したい
- シミュレーション担当者:オブジェクトは実際のドメインオブジェクトを表し、そのドメインに関連する機能を処理するようにプログラムしました。この方法でプログラムされたオブジェクトは、この機能を実装するために使用される多くの変更可能な状態と非表示の共同作業者を持つ可能性があります。
- レコード+関数:オブジェクトは、データとそのデータを操作する関数の単なるバンドルです。この方法でプログラムされたオブジェクトは、不変になりやすく、より少ない責任を引き受け、コラボレーターを注入できるようになります。
経験則では、最初の方法でプログラムされたオブジェクトにvoid
は、2番目の方法よりも多くのメソッドとメソッドが含まれます。フライトシミュレータを作成し、飛行機のクラスを設計するとします。私たちは次のようなものになるでしょう:
class Plane {
void accelerate();
void deccelerate();
void toggleRightFlaps();
void toggleLeftFlaps();
void turnRudderRight();
void turnRudderLeft();
void deployLandingGear();
void liftLandingGear();
// etc.
void tick() throws PlaneCrashedException;
}
これはおそらく人が遭遇するよりも少し極端かもしれませんが、それは全体的に重要です。この種のインターフェースを実装したい場合は、オブジェクト内に保持する必要があります。
- 飛行機の機器の状態に関するすべての情報。
- 飛行機の速度/加速度に関するすべての情報。
- シミュレーションのリフレッシュレート(ティックを実装するため)。
- シミュレーションの3Dモデルとティックを実装するための物理に関する詳細。
モードで記述されたオブジェクトの単体テストを記述することは、次の理由により非常に困難です。
- テストの開始時に、このオブジェクトに必要なさまざまなデータとコラボレーターのすべてを提供する必要があります(これらを初期化するのは非常に面倒な場合があります)。
- メソッドをテストする場合、次の2つの問題が発生します。a)インターフェースがテストするのに十分なデータを公開していないことが多い(そのため、モック/リフレクションを使用して期待を検証する必要がある)b)多くのコンポーネントがバインドされている各テストで動作を確認する必要があるものに。
基本的には、ある程度合理的でドメインによく似ているようなインターフェースから始めますが、シミュレーションの素晴らしさにより、テストが非常に難しいオブジェクトを作成するようになっています。
ただし、同じ目的を満たすオブジェクトを作成できます。あなたはPlane
より小さなビットにあなたのブレーキをかけたいでしょう。有するPlaneParticle
露光、1つは、これらを操作することができ、平面のphysicsyビット、位置、速度、加速度、ロール、ヨー、等、等を追跡しています。その後、PlaneParts
オブジェクトはステータスを追跡できます。あなたはtick()
完全に異なる場所に出荷しPlanePhysics
ます。たとえば、与えられたa PlaneParticle
とPlaneParts
新しいを吐き出す方法を知っている重力などによってパラメータ化されたオブジェクトがあるとしますPlaneParticle
。これは、必ずしも例である必要はありませんが、すべて不変である可能性があります。
これで、テストに関して次の利点があります。
- 個々のコンポーネントは実行する必要が少なく、設定が簡単です。
- コンポーネントを個別にテストできます。
- これらのオブジェクトは内部を公開することで回避できるため(特に、オブジェクトが不変にされている場合)、それらを測定するために賢い必要はありません。
これが秘訣です。私が説明した2番目のオブジェクト指向アプローチは、関数型プログラミングに非常に近いものです。多分純粋な関数型プログラムでは、レコードと関数は別々であり、オブジェクトに結合されていません。関数型プログラムはこれらすべてのことを確実にします。ユニットテストが本当に簡単になると私が思うのは
- 小さなユニット(小さな状態空間)。
- 入力が最小限の関数(非表示の入力なし)。
- 最小限の出力で機能します。
関数型プログラミングはこれらのことを奨励します(ただし、どのパラダイムでも悪いプログラムを書くことができます)が、オブジェクト指向プログラムでは実現可能です。さらに、関数型プログラミングとオブジェクト指向プログラミングには互換性がないわけではないことを強調しておきます。