Decoratorパターンは、GoF(Gang of Four)の23のデザインパターンの一つで、オブジェクトの機能を柔軟に拡張するための構造パターンです。
本記事では、Decoratorパターンの概要、使用方法、そして実装例について詳しく解説します。さらに、Javaを使った実装サンプルも紹介するので、実際のコーディングに役立ててください。
Decoratorとは
Decoratorパターンは、オブジェクトに対して追加機能を動的に付加するためのデザインパターンです。
既存のオブジェクトに対して継承ではなく、別のクラスを介して機能を拡張することができるため、柔軟な拡張が可能です。
Decoratorパターンの目的は、基本機能に追加の機能を組み込む際に、コードの再利用性や保守性を向上させる点にあります。
Decoratorの使い方
Decoratorパターンの使い方は非常にシンプルですが、設計において非常に効果的です。
基本的には、対象となるオブジェクトをインターフェースや抽象クラスで定義し、それに対してDecoratorとなるクラスが別のオブジェクトをラップする形で機能を追加していきます。
この手法を使用することで、既存のクラスに直接変更を加えずに、動的に機能を拡張できる利点があります。
Decoratorパターンの構成要素
Decoratorパターンは、以下の4つの主要な要素で構成されます。
Decoratorの利点と注意点
Decoratorパターンは柔軟性を提供する一方で、構造が複雑になる可能性があります。
特に、複数のデコレーターを組み合わせる場合、クラス間の依存関係が増大することがあるため、設計段階での注意が必要です。
しかし、機能の拡張や変更が容易であり、特定のオブジェクトに対して追加機能を段階的に付加できる点で非常に有用です。
Decorator実装サンプル
ここでは、Decoratorパターンを使ったJavaの実装例を紹介します。
この例では、コーヒーに対して追加のトッピング(ミルクや砂糖)を付加する仕組みを実装します。
Javaコードサンプル
まず、基本となるコーヒーのインターフェースを定義します。
public interface Coffee {
String getDescription();
double getCost();
}
次に、基本のコーヒーを実装するクラスを作成します。
public class SimpleCoffee implements Coffee {
public String getDescription() {
return "Simple Coffee";
}
public double getCost() {
return 2.0;
}
}
次に、Decoratorクラスを定義します。これは基本となるコーヒーをラップし、トッピングを追加するためのクラスです。
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
public String getDescription() {
return decoratedCoffee.getDescription();
}
public double getCost() {
return decoratedCoffee.getCost();
}
}
次に、具体的なデコレータークラス(ミルクと砂糖)を作成します。
ミルクを追加するデコレーター
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
public String getDescription() {
return decoratedCoffee.getDescription() + ", Milk";
}
public double getCost() {
return decoratedCoffee.getCost() + 0.5;
}
}
砂糖を追加するデコレーター
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
public String getDescription() {
return decoratedCoffee.getDescription() + ", Sugar";
}
public double getCost() {
return decoratedCoffee.getCost() + 0.2;
}
}
最後に、Decoratorを使用してコーヒーにミルクと砂糖を追加した例を示します。
public class CoffeeShop {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
}
}
まとめ
Decoratorパターンは、オブジェクトに動的に追加機能を付加するためのデザインパターンであり、継承よりも柔軟で保守性の高い設計が可能です。
特に、機能の拡張を必要とする場面ではDecoratorパターンの適用が有効です。
本記事では、Decoratorパターンの基本的な概念とその使用方法、そしてJavaによる実装サンプルを紹介しました。
これを参考に、実際のプロジェクトでDecoratorパターンを活用してみてください。