モブプログラミングに実況システム導入するのおすすめです #MobProgramming

僕らのモブチームは実況システムというのを導入しているのだけれど、それがとてもいい感じなので紹介したい。

実況システムとは

思ったことや感じたことを皆が気軽に発言、共有できる場を用意すること。

モブプログラミング中にリアルタイムで加筆、修正していきます。

僕らの場合は HackMD を使っています。

どんなことを書くのか

本当に、「何でも」書きます。

今何をやってるか、思っていること、メモ、雑談、などなど。

勉強会やカンファレンスで、Twitterハッシュタグ付けて呟いていくあのイメージです。

  • 今日はXXXからやるぞー
  • 念のためXXX確認しておいてよかった
  • XXX初めて使ったけどかなり便利
  • お腹すいた
  • XXX使えばもう少しすっきり書けないかな。。?
  • そろそろ休憩しよう

何がいいのか

発言ハードルが低い

作業を止めるほどでもないけど、ちょっと気になるなぁ、くらいの気軽さで発言できる。

もちろん大切なことはオフラインで発言すべきだけど、モブプロ中は実現したいことにフォーカスしてるので、本筋と論点が少しずれるようなことは言い出しづらいこともある気がする。

文字として残ってることで、キリのいいタイミングでチームで議論ができる。

後で相談しよう、は忘れてしまいがち。

ふりかえりに使える

僕らは一日の終りに実況をさらっと総ナメして、今日やったことを整理して、翌日やることを確認する。

一日の出来事を俯瞰してみることで、潜在的な課題やタスクに気付くことも多い。

気になってたことをその場で質問したり軽く相談したりもできる。

「なんでも」書いてあるので、チームの定性的な状態が分かったりもする(なんだか皆疲れてる?とか)。

情報がログになる

僕らの実況はマークダウン形式で書いているので、そのまま日報にしてesaに日報として残している。

情報がログとして残っているのは未来の自分たちに大きな意味を持つと思う。

ソロやペアだと共有知として情報を残すことに割く力が足りないことが多い。

でもモブだと手と目が多いことでスピードを落とさずに一定の情報をアウトプットすることができると思う。

たとえば分かりにくい仕様についてのメモだったり、フレームワークの使い方を調査した結果だったり、トラブルシューティングの記録だったり。

アウトプットしておくことで、他チームの助けになることもあると思う。

まとめ

ちょっと前に分報がいいとか悪いとか議論になっていたような気がするけど、実況+日報とすることで、メリットを享受しつつ、デメリットを回避できると思う。

モブプロ+実況システム、おすすめです。

f:id:su-kun1899:20170709170037p:plain

ドットインストールの独習会に参加しました #dotinstall

ドットインストールの独習会に参加してきた。

『ドットインストール』公式ブログ - 【7月6日】そろそろ時間をとってJavaScriptを勉強したい人向け自習会を行います

実は今回で参加するのは二回目。

抽選で当たった模様。倍率は知らない笑

前半はもくもく会で、後半は席の近い人やスタッフの方々と気軽に会話するミートアップといった感じ。
(ピザと飲み物が提供された)

一応独習の内容はドットインストールのレッスンかつJavaScriptということになっていた(今回の場合)。

Electron

JavaScript絡みで何がいいかなー、と思ったらElectron入門があったのでやってみた。

http://dotinstall.com/lessons/basic_electron

完全に初めてだったけど、中々楽しい。

一時間ちょっとくらいで、なんとかアプリを立ち上げて画面表示するくらいまではできた。

時代の流れ

Electron自体もNodeJSも最新のバージョンがレッスンのものとは大分違って、流れの速さを改めて感じる。

幸い、今日やったくらいのところだとそのせいでハマることはなかったけど。

gitignore

Electronだとgitignoreどうすんだろ?と思って何も考えずにググって出てきた↓をパクってみる。

Gitignore for Electron application development · GitHub

NodeJSだと node_modules はignoreするのか。。 npm start すると package.json 見てよろしくやってくれるのかしらん?

package.json がきっと maven でいうところの pom.xml なのかなー、と勝手に想像(違うかもだけど)

