四畳半の秘密基地

さあ、今日はどんな実験をしよう

MENU

技術書展5に行ってきました!

techbookfest.org

技術書展5に行ってきたのでその感想など書いてみようと思います。 技術書展への参加は2回目で、前回参加したときは台風の中、列に並んでいた記憶があります。 今回は天候に恵まれてよかった!(その分来る人が多くて大変だったかもですが)

滞在時間

当日は10時頃に並び始め、開場して列が動き始めるとそのまま中に入れました。会場では目当てのサークルを探したり興味を惹かれた本を手にとって読んだりして、昼前に人口密度が高くなり身動きが取りづらくなってきたので退散しました。

だいたい2時間弱滞在してました。開場時間を10時だと勘違いして早めに並んでしまいましたが、結果的に開場後にほぼ待たずに入れたので結果オーライ。

戦利品

f:id:k-seito:20181009225636j:plain

8冊書いました。Androidに関する本が多めです。肉の本は完全に衝動買いでした。低音調理イイよね!

良かった点

各サークルの書籍が見本として置かれている場所

個人的に一番有難かったのはこのスペースです。すべてのサークル?の本が一箇所にまとまっているので面白そうな本がないか探すために開場を歩き回らなくてもよかったので体力を温存できました。

決済アプリ

さすがテクブさんと思ったのが決済アプリ。同人イベントで決済アプリ見たのは初めてでした。このアプリを使えば後払いでじゃんじゃん本を購入することができるみたいです。

自分の場合、このアプリは使わず現金払いにしました。イベント事では財布の紐が緩んでしまうタイプなので、後払いというシステムは嫌な予感しかしません。

素敵な標語

f:id:k-seito:20181009225502j:plain f:id:k-seito:20181009225458j:plain f:id:k-seito:20181009225444j:plain

書かれている事が深いですね。こういうの好きです。
他にもありましたが、特に気に入ったものを撮りました。

気になった点

行列に行く手を遮られる

自分が滞在していた時間に一箇所、行列ができてました。その行列にサークルさんが隠れて見えない+行列で通路が狭くなり動きづらいという状態になってました。 コミケとかで人気サークルを壁際に配置していたのはこういう理由だったのかと得心しつつKIAIで通りました。 技術書展はコミケとかに比べるとまだまだ歴史は浅いし行列になるであろうサークルを特定するのは無理ゲー感ありますね。

まとめ

自分は基本的にネット通販でしか技術書を買いません。そうすると必然的に自分が興味を持った分野の書籍しか購入できないのですが、技術書展は自分の興味の外にある技術(技術書)を知る事ができる良い機会だと思い参加しています。

今回も「fitbitってAPIあるのかー」「システム管理者を題材にしてる漫画があるの知らなかった」「低音調理器って自作できるの!?」といった新しい発見がありました。

本屋さんは、その人が自分でも知らない興味の種を発見できるような仕掛けを準備している

と何かの本に買いてありましたが、技術書展はそれをITという限られた分野で行なっているように思いました。

そんな出会いを提供して頂いた技術書展の運営様やサークルの皆様に感謝です。ありがとうございました。いつの日かサークル参加できたらいいなぁ・・・

アウトプット大全を読んでみた

前々から、「アウトプットって大事だよな〜」と思いつつなかなか行動に移せていなかったのですが、学びを結果に変えるアウトプット大全を読んで改めてアウトプットの大事さを感じたので早速実践ということで書いてみたいと思います。
この本に読書感想用のテンプレートも準備されているのでそれに則って書いてみます。

概要

この本は全5章で、1章がアウトプットのメリット、2〜5章が具体的なアウトプットの方法という構成になっています。
私としてはアウトプットのメリット・方法どちらも知りたかったので全体的にとてもためになりました。個人的に特に目からウロコだった事柄を3つあげてみたいと思います。

1. アウトプット=運動

アウトプットするときは、書いたり話したりして運動神経を使うと記憶が定着しやすいです。「運動性記憶」と呼ばれるもので神経細胞が使われるほど記憶に残りやすくなります。
実感として声に出して読んだり・ブログに書いたりするとアウトプットすると記憶に残りやすい印象があります。

2. アウトプットのハードルは高ければいいとは限らない

アウトプットのハードルは、高すぎるとモチベーションが上がらないし不安や恐怖を感じてしまって長続きしません。
この本ではアウトプットの難易度を「快適領域」、「学習領域」、「危険領域」の3つに分類して学習領域となるちょい難のアウトプットを行うことを勧めています。
私はアウトプットのハードルを危険領域に設定する傾向があるみたいで、楽しさよりも不安が勝るときの方が多いので見直した方がよいと感じました。

3. やる気スイッチは時限式

やる気スイッチはやる前に入るのではなく、やり始めると入ります。人の脳は作業を始めると、だんだんやる気が出てくるような性質を持っています。知らなかった・・・。
たしかに、やる気はないけどポモドーロテクニックを1サイクルだけ回してみようかと思って始めた作業が2サイクル以上続いた経験は割とあります。
ポモドーロテクニックは25分間ですが、25分と言わず5分でもいいから始めた方がエンジンがかかりやすいみたいです。

まとめ

他にもたくさんためになることが書いてありますが、一度に吸収できない量なので何度も読み返したいと思います。興味を持たれた方は購入してみてください。
サービスを開発するエンジニアとして働いていると、アウトプットすることは生存戦略上大事なんだろうなーと思う時が多々ありました。
しかし生存戦略という動機だけでアウトプットするのは楽しくなくて、楽しくアウトプットできる理由を探していました。
この本はその疑問に答えくれる本でした。

Kotlinとスプラトゥーンで学ぶデザインパターン【7. Builder】

休日にやりたいことがありすぎてなかなかブログを更新できてません。
気がついてたら半年ぶりの更新になってた。
スプラトゥーン2は地味に続けてますが最近はNine Parchmentsにはまってます。

ec.nintendo.com

Builder パターンとは

普段Androidアプリの開発をしているとBuilderパターンで書かれているクラスをよく見ます。
StringBuilderとかOkHttpClientとか。
Builderパターンは複雑な処理を、段階的に組み上げていくパターンです。
また組み上げ方は固定ですが、組み上げる時に使用するオブジェクトは柔軟に変えられるようになってます。

実装

メインとなるクラスはDirectorとBuilderで、この2クラスで組み上げ方を決めています。

Director.kt

class Director(private val builder: MainWeaponBuilder) {
    fun construct() {
        builder.name(".96ガロン")
        builder.power(62)
        builder.range(31)
        builder.quickness(10)
    }
}

MainWeaponBuilder.kt

abstract class MainWeaponBuilder {
    abstract fun name(name: String)
    abstract fun range(range: Int)
    abstract fun power(power: Int)
    abstract fun quickness(quickness: Int)
}

今回はスプラトゥーン熱が低かったせいか例があまり良くないですがDirectorクラスは.96ガロンを作成するクラスとなっています。
デコるかどうかは使用するBuilderクラスに寄ります。
無印を作りたい場合はUnmarkedWeaponBuilderを、デコを作りたい場合はDecoratorWeaponBuilderを使用すれば作成できます。

UnmarkedWeaponBuilder.kt

class UnmarkedWeaponBuilder : MainWeaponBuilder() {

    var name: String? = null
    var range: Int = 0
    var power: Int = 0
    var quickness: Int = 0

    override fun name(name: String) {
        this.name = name
    }

    override fun range(range: Int) {
        this.range = range
    }

    override fun power(power: Int) {
        this.power = power
    }

    override fun quickness(quickness: Int) {
        this.quickness = quickness
    }

    fun getResult(): Weapon {
        return Weapon(name!!, range, power, quickness)
    }
}

DecoratorWeaponBuilder.kt

class DecoratorWeaponBuilder : MainWeaponBuilder() {

    var name: String? = null
    var range: Int = 0
    var power: Int = 0
    var quickness: Int = 0

    override fun name(name: String) {
        this.name = "${name}デコ"
    }

