Memento:kotlin

気を付けたこと

  • kotlinでは複数のクラスを一つのファイルにまとめることが出来るのでまとめた
  • コンストラクタ内で変数の定義と初期化が出来る
  • packageprivateの代わりにinternalを使う
  • “${式}”の形で文字列リテラルに変数や式を埋め込める
  • forの構文がちょっと違う
  • 型のキャストはas演算子を使うがスマートキャストという機能もある

パッケージ

kotlinでは「packageprivate」のアクセス修飾子は無いです。代わりに「internal」があります。同じモジュールからのみアクセスできます。別にモジュールに分けなくてもpackageキーワードは使えますが、internalを使えるので分けといた方が良い気がします。あとjavaのようにフォルダ名とパッケージ名が一致している必要は無いみたいですが、javaと合わせておいた方が良い気がします。こちらが参考になりました。

Intellijでモジュールを追加する

追加したいフォルダを右クリックして新規➡モジュール。

ダイアログに従ってモジュール名を決めて作成する。

モジュールの依存関係を追加する

使用する側のクラスが含まれるフォルダを選択してf4キー(ファイル➡モジュールを追加)を押下。

依存関係タブの+ボタンを押して追加したいモジュールを選択。


Main.kt

import game.Gamer

fun main(args: Array<String>) {
    val gamer = Gamer(100)
    var memento = gamer.createMemento()
    for (i in 0 until 100) {
        println("====${i}")
        println("現状:${gamer}")
        gamer.bet()
        println("所持金は${gamer.getMoney()}円になりました")
        if (gamer.getMoney() > memento.getMoney()) {
            println("   (だいぶ増えたので、現在の状態を保存しておこう)")
            memento = gamer.createMemento()
        }else if (gamer.getMoney() < memento.getMoney() / 2) {
            println("   (だいぶ減ったので、以前の状態に復帰しよう")
            gamer.restoreMemento(memento)
        }
        try {
            Thread.sleep(1000)

        } catch (e: InterruptedException) {

        }
        println("")
    }
}

Gamer.kt

package game

import java.util.*
import kotlin.collections.ArrayList

class Memento(internal var money:Int,private var fruits:ArrayList<String> = arrayListOf()) {
    fun getMoney() = money
    internal fun addFruit(fruit: String) {
        fruits.add(fruit)
    }
    internal fun getFruits() = fruits.clone()
}
class Gamer(private var money: Int){
    private var fruits = arrayListOf<String>()
    private val random = Random()

    companion object {
        val fruitsname = arrayOf("リンゴ","バナナ","ブドウ","みかん")
    }
    fun getMoney() = money
    fun bet() {
        val dice = random.nextInt(6) + 1
        if (dice == 1) {
            money += 100
            println("所持金が増えました")
        }else if (dice == 2) {
            money /= 2
            println("所持金が半分になりました")
        }else if (dice == 6) {
            val f = getFruit()
            println("フルーツ(${f})をもらいました")
            fruits.add(f)
        } else {
            println("何も起こりませんでした")
        }

    }
    fun createMemento(): Memento {
        val m = Memento(money)
        val it = fruits.iterator()
        while (it.hasNext()) {
            val f = it.next()
            if (f.startsWith("おいしい")) {
                m.addFruit(f)
            }
        }
        return m
    }
    fun restoreMemento(memento: Memento) {
        this.money = memento.money
        this.fruits = memento.getFruits() as ArrayList<String>

    }

    override fun toString(): String {
        return "[money = ${money} + , fruits = ${fruits} ]"

    }
    private fun getFruit(): String {
        var prefix = ""
        if (random.nextBoolean()) {
            prefix = "おいしい"
        }
        return "${prefix}${fruitsname[random.nextInt(fruitsname.size)]}"
    }

}

元のコードは以下の本からの引用です。サンプルコードは著者さんのサイトで配布されています。リンクはAmazonアソシエイトを使用しています。

増補改訂版Java言語で学ぶデザインパターン入門

ライセンス表記

Copyright (C) 2001,2004 Hiroshi Yuki.

hyuki@hyuki.com
This software is provided ‘as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution.

コメント

タイトルとURLをコピーしました