Visual Studio Code

普段コードは基本的に言語を問わず Intellij IDEA で書くんだけど、今回は何となく Visual Studio Code を使ってみた。

主にマークダウンのメモ帳としか使ってないんだけど、ちゃんと覚えればかなり強力にコーディングもできるんだろうなぁ、という印象。

とりあえずフォーマットのショートカットキーは覚えた。でも多分明日には忘れる。。

qiita.com

ミートアップ

後半の懇親会的なやつは、作業していた席で基本そのまま実施。

立食形式とかじゃなくて助かる。。(人見知りには地獄になるので)

仕事何やってるのかとか、何で参加したのかとか他愛のない話。

ドットインストールのサービスの特性上そうなんだろうけど、若いエンジニア(志望含む)か、非エンジニアが多く参加している印象。

考えてみると、非エンジニアの人とプログラミングを介して話すことはそうないと思うので、いい機会だったのかもしれない。

ポエム

参加者の中に学生さんがいたんだけれども、これから就活らしい。

エンジニアになるのか、そうじゃないのかは知らんけども。

SIなのか、事業会社なのか、大企業なのか、ベンチャーなのか知らんけども。

きっとどこに行ってもそれなりに大変なことはあると思う(多分)。

でもそれらを補って余りあるほどの楽しいことがエンジニアリングの世界にはあると僕は思ってる。

それぞれの場所で、お互いがんばれたらいいね。

知らんけども。

構文解析ハンズオンに参加してきました #構文解析ハンズオン

ちょっと行ったことのない感じの勉強会に参加してきました。

lang-impl.connpass.com

GitHubにテストコードと回答の付いたソースコードがあって、cloneしてテストを通すようにする流れ。

午前中にイントロダクション的な講義があった後は、課題の説明→コード書く→解説を繰り返す感じだった。

扱った課題

  • 1桁整数
  • 非負整数
  • 単純な算術式
  • 一般的な算術式
    • 四則演算
    • ネスト可能
    • カッコによる優先順位変更
  • JSON

自分は一般的な算術式の途中までしか行けなかった。。

構文解析初挑戦

前提知識が何も無い中で挑んだので中々難しかった。

テストがあったので、テストが通るように自力の力技で進めてたんだけど、算術式あたりで限界を迎えた。

Qiitaでちょうど似たことを扱ってる記事があり、参考になった。

qiita.com

反省点としては、Javaとしての書き方やオブジェクト指向的な書き方(というか、普段コード書く時に最初に考えること)が先に来てしまって、構文解析の理解を妨げてしまった気がする。

たとえば、Stream使うとか、処理の共通化とか、状態管理(インデックス位置の扱い)なんかは、一旦脇においたほうがよかったかも。 (逆にいうと、Javaでやったけど、言語から一歩引いて処理の仕方を考えるというのは普段やらないことなのですごく刺激があった気はする。)

たぶん本当はBNFの方が重要で、BNFがしっかりできれば、あとはコードに落としこんでいくだけなのかなぁ、なんて思ったり。
(あぁ、だから構文解析器があるのか?)

残念ながらコードに落とし込む力が足りずにタイムオーバーでしたが。。

まとめ

  • 正規表現ではできないことを無理やり正規表現でどうにかしようとしているのを見かける、っていう話は印象に残った。

  • 構文解析の知識がついたかは自信ないけど、朝の11:00から夜19:30くらいまで、普段とは違う形で頭を使ったのはすごく有意義だったと思う。
    (最後の方は頭から煙出てた気がする)

  • 本格的な構文解析は考慮しなきゃいけないことさらにたくさん増えそうだし、自分が普段何気なく使ってるようなParserの凄さを実感した。

  • ちょっとドキドキしながら参加したけど、楽しい一日だった。

当日の資料

kmizu.github.io

モブプロに魔法感あった #mobProgramming #ちら裏

概要

もう最近はずっと、チームの作業は基本的にモブプログラミングになってる。(今は6人体制)

ちょっと印象に残る出来事があったので残しておく。

きっかけ

今進めている実装で、一部モヤモヤすることところがあった。