    override fun range(range: Int) {
        this.range = range
    }

    override fun power(power: Int) {
        this.power = power
    }

    override fun quickness(quickness: Int) {
        this.quickness = quickness
    }

    fun getResult(): Weapon {
        return Weapon(name!!, range, power, quickness)
    }
}

改めて見ても例がいまいち・・・。

実行結果

それぞれの.96ガロンを作成して見ます。

Main.kt

fun main(args: Array<String>) {
    val unmarkedBuilder = UnmarkedWeaponBuilder()
    var director = Director(unmarkedBuilder)
    director.construct()
    println(unmarkedBuilder.getResult())

    val decoratorBuilder = DecoratorWeaponBuilder()
    director = Director(decoratorBuilder)
    director.construct()
    println(decoratorBuilder.getResult())
}

結果は

Weapon(name=.96ガロン, range=31, power=62, quickness=10)
Weapon(name=.96ガロンデコ, range=31, power=62, quickness=10)



感想

Builderパターンというデザインパターンは1つですが、その中身は参考書籍やサイト・実際に業務で使用するクラスによってまちまちでなんとも捉え難いパターンでした。
OkHttpClintの場合は、メソッドチェーンにしてクラスで使用するパラメータを順々に渡していくやり方で自分はそれがBuilderパターンなのかと思ってました。
必要なオブジェクトを段階を踏んで組み上げることがBuilderパターンの本質で実装はそれぞれ考えてるのかなぁ。

ソースはこちら

Kotlinとスプラトゥーンで学ぶデザインパターン【5. Singleton】

最近チャージャーに限界を感じてきました。特にガチホコだと思わぬ奇襲を受けやすいです。
奇襲に対処できるチャージャーになりたい。


Singleton パターンとは

Singletonとは対象のクラスが絶対に1つしか存在しないことを保証するデザインパターンです。
今回は、ダウニーの上位互換ことスパイキーをSingletonパターンで表現してみました。
スパイキーはゲソタウンで指定したギアの受け取りをしてくれます。
当たり前ですが、スパイキーは一人(匹?)しかいないです。
複数いたらどのスパイキーからギアを受け取ればいいかわからなくなりますね。


実装

Spiky.kt

class Spiky {

    private constructor() {}

    var delivery: Delivery? = null

    companion object {
        val spiky = Spiky()
        fun getInstance(): Spiky {
            return spiky
        }
    }

    fun receiveDelivery(delivery: Delivery) {
        this.delivery = delivery
    }

    fun requestReceiveOrder() {
        delivery?.let { println(it.name + "が届いてるぜ!") }
                ?: println("そんなものはない")
    }
}

まずはスパイキークラス。コンストラクタをプライベートにして外部からインスタンス化できないようにして、
インスタンスはクラス内で生成しgetInstanceで渡すようにしてます。
あとは配達物が届いてるか判定して文字を出力します。セリフは雑です。


Delivery.kt

data class Delivery(val id: Int, val name: String)

配達物のデータクラスです。良い英語が思いつかなかった・・・


Main.kt

val spiky = Spiky.getInstance()
spiky.requestReceiveOrder()

spiky.receiveDelivery(Delivery(1, "ガチガサネ"))

val spiky2 = Spiky.getInstance()
spiky2.requestReceiveOrder()

スパイキーを2回生成するようにして同じインスタンスを参照できているか確認します。
インスタンスであればspikey2には配達物が届いてないことになります。


実行結果

そんなものはない
ガチガサネが届いてるぜ!

2回目のリクエストで配達物が届いていたので中のインスタンスは同じようです。


感想

配達物の判定を最初、null判定で表示してたのですが、letを使用したら括弧のdeliveryがnullでないことを保証できたので
letを使いました。赤べこ本で知識として知ってはいたものの使いどころがわかってないですね。
IDEパイセンが気づかせてくれました。ありがとうIntelliJ IDEA!

Kotlinとスプラトゥーンで学ぶデザインパターン【6. Prototype】

