LoginSignup
1
0

【Gang of Four】Fly Weight

Last updated at Posted at 2019-03-18

#Fly Weight
目次
書中では何やら難しいことが色々と書いてありますが、要するに同じオブジェクトを複数回作成していると色々な面で高コストになるので、Factoryクラスを作成しインスタンスを生成するのは一度きりとすることでそれを回避しましょうね。というのが本パターンの主旨です。

##目的
多数の細かいオブジェクトを効率よくサポートするために共有を利用する。

##構成要素
・Flyweight 同一インスタンスを大量に生成する必要があるオブジェクトの抽象クラス
・ConcreteFlyweight Flyweightの具象クラス
・UnsharedConcreteFlyweight Flyweightクラスを管理するクラス 行、列など子としてFlyweightクラスを保持するクラス
・FlyweightFactory Flyweightクラスを生成するクラス
・Client 使用者

##実装
※UnsharedConcreteFlyweightに相当するクラスはありません。
文字オブジェクト管理するサンプルコードを書きます。書中のサンプルコードも文字オブジェクトが例になっているので同じようなものになってしまいますが。

###ConcreteFlyweight Flyweightの具象クラス
文字クラス
文字を1文字管理するクラス

Character.kt
package flyweight

class Character(private val character: Char) {
    fun print() {
        print(character)
    }
}

###FlyweightFactory Flyweightクラスを生成するクラス
文字製造クラス
文字クラスのインスタンスを生成、プールするファクトリークラスを作成します。
当該クラスにて一度生成したオブジェクトをプールすることにより、以前生成したことのあるオブジェクトを再度生成しない。

CharacterFactory.kt
package flyweight

// シングルトンオブジェクトにする
object CharacterFactory {

    val characterPool = HashMap<AllCharacter, Character>()

    enum class AllCharacter(val value: Char) {
        A('A'),
        B('B'),
        C('C'),
        D('D'),
        E('E'),
        F('F'),
        G('G'),
        H('H'),
        I('I'),
        J('J'),
        K('K'),
        L('L'),
        M('M'),
        N('N'),
        O('O'),
        P('P'),
        Q('Q'),
        R('R'),
        S('S'),
        T('T'),
        U('U'),
        V('V'),
        W('W'),
        X('X'),
        Y('Y'),
        Z('Z')
    }

    fun getCharacterObject(characterType: AllCharacter): Character {
        // 未生成であれば、当該インスタンスをプールする。
        characterPool[characterType]?.let {
            return it
        } ?: run {
            val char = Character(characterType.value)
            characterPool[characterType] = char
            return char
        }
    }
}

###Client 使用者
文字を使う人
BANANAを生成します。

Client.kt
package flyweight

class Client {
    init {
        val characters = ArrayList<Character>()
        // "BANANA"を生成します
        characters.add(CharacterFactory.getCharacterObject(CharacterFactory.AllCharacter.B))
        characters.add(CharacterFactory.getCharacterObject(CharacterFactory.AllCharacter.A))
        characters.add(CharacterFactory.getCharacterObject(CharacterFactory.AllCharacter.N))
        characters.add(CharacterFactory.getCharacterObject(CharacterFactory.AllCharacter.A))
        characters.add(CharacterFactory.getCharacterObject(CharacterFactory.AllCharacter.N))
        characters.add(CharacterFactory.getCharacterObject(CharacterFactory.AllCharacter.A))

        characters.forEach {
            it.print()
        }
    }
}

###出力結果

[output]
BANANA
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0