ちょっとテストがめんどくさかったり、どうもスマートさに欠けるというか。

んで、「この辺モヤモヤするよねー、何とかなんないかなー」となんとなしにつぶやいてみたんです。

そしたら

そこから議論が始まって。

設計というか実装方針とかが決まって。

実際に実装してみて(もちろんモブスタイルで)。

テスト通してうまくいって。

もっと良くなんないかなー、ってリファクタリングの議論して。

こうしてみたらどうだろ?って色々試して。

似たような感じのとこも適用できそうだったって展開して。

あっという間にスマートな実装に生まれ変わった。

すごくない?

もちろん自分も議論に参加したし、モブプロもしたんだけど。

なんかモヤモヤを吐き出したら、いつの間にか始まってあっという間にできあがった感じがして。

「魔法かよ!」って思いました(笑)

まとめ

もちろん銀の弾丸ではないんだけど、モブプロ最高なので続けて行きます。

ネストしたオブジェクトのマッピングする #MyBatis

MyBatisでネストしたオブジェクトマッピングするサンプルあんまり見かけないので、残しておく。

例えばこんなデータを

person

id name address_id
1 yamada 11
2 sato 11

address

id city
11 tokyo

book

id title
21 hoge
22 fuga
23 piyo

person_book

person_id book_id
1 21
1 22
2 23

こんなオブジェクトにマッピングしたい時。。

public class Person {
    private Address address;
    private List<Book> books;

    // アクセサは省略
}

こんな感じになる

<mapper>
    <resultMap id="personMap" type="Person">
         <id column="person_id"/>
         <association property="address" javaType="Address">
           <id property="id" column="address_id"/>
           <result property="city" column="address_city" />
         </association>
         <collection property="books" ofType="Book">
            <id property="id"  column="book_id"/>
            <result property="title" column="book_title"/>
        </collection>
    </resultMap>
    <select id="selectPerson" resultMap="personMap">
        select
            person.id     AS person_id
            address.id    AS address_id,
            address.city  AS address_city,
            book.id       AS book_id,
            book.title    AS book_title
        from
            person person
            inner join
            address address
                on person.address_id = address.id
            inner join
            person_book person_book
                on person.id = person_book.person_id
            inner join
            book book
                on person_book.book_id = book.id
        where
            person.id = 1
    </select>
</mapper>

<id> の指定を忘れない

TooManyResultsExceptionなどが発生してマッピングが期待通りに行かない時は、<id> の指定が漏れていないか確認してみる。

Personクラスではあえてネストしたオブジェクト以外のフィールドを持たせていないが、その場合でも必須になる。(オブジェクトにマッピングする必要がなくても、idは必要)

これはMyBatis側で生成するインスタンスを一意に判別する必要があるからだと思われる。

関連

su-kun1899.hatenablog.com

すでに存在するデータベースにFlywayを適用する(その2) #flyway

概要

下記記事の続き。

今度はbaselineの設定を活用して、SQLとFlywayの足並みを調整する。

su-kun1899.hatenablog.com

テスト用のデータベースを作る

create database if not exists flyway_sample character set utf8

flyway管理外のテーブルを追加する

mysql -u root -D flyway_sample_2
create table person (
    `person_id` int not null,
    `name` varchar(100) not null
);
create table hoge (
    `hoge_id` int not null,
    `name` varchar(100) not null
);

DDLを作成する

  • src/main/resources/db/migration
    • V1_0_0__create_person.sql
    • V1_0_1__create_hoge.sql
    • V1_2_0__create_fuga.sql
    • V1_2_1__create_piyo.sql

この場合、既にpesonテーブルとhogeテーブルは作成済のため、実際に適用したいのは V1_2_0 以降となる。

Baselineを設定する

pom.xmlにて、baselineOnMigratebaselineVersion を指定する。

baselineOnMigrateをtrueにして、baselineを有効化する。

baselineVersionは指定したバージョンがBaseline(適用済)となる。

つまり、1.0.1 を指定すると 1.2.0 移行のSQLがFlywayでMigrateされる