久しぶりの更新になってしまいました。
スプラトゥーン2が発売されたし仕方ないよね。ちまちま空いてる時間にプレイしてます。
↓今の状況です。

今回はPrototypeパターンです。Singletonパターンをすでにやってるつもりになってとばしてしまった・・・

Prototype パターンとは

インスタンスを作る時、通常は作りたいクラスをnewして作成しますが、
そうではなく既存のインスタンスをコピーして作る。それをPrototypeパターンと呼ぶらしいです。
なぜそのような実装をするかというと

などの理由が挙げられます。

実装

スプラトゥーンからは離れてしまいますが、セーブデータを題材にしてみました。
セーブデータの中にはいろいろな情報が入っており、クラスからインスタンス化するには難しいというか面倒くさいです。
そこでprototypeパターンを使って実装してみます。

SaveData.kt

class SaveData(val user: User, val games: Array<String>) : Cloneable {
    fun createClone(): SaveData {
        return clone() as SaveData
    }

    fun print() {
        println("id:" + user.id)
        println("name:" + user.name)
        println("registered game datas:")
        games.forEach { println(it) }
    }
}

SaveDataManager.kt

class SaveDataManager {
    fun create(user: User, games: Array<String>): SaveData {
        return SaveData(user, games)
    }

    fun copy(data: SaveData):SaveData {
        return data.createClone()
    }
}

SaveDataにCloneableインターフェースを実装してクローンできるようにしてます。これが今回のキモですね。
cloneは外部に見えないので別途メソッドを作って対応しました。

Main.kt

fun main(args: Array<String>) {
    val user = User(123, "seito")
    var games:Array<String> = arrayOf("Splatoon2", "Mario Kart")
    val manager: SaveDataManager = SaveDataManager()

    val newSaveData = manager.create(user, games)
    newSaveData.print()

    val copiedSaveData = manager.copy(newSaveData)
    copiedSaveData.print()
}

一度セーブデータを作ってそれをコピーして同じ出力結果になるよねーって確認をしています。

実行結果

id:123
name:seito
registered game datas:
Splatoon2
Mario Kart
id:123
name:seito
registered game datas:
Splatoon2
Mario Kart

感想

デザパタ本を読みながら作ったらManagerクラスができたんですが、今回の場合Manager内で扱うクラスは1種類なのでManagerクラスを作らないでMainから直接createCloneを呼んだほうがすっきりするだろうなーと思ったり。
スケーラビリティを考えるとManagerクラスがあってもいいけどスケールする可能性あるのか。

Kotlinとスプラトゥーンで学ぶデザインパターン【4. Factory Method】

昨日前夜祭で久しぶりのスプラトゥーンを満喫してました。
エイムも操作もひどいことになってました。
しばらくはリハビリ期間になりそうです・・・

Factory Methodパターンとは

Factory Methodパターンは、インスタンスの作り方をスーパークラスで定め、実際にインスタンス化する処理はサブクラスに分けて実装するパターンです。
今回は、サーモンランの敵を題材にしました。登場から攻撃までの処理を実装します。

実装

まず枠組みとなるスーパークラスを2つ定義します。
Factory.kt

abstract class Factory {
    fun create() : Enemy {
        var enemy = createEnemy()
        deployToMap(enemy)
        return enemy
    }

    abstract fun createEnemy() : Enemy
    abstract fun deployToMap(enemy: Enemy)
}

Enemy.kt

abstract class Enemy {
    abstract fun attack()
    abstract fun move()
    abstract fun appear()
}

Factoryでは生成してからマップに配置するまでの処理を行なっています。
次に具象クラスです。バクダンという敵をインタンス化します。

BakudanFactory.kt

class BakudanFactory : Factory() {
    override fun createEnemy(): Enemy {
        return Bakudan()
    }

    override fun deployToMap(enemy: Enemy) {
        enemy.appear()
    }

}

Bakudan.kt

class Bakudan : Enemy() {
    override fun attack() {
        println("爆弾を発射!")
    }

    override fun move() {
        println("ちょっと移動")
    }

    override fun appear() {
        println("バクダンが現れた!")
    }

}

