Adapterパターンは、GoF(Gang of Four)が提唱した23のデザインパターンの一つで、異なるインターフェースを持つクラス同士を接続し、互換性を提供するためのパターンです。
このパターンを使うことで、既存のコードを変更せずに新しい機能を追加することが可能になります。
本記事では、Adapterパターンの概要と実際の使い方、さらにJava、C++、C#、VB.NETでの実装例を詳しく解説します。
Adapterパターンとは
Adapterパターンは、互換性のないクラスをつなぐ「変換器」の役割を果たします。
これにより、既存のクラスやコードに手を加えることなく、新しいインターフェースに適応させることができます。
このパターンは、特にライブラリやフレームワークなど、既存のコードベースを活用したい場面で効果を発揮します。
Adapterパターンの基本構造
Adapterパターンは、既存のクラスを新しいインターフェースに適合させるための構造を持ちます。主な要素は、
以下の通りです。
- Client: 新しいインターフェースを期待するクラス
- Target: 期待されるインターフェース
- Adaptee: 既存のクラスやインターフェース
- Adapter: AdapteeをTargetに適合させる役割を担うクラス
Adapterパターンの使い方
Adapterパターンの使い方は、異なるインターフェース間での互換性を提供する場面で用いられます。
例えば、既存のシステムに新しい機能を統合する際に、Adapterを使うことで、既存のコードを変更することなく新しいインターフェースを導入できます。
実際の使用例
実際の開発においては、ライブラリや外部APIとの互換性を持たせるためにAdapterパターンがよく使用されます。
例えば、外部サービスからのデータを既存のデータフォーマットに適合させる場合などが考えられます。
Adapterパターン実装サンプル
ここでは、AdapterパターンをJava、C++、C#、VB.NETで実装したサンプルコードを紹介します。
Javaでの実装例
// Targetインターフェース
public interface Target {
void request();
}
// Adapteeクラス
public class Adaptee {
public void specificRequest() {
System.out.println("Adapteeのメソッドを呼び出しています。");
}
}
// Adapterクラス
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// Clientクラス
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request();
}
}
C++での実装例
// Targetクラス
class Target {
public:
virtual void request() = 0;
};
// Adapteeクラス
class Adaptee {
public:
void specificRequest() {
std::cout << "Adapteeのメソッドを呼び出しています。" << std::endl;
}
};
// Adapterクラス
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* adaptee) : adaptee(adaptee) {}
void request() override {
adaptee->specificRequest();
}
};
// Clientコード
int main() {
Adaptee adaptee;
Target* target = new Adapter(&adaptee);
target->request();
delete target;
return 0;
}
C#での実装例
// Targetインターフェース
public interface Target {
void Request();
}
// Adapteeクラス
public class Adaptee {
public void SpecificRequest() {
Console.WriteLine("Adapteeのメソッドを呼び出しています。");
}
}
// Adapterクラス
public class Adapter : Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void Request() {
adaptee.SpecificRequest();
}
}
// Clientコード
class Program {
static void Main(string[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.Request();
}
}
VB.NETでの実装例
' Targetインターフェース
Public Interface Target
Sub Request()
End Interface
' Adapteeクラス
Public Class Adaptee
Public Sub SpecificRequest()
Console.WriteLine("Adapteeのメソッドを呼び出しています。")
End Sub
End Class
' Adapterクラス
Public Class Adapter
Implements Target
Private adaptee As Adaptee
Public Sub New(adaptee As Adaptee)
Me.adaptee = adaptee
End Sub
Public Sub Request() Implements Target.Request
adaptee.SpecificRequest()
End Sub
End Class
' Clientコード
Module Program
Sub Main()
Dim adaptee As New Adaptee()
Dim target As Target = New Adapter(adaptee)
target.Request()
End Sub
End Module
まとめ
Adapterパターンは、既存のコードやシステムを変更せずに新しいインターフェースを追加する際に非常に有効なパターンです。
このパターンを使用することで、クラス間の互換性を保ちながら柔軟なシステム設計が可能になります。
Java、C++、C#、VB.NETなどのプログラミング言語で簡単に実装できるため、開発現場でも広く利用されています。
Adapterパターンを正しく理解し、適切な場面で活用することが重要です。
