1. 概要

Abstract Factoryは、具体的な実装を公開せずに、同じテーマでオブジェクトのファミリを作成するための単一のインターフェイスを提供することを目的としたソフトウェアデザインパターンです。 このパターンは、ファクトリパターンの上に別の抽象化レイヤーを提供します。

このチュートリアルでは、KotlinにAbstractFactoryを実装するための効率的なアプローチを見ていきます。

2. 抽象ファクトリパターン

Abstract Factoryは作成デザインパターンであり、主な目的は、共通のテーマを持つオブジェクトの作成を別のファクトリオブジェクトにカプセル化することです。 さらに、各ファクトリオブジェクトには、すべてのオブジェクトに構築サービスを提供する責任があります。

抽象ファクトリのコンポーネントクラスとインターフェイスを見てみましょう。

  • 抽象ファクトリ:抽象オブジェクトを作成するための操作のインターフェースを定義します
  • コンクリートファクトリ:コンクリートオブジェクトを作成する操作を実装します
  • 抽象オブジェクト:特定のタイプのオブジェクトのインターフェースを定義します
  • 具体的なオブジェクト:具体的なファクトリによって作成されるオブジェクトのクラス定義
  • クライアント:AbstractFactoryおよびAbstractObjectで定義されたインターフェースを使用するクラス

次の図は、抽象ファクトリの構造とそのコンポーネントを示しています。

3. 実装

私たちの研究事例では、武器のファミリーの例を考えてみましょう。 そのためには、クライアント側で使用できるWeaponタイプのオブジェクトを作成する方法が必要です。

タイプWeaponの一般的な汎用インターフェースを定義しましょう。

interface Weapon {

    fun use():String
}

次に、タイプWeaponのオブジェクトを作成するための汎用インターフェイスとして機能する抽象ファクトリクラスを作成します。

abstract class WeaponFactory {

    abstract fun buildWeapon(): Weapon
}

このチュートリアルでは、コンパニオンオブジェクトを使用して特定のファクトリを実装します。 Kotlinのコンパニオンオブジェクトを使用すると、クラスと同じファイルで宣言されたオブジェクトを作成できます。 たとえば、必要になる可能性のある特定の武器ごとに、コンパニオンオブジェクトFactoryを定義できます。

Crossbowクラスを作成しましょう。

class Crossbow : Weapon {

    companion object Factory : WeaponFactory() {
        override fun buildWeapon() = Crossbow()
    }

    override fun use(): String {
        return "Using crossbow weapon"
    }
}

その後、このタイプの武器の最終的なクライアントを定義する必要があります。

val factory : WeaponFactory = Crossbow.Factory
val crossbow = factory.buildWeapon()

assertNotNull(crossbow)
assertEquals("Using crossbow weapon", crossbow.use())

Weapon タイプは、実行時にFactory宣言によって定義されていることがわかります。

同様に、別のタイプの武器を定義することもできます。 剣の種類を定義しましょう–

class Katana : Weapon {

    companion object Factory : WeaponFactory() {
        override fun buildWeapon() = Katana()
    }

    override fun use(): String {
        return "Using katana weapon"
    }
}

4. 抽象ファクトリの利点

Abstract Factoryパターンを実装すると、保守するコードがより複雑になる可能性があります。 ただし、このパターンを使用することにはいくつかの利点があります。

  • 具体的なオブジェクトクラスはクライアントとの結合が緩いため、コードの柔軟性と再利用性が向上します。
  • 新しいタイプのオブジェクトを作成するプロセスは単一のインターフェースに統合され、ベースコードの保守が容易になります
  • オープン/クローズド原則に準拠しているため、既存のコードに影響を与えることなく新しいファクトリを追加することで機能を拡張できます

5. 結論

この記事では、KotlinでAbstractFactoryパターンを実装するための効率的なアプローチについて説明しました。 このパターンは、ファクトリのグループに対して別のレベルの抽象化が必要な場合に役立ちます。 さらに、Kotlinがパターンの実装を強力にサポートしていることもわかりました。

いつものように、この記事の完全なコードは、GitHubから入手できます。