<build>
    <plugins>
        <plugin>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-maven-plugin</artifactId>
            <version>4.0.3</version>
            <configuration>
                <url>
                    jdbc:mysql://localhost:3306/flyway_sample
                </url>
                <user>root</user>
                <!-- Baselineの設定 -->
                <baselineOnMigrate>true</baselineOnMigrate>
                <baselineVersion>1.0.1</baselineVersion>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.6</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

flyway:migrate する

mvn flyway:migrate 
+---------+-----------------------+---------------------+---------+
| Version | Description           | Installed on        | State   |
+---------+-----------------------+---------------------+---------+
| 1.0.0   | create person         |                     | <Baseln |
| 1.0.1   | << Flyway Baseline >> |                     | <Baseln |
| 1.2.0   | create fuga           | 2017-06-08 09:51:07 | Success |
| 1.2.1   | create piyo           | 2017-06-08 09:51:07 | Success |
+---------+-----------------------+---------------------+---------+

注意事項

  • Baseline以前のDBの状態はユーザに委ねられるため、Flyway側では保証されない(当たり前だけど)
  • データベースが空の場合、Baselineが効かない?
    • 空なので、途中から流す必要ないので特に問題はないのだけれども

まとめ

flywayが好きだ。

すでに存在するデータベースにFlywayを適用する #flyway

概要

Baselineを使って、MySQL+Mavenで、FlywayによるDB構成管理を既に存在するデータベースに適用する。

Flyway by Boxfuse • Database Migrations Made Easy.

テスト用のデータベースを作る

create database if not exists flyway_sample character set utf8

flyway管理外のテーブルを追加する

mysql -u root -D flyway_sample
create table person (
    `person_id` int not null,
    `name` varchar(100) not null
);

pom.xmlにFlywayを追加する

<build>
    <plugins>
        <plugin>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-maven-plugin</artifactId>
            <version>4.0.3</version>
            <configuration>
                <url>
                    jdbc:mysql://localhost:3306/flyway_sample
                </url>
                <user>root</user>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.6</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

flyway:baselineを実行する

mvn flyway:baseline

schema_versionが作成される

mysql> show tables;
+-------------------------+
| Tables_in_flyway_sample |
+-------------------------+
| person                  |
| schema_version          |
+-------------------------+
2 rows in set (0.00 sec)

mysql> select * from schema_version;
+----------------+---------+-----------------------+----------+-----------------------+----------+--------------+---------------------+----------------+---------+
| installed_rank | version | description           | type     | script                | checksum | installed_by | installed_on        | execution_time | success |
+----------------+---------+-----------------------+----------+-----------------------+----------+--------------+---------------------+----------------+---------+
|              1 | 1       | << Flyway Baseline >> | BASELINE | << Flyway Baseline >> |     NULL | root         | 2017-06-08 09:27:41 |              0 |       1 |
+----------------+---------+-----------------------+----------+-----------------------+----------+--------------+---------------------+----------------+---------+

新しいDDLを追加する

src/main/resources/db/migration/V1_0_1__create_demo.sqlあたりに。

create table demo (
    `demo_id` int not null,
    `name` varchar(100) not null
);

flyway:migrateを実行する

mvn flyway:migrate

構成管理ができている

mysql> select * from schema_version;
+----------------+---------+-----------------------+----------+-------------------------+-------------+--------------+---------------------+----------------+---------+
| installed_rank | version | description           | type     | script                  | checksum    | installed_by | installed_on        | execution_time | success |
+----------------+---------+-----------------------+----------+-------------------------+-------------+--------------+---------------------+----------------+---------+
|              1 | 1       | << Flyway Baseline >> | BASELINE | << Flyway Baseline >>   |        NULL | root         | 2017-06-08 09:27:41 |              0 |       1 |
|              2 | 1.0.1   | create demo           | SQL      | V1_0_1__create_demo.sql | -1142022008 | root         | 2017-06-08 09:33:54 |            153 |       1 |
+----------------+---------+-----------------------+----------+-------------------------+-------------+--------------+---------------------+----------------+---------+
2 rows in set (0.00 sec)

まとめ

Flyway好きです。