🗂
Template Method Pattern と Strategy Pattern を図解して説明
Template Method Patternとは
Template Method Pattern(テンプレートメソッドパターン)は、動作の基本的な骨組み(テンプレート)を定義し、派生クラスでその詳細な実装を提供できるようにするデザインパターンです。このパターンはコードの再利用性を高め、一貫性を維持するために使用されます。
Template Method Patternの図解
以下は、Template Method Pattern の構造を表すクラス図です。
クラス説明
-
AbstractClass
: テンプレートメソッドを提供する抽象クラス。-
templateMethod
: 処理の骨組みを定義し、派生クラスで具体的な実装を指定します。 -
step1
とstep2
: 派生クラスでオーバーライド可能なメソッド。
-
-
ConcreteClassA
とConcreteClassB
: 具体的な処理を実装する派生クラス。
Template Method Patternのメリットとデメリット
メリット
-
コードの再利用性向上:
- 共通の処理をテンプレートメソッドに集約することで、重複コードを減らせます。
-
処理の一貫性:
- 骨組みは抽象クラスで定義されるため、処理の流れが統一されます。
-
拡張性:
- 新しい具体クラスを追加することで、振る舞いを変更可能です。
デメリット
-
柔軟性の制限:
- 処理の骨組みが固定化されているため、大幅な変更が難しくなる場合があります。
-
派生クラスの依存:
- 派生クラスがテンプレートの実装に依存するため、抽象クラスの変更が派生クラス全体に影響を与える可能性があります。
-
複雑性の増加:
- シンプルな処理では、このパターンを採用することでコードがかえって複雑になることがあります。
Template Method Patternの使用例
以下は、Template Method Pattern を用いたコーヒーとお茶の調理を表すコード例です。
public abstract class Beverage {
public void Prepare() {
BoilWater();
Brew();
PourInCup();
AddCondiments();
}
protected abstract void Brew();
protected abstract void AddCondiments();
private void BoilWater() {
Console.WriteLine("Boiling water");
}
private void PourInCup() {
Console.WriteLine("Pouring into cup");
}
}
public class Tea : Beverage {
protected override void Brew() {
Console.WriteLine("Steeping the tea");
}
protected override void AddCondiments() {
Console.WriteLine("Adding lemon");
}
}
public class Coffee : Beverage {
protected override void Brew() {
Console.WriteLine("Dripping coffee through filter");
}
protected override void AddCondiments() {
Console.WriteLine("Adding sugar and milk");
}
}
Strategy Patternとは
Strategy Pattern(ストラテジーパターン)は、アルゴリズムをクラスとして分離し、それを動的に切り替えることで柔軟な設計を実現するデザインパターンです。特定の処理を外部化し、コンテキストクラスが異なる戦略(アルゴリズム)を利用できるようにします。
Strategy Patternの図解
以下は、Strategy Pattern の構造を表すクラス図です。
クラス説明
-
Context
: 戦略を利用するクラス。- 戦略を設定する
SetStrategy
メソッドと、それを実行するExecuteStrategy
メソッドを持ちます。
- 戦略を設定する
-
IStrategy
: 戦略の共通インターフェース。- 各戦略クラスで共通のメソッド(例:
Execute
)を定義します。
- 各戦略クラスで共通のメソッド(例:
-
ConcreteStrategyA
とConcreteStrategyB
: 具体的な戦略クラス。-
IStrategy
を実装し、それぞれ異なるアルゴリズムを提供します。
-
Strategy Patternのメリットとデメリット
メリット
-
アルゴリズムの柔軟な切り替え:
- アルゴリズムを実行時に動的に変更できます。
-
コードの責任分離:
- アルゴリズムをコンテキストクラスから分離し、モジュール化を促進します。
-
拡張性:
- 新しい戦略クラスを追加することで、既存コードを変更せずにアルゴリズムを拡張できます。
デメリット
-
複雑性の増加:
- 小規模なシステムでは、クラスやインターフェースの数が増えすぎる可能性があります。
-
戦略間の重複:
- 類似した戦略が複数存在する場合、コードの重複が発生する可能性があります。
Strategy Patternの使用例
以下は、Strategy Pattern を用いた支払い方法の切り替えを表すコード例です。
public interface IPaymentStrategy {
void Pay(decimal amount);
}
public class CreditCardPayment : IPaymentStrategy {
public void Pay(decimal amount) {
Console.WriteLine($"Paid {amount} using Credit Card.");
}
}
public class PayPalPayment : IPaymentStrategy {
public void Pay(decimal amount) {
Console.WriteLine($"Paid {amount} using PayPal.");
}
}
public class PaymentContext {
private IPaymentStrategy _paymentStrategy;
public void SetPaymentStrategy(IPaymentStrategy paymentStrategy) {
_paymentStrategy = paymentStrategy;
}
public void Pay(decimal amount) {
_paymentStrategy?.Pay(amount);
}
}
// 使用例
var context = new PaymentContext();
context.SetPaymentStrategy(new CreditCardPayment());
context.Pay(100);
context.SetPaymentStrategy(new PayPalPayment());
context.Pay(200);
Template Method Pattern と Strategy Pattern の違い
特徴 | Template Method Pattern | Strategy Pattern |
---|---|---|
処理のカスタマイズ方法 | 抽象クラスを継承して処理をオーバーライドする | 実行時に戦略を差し替えて柔軟に処理を変更 |
共通処理の定義場所 | 抽象クラス内に共通処理のテンプレートを定義 | 共通インターフェースを通じて処理を実装 |
柔軟性 | 限定的 | 高い |
Discussion