Javaにおけるマーカーインターフェースパターン:空のインターフェースによる振る舞いの定義
別名
- マーカー
- タグ付けインターフェース
マーカーインターフェースデザインパターンの意図
Javaにおけるマーカーインターフェースパターンは、クラスに関するメタデータをタイプセーフな方法で伝えるために使用されます。メソッド宣言を持たないJavaのインターフェースは、マーカーインターフェースとして知られています。これらは、そのようなインターフェースを実装するクラスが、特別な振る舞いや能力を持っていることを示すために使用されます。
現実世界の例を用いたマーカーインターフェースパターンの詳細な説明
現実世界の例
Javaライブラリシステムで、特定の書籍が希少で、貸出制限や特別な保管条件など、特別な取り扱い手順が必要なシナリオを考えてみましょう。マーカーインターフェースパターンと同様に、`RareBook` というマーカーインターフェースを用意することができます。ライブラリカタログの中でこのインターフェースを実装する書籍は、特別な扱いが必要であるとフラグが立てられますが、他の書籍とは異なるメソッドを持つ必要はありません。
図書館の職員がトランザクションを処理したり、保管を処理したりする際に、システムは書籍が `RareBook` インターフェースを実装しているかどうかを確認します。実装している場合、システムは「3日を超える貸出は許可しない」や「温度管理された環境に保管する」などのルールを自動的に適用します。このマーカーインターフェースの使用は、書籍の一般的な管理方法を変更することなく、特別な条件のマーカーとして機能することで、特別な要件を効果的に伝えます。
分かりやすく言うと
Javaにおけるマーカーインターフェースデザインパターンは、特定のメソッド実装を必要とせずに、オブジェクトの特定のプロパティと振る舞いをタイプセーフな方法でシグナリングまたは定義するために、空のインターフェースを使用します。
Wikipediaによると
マーカーインターフェースパターンは、オブジェクトに関する実行時型情報を提供する言語で使用される、コンピュータサイエンスにおけるデザインパターンです。言語がそのようなメタデータを明示的にサポートしていない場合に、メタデータをクラスに関連付ける手段を提供します。
このパターンを使用するには、クラスは空のインターフェースであるマーカーインターフェース(タグ付けインターフェースとも呼ばれます)を実装し、そのクラスのインスタンスと相互作用するメソッドは、インターフェースの存在をテストします。典型的なインターフェースは、実装クラスがサポートしなければならない機能(メソッド宣言の形式で)を指定しますが、マーカーインターフェースはそうする必要はありません。そのようなインターフェースが存在するだけで、実装クラスの特定の振る舞いが示されます。マーカーとして機能し、必要なメソッドを指定するハイブリッドインターフェースも可能ですが、不適切に使用すると混乱を招く可能性があります。
Javaにおけるマーカーインターフェースパターンのプログラム例
マーカーインターフェースデザインパターンは、オブジェクトに関する実行時型情報を提供する言語で使用される、コンピュータサイエンスにおけるデザインパターンです。言語がそのようなメタデータを明示的にサポートしていない場合に、メタデータをクラスに関連付ける手段を提供します。
指定されたJavaコード例では、Permissionインターフェースはマーカーインターフェースとして機能します。このインターフェースを実装するクラスは、特別な権限を持っているとマークされます。このパターンがどのように実装されているかを理解するために、コードを分解してみましょう。
まず、`Permission` インターフェースを定義します。このインターフェースにはメソッドがないため、マーカーインターフェースになります。
public interface Permission {
// This is a marker interface and does not contain any methods
}
次に、アプリケーション内の異なるタイプのキャラクターを表す2つのクラス、`Guard` と `Thief` があります。`Guard` クラスは `Permission` インターフェースを実装しており、このクラスのオブジェクトが特別な権限を持っていることを示しています。
public class Guard implements Permission {
public void enter() {
// Implementation of enter method
}
}
一方、`Thief` クラスは `Permission` インターフェースを実装していないため、このクラスのオブジェクトは特別な権限を持っていないことを示しています。
public class Thief {
public void steal() {
// Implementation of steal method
}
public void doNothing() {
// Implementation of doNothing method
}
}
`App` クラスの `main` メソッドでは、`Guard` と `Thief` のインスタンスを作成します。次に、`instanceof` 演算子を使用して、これらのオブジェクトが `Permission` インターフェースを実装しているかどうかを確認します。オブジェクトが `Permission` インターフェースを実装している場合、特定のアクションを実行することが許可されます。そうでない場合、それらのアクションの実行は制限されます。
public class App {
public static void main(String[] args) {
final var logger = LoggerFactory.getLogger(App.class);
var guard = new Guard();
var thief = new Thief();
if (guard instanceof Permission) {
guard.enter();
} else {
logger.info("You have no permission to enter, please leave this area");
}
if (thief instanceof Permission) {
thief.steal();
} else {
thief.doNothing();
}
}
}
このように、マーカーインターフェースパターン allows us to associate metadata (in this case, special permissions) with a class in a type-safe manner. このように、マーカーインターフェースパターンを使用すると、メタデータ(この場合は特別な権限)をタイプセーフな方法でクラスに関連付けることができます。
Javaでマーカーインターフェースパターンを使用する場合
マーカーインターフェースは、クラスに特別な振る舞いや能力を課したいが、クラスに特定のメソッドを定義することを強制したくない場合に適用できます。このパターンは、メソッドを実装する必要なく、クラスが特定の契約に準拠していることを示すためによく使用されます。
Javaにおけるマーカーインターフェースパターンの実際の適用例
- java.io.Serializable:このインターフェースを実装するクラスは、Javaランタイムによってシリアライズすることができます。
- java.lang.Cloneable:このインターフェースを実装するクラスは、Javaのcloneメソッドを使用して複製できます。
マーカーインターフェースパターンの利点と欠点
利点
- コンパイル時の型チェックが可能になり、開発者はポリモーフィズムを使用して、よりクリーンで柔軟なコードを記述できます。
- 実際の振る舞いを変更することなく、クラスにメタデータを追加できます。
欠点
- コードベースに空のインターフェースが生じる可能性があり、一部の人はそれをクリーンではない、または目的が明確ではないと考えるかもしれません。
- メソッドの実装を強制しないため、適切に処理しないとランタイムエラーが発生する可能性があります。