Help us understand the problem. What is going on with this article?

【Gang of Four】デザインパターン学習 - Fly Weight

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
takumi0620
今はAndroidの仕事がメイン https://github.com/takumi0620
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした