Car オブジェクトがあるとします。加速機能と破壊機能は、戦略パターンを使用して実装されます。しかし、既存の車のオブジェクトにニトロガス機能を導入したい場合はどうなるでしょうか? 使えるデザインパターンは?
車のオブジェクトを作成した後、ニトロ機能(属性)を追加したいです。
Car オブジェクトがあるとします。加速機能と破壊機能は、戦略パターンを使用して実装されます。しかし、既存の車のオブジェクトにニトロガス機能を導入したい場合はどうなるでしょうか? 使えるデザインパターンは?
車のオブジェクトを作成した後、ニトロ機能(属性)を追加したいです。
Decorator パターンを確認できます。これを使用して、既存のオブジェクトに機能を動的に追加できます。
デコレーター パターンは、さまざまな機能をオブジェクトに動的に追加できます。しかし、これらの機能は Concrete Decorator に実装する必要があります。開発者は、実行時に追加する機能を決定できます。
静的に型付けされた言語では、実行時にメソッドをオブジェクトに追加することはできません。コンパイラは、car.nitroAccelerate() のようなステートメントに遭遇すると、car オブジェクトが nitroAccelerate メソッドを持つインターフェイスを実装しているかどうかをチェックします。実行時にメソッドを追加 (または削除) できる場合、そのようなチェックは不可能です。
動的言語では、実行時にメソッドを追加できます。しかし、これには欠点があります。コードに car.nitroAccelerate() を入れる場合、この時点の car オブジェクトにそのようなメソッドがあるかどうかを注意深く分析する必要があります。
実行時にデコレータを使用して既存のメソッドを変更できますが、その場合、既存のオブジェクトを変更するのではなく、古いオブジェクトをラップする新しいオブジェクトを作成するだけです。
したがって、次のようなことをすると:
Car fasterCar = new CarWithNitro(car);
コードの一部が元の車への参照をまだ保持している場合、この元の車は高速ではありません。これは、ラッピングの操作によって元の車が変更されないためです。
新しいメソッドを追加する場合は、新しいサブクラスを作成するか、委任を使用する必要があります。これは、「ニトロ」機能を有効にするために明示的なメソッド呼び出しが必要な場合に必要になります。
ただし、メソッドを追加せずに既存の機能に追加することだけが必要な場合は、Decorator を使用することをお勧めします。インターフェイス「Car」に floorIt() というメソッドがあるとします。その場合、Car インターフェイスに追加しなくても、Decorator を使用して floorIt に「ニトロ キック」を追加できます。
もちろん、中間点はあります。ランタイム タイプの検出や複数のインターフェイスを使用する場合は、Decorator を使用して、結果のオブジェクトにメソッドを追加することができます。