デコレータパターンの概要
デコレータパターンは構造的デザインパターンの一種で、既存のオブジェクト機能を変更せずに拡張する手法です。ラップされたオブジェクトは元のオブジェクトと同一インターフェースを維持しつつ、追加機能を提供します。
主要構成要素
- 抽象コンポーネント(Component): 基本機能を定義するインターフェース
- 具象コンポーネント(ConcreteComponent): 基本機能の実装クラス
- 抽象デコレータ(Decorator): 追加機能の基本構造
- 具象デコレータ(ConcreteDecorator): 実際の機能拡張を実装
利点と欠点
利点
- 継承よりも柔軟な機能拡張が可能
- コンポーネントとデコレータの結合度が低い
- 開放/閉鎖原則を完全に遵守
欠点
- デコレーション階層が深くなると理解が困難
実装例
基本インターフェースの定義:
public interface MusicalDevice {
void execute();
}
具象コンポーネントの実装:
public class Keyboard implements MusicalDevice {
@Override
public void execute() {
System.out.println("キーボード演奏");
}
}
public class StringInstrument implements MusicalDevice {
@Override
public void execute() {
System.out.println("弦楽器演奏");
}
}
抽象デコレータの実装:
public abstract class DeviceEnhancer implements MusicalDevice {
protected MusicalDevice baseDevice;
public DeviceEnhancer(MusicalDevice baseDevice) {
this.baseDevice = baseDevice;
}
@Override
public void execute() {
baseDevice.execute();
}
}
具象デコレータの実装:
public class CookingEnhancer extends DeviceEnhancer {
public CookingEnhancer(MusicalDevice baseDevice) {
super(baseDevice);
}
@Override
public void execute() {
super.execute();
cook();
}
private void cook() {
System.out.println("調理機能実行");
}
}
使用例:
public class DecoratorExample {
public static void main(String[] args) {
MusicalDevice device = new Keyboard();
device.execute();
MusicalDevice enhancedDevice = new CookingEnhancer(new StringInstrument());
enhancedDevice.execute();
}
}
実行結果:
キーボード演奏 弦楽器演奏 調理機能実行
実践応用例
Java I/Oライブラリにおける典型的なデコレータパターンの使用例:
DataInputStream dataInput = new DataInputStream(
new BufferedInputStream(
new FileInputStream("data.bin")
)
);