実行結果

バクダンが現れた!
ちょっと移動
爆弾を発射!

感想

参考書の例では1製品1工場で作られていたのですが、複数製品があったらどうするのか疑問です。スプラトゥーンのサーモンランではオオモノシャケという敵が複数種類います。今回はバクダン専用のFactoryクラスを作りましたが、コウモリやモグラなどを追加する場合は別でFactoryクラスを作った方がいいのかなぁ。個人的にはEnemyFactoryを作ってそこに全ての敵のインスタンス化を押し込んでしまいたい気持ちになります。謎は深まるばかり・・・

Kotlinとスプラトゥーンで学ぶデザインパターン【3. Template Method】

スプラトゥーン2発売日まで1ヶ月を切りました。
E3での大会、日本チームは惜しくも2位でしたが熱い試合でした。
今回はTemplate Methodパターンです。

Template Methodパターンとは

Template Methodパターンは、親クラスで処理の枠組みを決め、子クラスで具体的な処理を記述するデザインパターンです。
スプラトゥーンでこのデザインパターンが適用できるところがなかなか見つからなかったのですが
試合結果画面がナワバリとガチで違うことに気づき今回は試合結果画面を題材にすることにしました。(前提として勝った時しか考慮していません)

実装

まずナワバリバトルとガチバトルの違いを見極めます。

ナワバリバトル

  • 左上のポイントは塗った面積、
  • チームのリザルトにはランク、武器、名前、塗った面積

<ガチバトル>

  • 左上のポイントはランクに応じてランクに応じて取得できるポイント
  • チームのリザルトにはランク、武器、名前、腕前

が各々表示されます。
これらのことを考慮して実装するとイカのようになりました。

GameResult.kt

abstract class GameResult {
    abstract fun showScore(player: Player)
    abstract fun showTeamResult(players: Array<Player>)

    fun show(players: Array<Player>) {

        //一人目のプレイヤーが自分自身
        showScore(players[0])

        showTeamResult(players)
    }
}

スコア表示、チーム表示メソッドを抽象化して具象クラスに任せています。

Player.kt

data class Player(val name: String, val rank: Int, val udemae: String, val score:Int, val wepon:String)

データクラス。

NawabariBattleResult.kt

class NawabariBattleResult: GameResult() {
    override fun showScore(player: Player) {
        println("" + player.score + "ポイント獲得しました!")
    }

    override fun showTeamResult(players: Array<Player>) {
        for (player in players) {
            println("" + player.rank + ", "  + player.wepon + ", " + player.name + ", " + player.score)
        }
    }

}

GachiBattleResult.kt

class GachiBattleResult : GameResult() {
    override fun showScore(player: Player) {
        println("" + getScoreByUdemae(player.udemae) + "ポイント獲得しました!")
    }

    override fun showTeamResult(players: Array<Player>) {
        for (player in players) {
            println(player.wepon + ", " + player.name + ", " + player.rank)
        }
    }

    //ノックアウトは考慮しない
    private fun getScoreByUdemae(udemae: String): Int {
        when (udemae) {
            "C-" -> return 1000
            "C" -> return 1300
            "C+" -> return 1600
            "B-" -> return 2000
            "B" -> return 2300
            "B+" -> return 2600
            "A-" -> return 3000
            "A" -> return 3300
            "A+" -> return 3600
            "S" -> return 4000
            else -> return 5000
        }
    }
}


具象クラスの実装は上記のようになりました。

呼び出すときはイカのように。

println("ナワバリバトルの結果")
val nawabariResult: NawabariBattleResult = NawabariBattleResult()
nawabariResult.show(players)

println("\n\nガチバトルの結果")
val gachiResult: GachiBattleResult = GachiBattleResult()
gachiResult.show(players)

ソースはこちら
github.com

感想

Javaの入門書を読んでる頃、抽象クラスとかインターフェースとか何に使うのだろう?とずっと疑問で、
業務でもあまり使わないで実装してましたがデザインパターンを学ぶと使い所が見えてくる気がします。