RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのエンジニアブログ

ボーナスステージで実践するモブプログラミングのメリットとデメリット

id:radiocat です。今回はモブプログラミング Advent Calendar 2018の12日目の記事として投稿させて頂きます。久々のスクラム事例です。

qiita.com

私達のチームではスクラム開発の中で毎週モブプログラミング(以下モブプロ)をする時間を設けています。その名も「ボーナスステージ・モブプロ」です。

実践に至る経緯

まずは現在のモブプロのスタイルを実践するに至った経緯をご紹介します。

チームの知識共有

我々が開発を担当している楽楽精算はチームで開発を進めていくうえで以下の2点が課題となります。

  • 経理業務の知識
  • レガシーかつ経理業務に合わせた独特なシステム設計

例えば、今年リリースした iPhoneアプリ は精算時に使う領収書を撮影して保存することができますが、領収書を電子化して保存する経理業務の背後には「 電子帳簿保存法 」という法律があります。操作性やアーキテクチャの側面だけでなくお客様の経理業務への効果や影響も意識してシステムを実現する必要があるためチームの知識共有がとても重要になります。

メンバーの半分がチームにJOINして1年未満

体制の変更もあって経験と立場がそれぞれ違うメンバー構成となり、それまでのように知識豊富な一部のメンバーがリードして進めるスタイルの限界を感じていました。

f:id:radiocat:20181208190044p:plain:w500

スプリントにモブプロを取り入れてふりかえりで改善

モブプロには以前から実験的に取り組んでいましたが、これらの課題が明確になってきてからは思い切ってスプリントの一部に組み込むようになりました。はじめはスプリント計画時にモブプロでやったほうが良い開発タスクを決めてモブプロの時間を設けていました。しかし、モブプロのために全員のスケジュールが合う時間を調整しなければならずスプリントを進めるうえでの負担になってしまいました。ふりかえりでこのような課題を議論した結果、スプリントで計画するのではなくスプリントが終わってからモブプロするほうが取り組みやすいという結論になりました。

スプリント最終日の午後はモブプロタイム!

1週間スプリントの木曜は朝からスプリントレビューなので前日の水曜日は15時に開発が完了することを目標に計画していました。計画通りに終わればそれ以降は直前に開発した機能のPOレビューや翌日のスプリントレビューの準備、次のスプリントの準備の時間に充てます。計画より早く終われば改善などにも取り組むことができるので、この時間をボーナスステージと呼んでいます。モブプロに取り組むようになって試行錯誤の結果、このスケジュールをさらに繰り上げて開発完了目標を水曜午前中までとして、モブプロをボーナスステージに組み込むことにしました。

f:id:radiocat:20181208190921p:plain:w500

実装やコードレビューの中で「ここがわからない」「ここの知識が共有できていない」と気づいた部分は「今週のモブプロのお題にしよう!」と決めてリストアップしておき、ボーナスステージでテストコードを強化したりリファクタリングしたりしながらモブプロするようにしています。

スプリント中にモブプロすることを禁止しているわけではないですが、開発中はスプリントの完了を優先させて取り組み、ボーナスステージに突入してから落ち着いてモブプロに取り組むスタイルが定着しています。チームで決めたトレードオフスライダーの最上位が「納期」であることもこのスタイルが定着する要因のひとつと言えるかもしれません。

f:id:radiocat:20181209191718p:plain:w500

実践のポイント

モブプロを実践する中でチームで合意している取り決めがいくつかあります。

モブプロはあくまでボーナス

開発中にトラブルが起きて計画どおりに進められなかった場合、ボーナスステージは無くなります。その時は無理にモブプロをすることはしません。チームの最優先は「納期」なのでまた次のスプリントで頑張ってボーナスステージに突入できるように改善していくだけです。

知識の共有をメインにする

我々のチームのモブプロの目的は今のところ知識の共有なので、それ以外の目的でモブプロすることはしません。ボーナスステージに突入しても特に共有が必要なテーマがなければ無理にモブプロはしていません。逆に知識の共有が必要なことであればプログラミングに限らずモブの時間を取るようにしています。最近ではコードレビューふりかえりと呼んで、プログラミングの観点だけに絞ったふりかえりの時間を設けてより良いコードの書き方やコードレビュー観点などを議論する時間を取ってみたりもしています。

環境の共通化

我々のチームでは各自のノートPCを持ち寄ってモブプロしていますが、モブプロあるあるの課題としてドライバーを交代した時に他人の設定している環境が使いづらいという問題があります。そのため、チームで話し合ってモブプロのときに使用する最低限のIDEの設定などをいくつか決めています。個人で開発している時に設定を変えるのは自由ですが、モブプロの時にはみんな同じ設定で作業します。人によっては普段より効率が落ちるケースがあるかもしれませんが、事前にチームで話し合って決めたルールなのでモブプロの時は合わせてもらいます。事前に決めておくことで、モブプロの時に突然設定が変わって戸惑うことも少ないですし、事前に設定して慣れておくこともできます。

メリット

このようなモブプロの実践についてメリットを考えてみました。

生産性の話をしなくていい

モブプロを実践するうえで最も議論になるのが生産性の話です。1つのプログラムをチーム全員でプログラミングするのは効率が悪いのではないか?というヤツです。 しかし我々のやり方の場合、スプリントの開発は既に終わっています。やるべき事をやったので、もっと良くするために知識を共有する目的でモブプロをやっているだけなので少なくとも開発チーム内で生産性の議論をする必要がありません。生産性の議論をしなくて良いのはモブプロを実践するうえで非常に取り組みやすい状況です。

安心して開発に集中できる

「知識の共有」と言うのは簡単ですが、知らない事を知るという意味では言うほど簡単な事ではありません。1週間という短いスプリントの中でメンバー間の知識差に気づいた時には、時間的にも精神的にもそれほど猶予はない状態なので、「じゃあちょっとモブプロでもしようか」とはならないのです。「ここはひとまずこのまま進めておいて、あとでみんなでモブプロしながらリファクタリングしよう」と言えるのはチームにとって非常に強力な手段となります。

ボーナスステージへのモチベーションが上がる

なんだかんだ言ってみんなで集まってワイガヤしながらプログラミングするのは楽しいです。1週間のスプリントを無事に終えてリラックスしながら、成果物をさらに良くしていくというのはスプリントを早く終わらせてモブプロしようというモチベーションにも繋がります。

デメリット

モブプロ自体のデメリットではありませんが、ボーナスステージで実践することにはいくつかリスクがあります。意識して取り組めば回避可能なので紹介しておきます。

デグレードのリスクがある

スプリントの最後にモブプロでリファクタリングするということは完成したものに手を加えるということなのでデグレードを起こすリスクがあります。翌日は朝からスプリントレビューなので、完成したはずの機能が万が一動かなくなっていたらスプリントでやってきたことが全て水の泡です。そこまで大事には至らなかったものの、実際に我々もデグレードを起こしてしまったことがあります。そのため我々はモブプロを行ったあとに一通りの機能を再度テストをして終わるようにしています。

予定が立てにくい

ボーナスステージというのはうまくいけば訪れるものなので、事前に計画することができません。モブプロしようと思ったら全員が集まれる場所が確保できなかったということも起こりえます。デイリースクラムで日々の状況をうかがいながら先回りして予定を確保する必要があります。

もっとできるのにがんばらないリスク

スプリント終わりにモブプロをするのを「ありき」にしてしまうと、その分の余裕をみて計画を立ててしまいます。しかしそれではチームのパフォーマンスは上がっていきません。あくまでスプリントで出来ることを出来るだけこなしたうえで、余裕があればモブプロを実行するのが理想です。POやステークホルダがもっとたくさん作って欲しいと思っているのに開発チームがスプリントを早めに切り上げてモブプロしているような状態になってしまうとモブプロの意義も疑われてしまいます。これはスクラムマスターがしっかり状況を判断してコントロールしなければなりません。

まとめ

我々のチームでは知識の共有を目的としてモブプロを実践することでチーム力を強化してきました。最近ではスプリント計画時にもこれからモブプロをするかのように、みんなでプログラムを見ながら「ここをこうするんだ」と議論して計画を立てるようになりました。新たに若手のメンバーも迎え入れてチームを強化している最中で、学習をテーマにしたモブプロも実践してみたいと話をしています。

f:id:radiocat:20181209193216p:plain:w500

このように我々はチームを前進させるために目的を決めてモブプロを取り入れています。モブプロには他にも様々な効果があると思いますが、目的を絞って取り組んでみると改善点も明確になるのでチームに定着させやすいと感じています。


お知らせ

楽楽精算開発チームでは1年前からスクラム開発を取り入れて実践してきました。これらの取り組みを2月に行われる Scrum Fest Osaka 2019 ご紹介できればと思い応募していますので、よろしければ投票お願いします。

confengine.com

Dockerのコンテナ間通信~アプリとDBを繋ぐ~

sts-250rrです。

今回はラクス Advent Calendar 2018に投稿した記事、「開発環境を作るためにDockerを使った話」の続きになります。

qiita.com

はじめに

前回の記事ではDockerで開発環境を作ってみました。
が、このままではあまりにもチープな構成に感じます。。。

今回はコンテナ間通信を使って別コンテナに作成したDBのデータを取得できるような構成を作っていくことを目標とします。
目標とする形は以下のようなイメージです。

f:id:sts-250rr:20181209170703p:plain

Dockerネットワークを作成してコンテナ間通信

コンテナ間通信を実現するために、Dockerネットワークを作成します。 Dockerネットワークはコンテナ名を指定することでアプリ用(開発環境用)のコンテナからDBコンテナに接続することができるようになります。

まずはDockerネットワークを作っていきます。

$ docker network create my-network
cbe89848f313a1b7766780903f79da2ff3a83bbe962f930c1f3caf9136fbac6f

$ docker network ls
NETWORK ID          NAME                     DRIVER              SCOPE
39d283374d44        bridge                   bridge              local
a3d0faef3da4        host                     host                local
cbe89848f313        my-network               bridge              local
7b1a7347c6b9        none                     null                local

以下のコマンドでDockerネットワークの詳細を確認することができます。

$ docker network inspect my-network
[
    {
        "Name": "my-network",
        "Id": "cbe89848f313a1b7766780903f79da2ff3a83bbe962f930c1f3caf9136fbac6f",
        "Created": "2018-12-09T02:41:41.8124636Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

作成したてのDockerネットワークなので何も登録されておらず、Containers部分が空っぽです。
コンテナ起動時にこのDockerネットワークを指定することで、同一のネットワークにコンテナが作成されるため、コンテナ間通信ができるようになります。 ※細かい部分は詰められていません。

開発環境(Go)・PostgreSQLコンテナの起動

コンテナを起動して、開発環境コンテナのGoプログラムからPostgreSQLコンテナのDBに接続出来るような環境構築を行なっていきます。
今回もdocker-composeを利用していくのでディレクトリ構成・ファイルを以下のように作成します。

<任意のディレクトリ>
|-- init
|      |-- 1_createdb.sql
|-- Dockerfile
|-- docker-compose.yml
|-- main.go

今回、main.goからPostgreSQLコンテナのDBに接続するために各設定ファイルやDBの初期構築が必要になります。
各ファイルは以下のように作成します。

docker-compose.yml
version: '3'
services:
  postgres:
    image: postgres
    environment:
      POSTGRES_USER: postgres # user
      POSTGRES_PASSWORD: postgres # pass
    ports:
      - "5432:5432"
    volumes:
      - ./db:/docker-entrypoint-initdb.d
    networks:
      - my-network
  app:
    build: .
    ports:
      - "8080:8080"
    networks:
      - my-network
volumes:
  test_db:
    external: false
networks:
  my-network:
    external: true
Dockerfile
#ベースのDockerイメージをgolangで指定
FROM golang:latest
EXPOSE 5000

#ワークディレクトリを設定する
WORKDIR /go
#ホストのディレクトリを/go配下にコピー
ADD . /go
#GOPATHの設定
ENV GOPATH $GOPATH:$HOME/go
RUN go get github.com/jinzhu/gorm
RUN go get github.com/lib/pq

#main.goを実行
CMD ["go", "run", "main.go"]
1_createdb.sql
create database testdb;
main.go

main.goはこちらを参考にさせていただきました。 実行するとDBに登録されているIDと名前を出力します。

qiita.com

package main

import (
   "fmt"

   "github.com/jinzhu/gorm"
   _ "github.com/lib/pq"
)

type User struct {
   ID int64 `gorm:"primary_key" json:"id"`
   Name string `json:"name"`
}

type Users []User

func main() {
   db, err := gorm.Open("postgres", "host=172.24.0.3 user=postgres port=5432 password=postgres dbname=testdb sslmode=disable")
   if err != nil {
      panic(err)
   }
   defer db.Close()
   db.AutoMigrate(User{})
   var user = User{Name: "testname"}
   db.NewRecord(user)
   db.Create(&user)
   db.Save(&user)

   var users = Users{}
   db.Find(&users) 
   fmt.Println(users)
}

さて、ファイルが揃ったら、docker-compose builddocker-compose upを実行すれば、main.goの実行結果が得られます。

(略)
postgres_1  | 2018-12-09 06:32:23.787 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1  | 2018-12-09 06:32:23.829 UTC [58] LOG:  database system was shut down at 2018-12-09 06:32:23 UTC
postgres_1  | 2018-12-09 06:32:23.851 UTC [1] LOG:  database system is ready to accept connections
app_1       | [{1 testname}]
app_app_1 exited with code 0

postgres_1 |app_1 |といった形でコンテナごとの出力結果が得られています。app_1 | [{1 testname}]と出力されているのでなんだかいけてそうな気がします。

これだけではピンとこないのでPostgreSQLコンテナに入ってDBを確認してみると、

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
f9a9ed9b3fc8        postgres            "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes        0.0.0.0:5432->5432/tcp   app_postgres_1
$ docker exec -it app_postgres_1 bash
root@f9a9ed9b3fc8:/# psql -U postgres testdb
psql (11.1 (Debian 11.1-1.pgdg90+1))
Type "help" for help.

testdb=# select * from users;
 id |   name   
----+----------
  1 | testname
(1 rows)

PostgreSQLコンテナの内容と開発環境コンテナのmain.go実行時の内容が一致するので正しく値を取得できているようです。

最後にDockerネットワークの状態を確認します。

docker network inspect my-network
[
    {
        "Name": "my-network",
        "Id": "e77a834d8aff49e316e7ab153666232eab35f7fe4350b18be19da1d608125c4b",
        "Created": "2018-12-09T06:25:02.1986525Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.24.0.0/16",
                    "Gateway": "172.24.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "f9a9ed9b3fc8b67232edb76ec4202e0b66ec776dbd0665db7f9ee11341088571": {
                "Name": "app_postgres_1",
                "EndpointID": "6dfd276d55c4352668364de97a588ca5072bf5ee647b8b9dbe5cbdc04d8603f1",
                "MacAddress": "02:42:ac:18:00:03",
                "IPv4Address": "172.24.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

Go側のコンテナは実行完了と同時に停止してしまうので、Containersには表示されていませんが、Postgresコンテナがmy-network内に含まれていることがわかります。

色々複雑でしたが、コンテナ間通信ができる開発環境、無事完成です。

今回のポイント

Goのパッケージインポート

ローカルでGoを書く時にも必要なことですが、軽く詰まりました。
main.goの中でGithubからパッケージをインポートしていますが、事前にGOPATHを設定したり、go getでGitリモートリポジトリをダウンロードしておかなければならなかったようです。
Dockerコンテナでもこれは同様なのでDockerfile上でENVやRUNで必要な事前処理を行っていますが、詰まったのはRUNでgo getを実行する部分です。
はじめはCMDで実行していましたが、main.go実行時にこうなります。

app_1  | main.go:6:4: cannot find package "github.com/jinzhu/gorm" in any of:
app_1  |    /usr/local/go/src/github.com/jinzhu/gorm (from $GOROOT)
app_1  |    /go/src/github.com/jinzhu/gorm (from $GOPATH)
app_1  |    /go/src/src/github.com/jinzhu/gorm
app_1  | main.go:7:4: cannot find package "github.com/lib/pq" in any of:
app_1  |    /usr/local/go/src/github.com/lib/pq (from $GOROOT)
app_1  |    /go/src/github.com/lib/pq (from $GOPATH)
app_1  |    /go/src/src/github.com/lib/pq
app_app_1 exited with code 1

パッケージ見つからないよ。という旨のエラーですね。
調べてみたらRUNとCMDでこんな違いがありました。

qiita.com

深くまで追えていませんがイメージ作成時に実行しておかないとmain.goの実行時にはDLが完了できないとかなんでしょうか?

PostgreSQLコンテナで初期DB構築を行う

PostgreSQLコンテナをただ作るのみではもちろんDBの作成はしていないので、接続に失敗します。かといって毎回コンテナを起動するたびに手動で作成するのはDockerの利点を潰してしまっていますよね。

そんなことをしなくて良いようにDockerhubの公式のイメージには便利機能がありました。

If you would like to do additional initialization in an image derived from this one, add one or more .sql, .sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d (creating the directory if necessary).

/docker-entrypoint-initdb.dというディレクトリに.sql.shのファイルを配置しておけば起動時に実行してくれるみたいです。

ということで、docker-compose.ymlvolumes:init以下の1_createdb.sqldocker-entrypoint-initdb.dに配置し、createdbを実行していました。

実は・・・

必要なファイルが揃えば、さも簡単に実行できるかのように書いていますが、1度目の実行はほぼ必ず失敗します。 というのも1度目の実行ではDockerネットワーク上のPostgreSQLコンテナに割り振られるIPがわからないためです。。。 main.goの中で接続先のDBのあるIPを指定しているので、その部分でコケます。 多分何かしらいい方法があるんだと思いますが、現時点では見つからず。。。

良い方法があれば教えていただきたいです。。。

まとめ

今回はDockerネットワークを使ってGoアプリとDBを接続してみました。 アプリのコンテナとDBを分けることができ、なんだかそれらしくなってきたような気がします。 Dockerやdocker-composeがよしなにやってくれる分、上手くいかなかった時にはどこに問題があるのかを見つけるのが大変です。 その分出来上がってしまえば作り直しや複製が簡単にできてしまうので、便利であることに変わりはないですね。

個人的には、「実は・・・」でお伝えした部分はなんとか解決したいものです。。。

『Rakus Meetup Osaka #1 大阪開発チームのチャレンジ紹介』のふりかえり

id:radiocat です。以前 ご案内 したとおり11/27に大阪オフィス初のMeetupを開催しました。

f:id:radiocat:20181203213901p:plain:w500

今回はMeetupのご報告とともに、運営で得た知見などを少しだけご紹介します。

大阪開発チームのチャレンジ紹介

今回は次の3つのチャレンジをご紹介しました。

チャットディーラーの高速開発を支えるLaravel

f:id:radiocat:20181203214820p:plain:w500

今年夏に登壇させて頂いた PHPカンファレンス関西 2018 の内容 をベースに、Laravel導入のチャレンジとそこで得た知見をお伝えしました。Vue.jsと格闘したエピソードでは前回登壇時には無かった開発メンバーの生の声を加えることで、大阪開発チームらしさもお伝えできたと思います。

speakerdeck.com

Why Mob Programming? - モブプロという働き方 -

f:id:radiocat:20181127193218j:plain:w500

モブプロに取り組み始めた経緯、はじめ方、やってみて良かったこと、悪かったことなど、アジャイルを推進する開発現場のモブプロへのチャレンジと得た知見を余すことなくお伝えしました。本編のスライドに使用されている写真は移転前のオフィスで撮影されたものでしたが、唯一、新オフィスで撮影した一番最後のスライドの「俺たちの戦いはこれからだ!」っぽい雰囲気もまたチャレンジ感をお伝えできたのではないかと思います。

speakerdeck.com

トウダン・ジャーニー

f:id:radiocat:20181127200057j:plain:w500

1つ目の発表にあるPHPカンファレンス関西 2018への登壇に向けて開発組織を横断した登壇推進チームを結成して取り組んだチャレンジについてお伝えしました。既に次の登壇も決まっており、社内チャットにさりげなく釣り針を落とすことから始まった登壇へのジャーニーは今後もまだまだ続きます。

speakerdeck.com

Meetupへのチャレンジ

今回、私自身はMeetupの運営にチャレンジしました。運営のチャレンジで特に大切だったことは次の2つです。

イベントのテーマを何にするか?

Meetupのテーマを何にするかは運営にとって最初の大きな課題でした。そもそもテーマを絞る必要があるのか?という疑問もありました。しかし、せっかく仕事終わりの時間を使って多くのかたに集まってもらうので、我々がどんなイベントにしようとしてるのかをイメージしてもらえる程度にテーマを絞るべきと考えました。特定の技術テーマに絞ることも考えましたが、初めてということもあるのでまずは大阪オフィスと開発チームの雰囲気を知ってもらうのが良いだろうと考えました。

「チャレンジ」というのはチャレンジそのものではなく、チャレンジを実践して結果を出したその場に価値があると思います。つまり、チャレンジというキーワードを通して「開発の現場」を知ってもらうことが大事だと考えました。そして、社内のビアバッシュで「Meetupをはじめよう」というLTを行ってこの思いを開発チームのメンバーに共有しました( その模様は『 大阪開発ビアバッシュ~11月「新機能特集」 』で投稿していますのでご確認ください)。

f:id:radiocat:20181204214246p:plain:w500

今回、登壇を引き受けてくれたメンバーはその思いを汲み取ってそれぞれの視点でエンジニアの現場のエッセンスを発表に盛り込んで伝えてもらえたと思います。

LTをやりたい!

イベントの運営を引き受けるうえで、もうひとつ大切にしたかったのが次の2つを軸とした交流です。

  • 大阪の梅田という地域性
  • エンジニアの楽しみ

ここ数年で大阪でもたくさんの勉強会イベントが日々開催されるようになり、我々も一緒に大阪のコミュニティを盛り上げたいという思いがあります。また、社内外のエンジニアの交流を深めることで、エンジニアが楽しみながら成長していける場にしていけたらという思いもあります。社外の勉強会には私もよく参加させて頂いてたくさん情報交換させて頂いていますが、逆の立場で自社でもイベントを開催し、社外と社内が混ざり合って交流することで2つの軸はさらに強くなると思います。

そこで、LTを募集して参加者の方々にもイベントの一部に加わって頂くことで、この2つを軸とした交流をさらに深めたいと考えました。ただ、弊社が主催するイベントということもあり、本編のセッションと繋げてしまうとLTして頂く側からするとやりにくさもありそうなので、本編のセッションが終わったところで一区切り入れて交流会の中でLTして頂くことにしました。

交流会をスタートしてからLTに入るタイミングや進め方などはまだまだ改善の余地があると感じていますが、運営側の願いどおりの楽しみながら交流できるLTセッションにして頂けました。LTに応募して頂いた皆様、本当にありがとうございました。

おわりに

運営のチャレンジは始まったばかりで課題もたくさんありますが、フィードバックもたくさん頂きましたので得られたものも大きいです。今後につなげて継続的に開催していきたいと思います。

次回は2月頃に開催を予定

詳細が決まり次第、connpassに公開します。

もくもく勉強会も計画中

1月から月1回程度のペースでもくもく勉強会の開催も計画しています。こちらも決まり次第、connpassに公開します。

rakus.connpass.com

今後もこのようなイベントを企画してエンジニアを楽しくするための交流の場をつくっていければと思います。ぜひご参加をお待ちしております。

f:id:radiocat:20181203224844p:plain:w500

お知らせ

ラクス Advent Calendar 2018を実施中!

毎年恒例のアドベントカレンダーが今年も始まっています。ラクスのメンバーがこの1年間で集めたそれぞれのネタをつないでリレーしていますのでぜひご覧ください!

qiita.com

Scrum Fest Osaka 2019に応募しています

大阪では2月に Scrum Fest Osaka 2019 という大きなイベントが開催される予定で、現在セッション公募が行われています。私も楽楽精算開発チームのスクラムの取り組みをご紹介できればと思い応募していますので、よろしければ投票お願いします。

confengine.com

振り返りの手法を理解しよう~KPT法編~

はじめに

こんにちは、@rs_tukki です。
以前id:radiocatさんが記事にされていましたが、効率よくプロジェクトを進めるにあたって、「振り返り」を行うことは非常に大切です。
今回は、その「振り返り」の手法のひとつ、KPT法について話したいと思います。

tech-blog.rakus.co.jp

振り返りとは

振り返る
読み方:ふりかえる

(1)身体を翻して後方を見る、後ろ側を向く、などの意味の表現。
(2)過去の物事を顧みる、思い起こすこと。回顧すること。
(3)これまで行われてきた物事の一連の流れを総括すること。

引用:振り返る(ふりかえる)の意味や定義 Weblio辞書

今回扱う、プロジェクトを進めるにあたっての「振り返り」は、このうちの(3)にあたります。
ここまで実施したことの内容と結果、それを通じて学んだことをメンバー全員で確認することで、これから実施することを見直し、改善していく作業のことを指します。
特にアジャイル開発を採用したプロジェクトだとスプリントごとに行うことが多いですが、開発現場に限らずとも、複数人で何かを進めていく場では、よりよい方向を目指すために役立ちます。

なぜ振り返りが大切なのか?

「振り返り」という言葉だけでは、「反省」と勘違いされることがあります。
しかし、反省が、過去の失敗がなぜ起こったのか、という原因の追及を行うのに対して、振り返りは、目標にしていたことが達成できたか達成できたのなら次の目標はどうするか達成できなかったのならどうすれば達成できるようになるのか、という考え方のもとに進めていきます。
次の仕事をより効率よく改善していくためには、単なる「反省」ではなく、「振り返り」を実施することが大切なのです。

KPT

KPT法とは、振り返りの手法として用いられている枠組みの1つです。 今までの仕事の中で感じたことを、
一人ずつ「Keep」「Problem」の二つに分けて挙げてもらい、議題とします。その中から次の改善案となる取り組みを「Try」として選び実施していきます。

元々はAlistair Cockburn氏が2004年の著書で提唱した理論を、平鍋 健児氏がKPTと呼んだのが始まりのようです。既に15年近くも使われている伝統の手法みたいですね。

tbpgr.hatenablog.com

f:id:rs_tukki:20181204161628p:plain

K ~Keep:継続すべきこと~

Kには、実施してよかったこと、今後も継続して実施していきたいことが入ります。

例えば、新機能の開発を行うとき、複雑なコードをモブプログラミングで実装したとします。その機能が大きなバグもなく、スムーズにリリースできたというKeepがあれば、モブプログラミングの実施は効果があった、という判断ができ、またそれを提案した人が達成感を覚える機会にもなります。

P ~Problem:問題だと思うこと~

一方でPには、失敗したこと、これから改善していきたいことが入ります。

例えば、バグの修正を行うとき、影響範囲がどこなのか、よく調べずに取り組んでしまったとします。
結果、修正に余計な時間がかかってしまった、別のところにバグが発生してしまった、というProblemがあれば、その問題を共有するとともに、改善へ向けた意識付けができます。

ここで問題なのは、先ほど書いたように原因の追及をしないということです。
起こってしまった問題に対して個人を攻撃するのではなく、どうすれば改善できるか、を考えることが大事です。

T ~Try:改善していくこと~

最後にTは、今まで挙がった内容を踏まえて、次の機会にどのように実施していくかのまとめが入ります。 上記の例で言えばモブプログラミングによる効率を上げるために、より多くの機能でモブプログラミングを実践する、
あるいはバグ修正の手戻りをなくすために、修正方針をレビューしてもらう、といった形です。
そして次回のKPTでは、今回Tryに挙げたことがまたKやPに入り、更なる改善を目指していくのです。

f:id:rs_tukki:20181204161701p:plain

KPT法のメリット

振り返りの手法には、有名なものでPDCA*1がありますが、こちらではそれぞれの中で具体的にどのようなことをすればいいのかが曖昧です。
KPT法では、PDCAの中のCAに絞った手法を具体的に示しているので、初めて振り返りをする場合でも、何を確認して何を話し合えばいいのか分かりやすいのがメリットと言えます。

実践例

以下の画像は、私たちのチームで毎年実施しているとあるプロジェクトのKPTです。

f:id:rs_tukki:20181204161720p:plain

特別な道具を用いる必要はなく、一つのExcelファイルへメンバーが一人ひとり自由に記載してもらっています。
ここで重要なことは、意見の被りを気にしないことと、プロジェクトを実施するたびに行うことです。意見が被るということは、それだけ多くの人が同じことを感じているということですので、それだけ継続、あるいは改善の優先度が高まります。Problemの全てをTryにするのが難しい場合でも、意見の数を参考にTryにすること、しないことを判断できるのです。
また、KPTは1回で終えるのではなく、都度繰り返し実施することで、よりよいプロジェクトになっていくのではないかと思います。

おわりに

今回は、チームのプロジェクトを進めるにあたって振り返りが必要なこと、またその手法の一つとしてKPT法を紹介いたしました。
実施したことを適切に振り返り、改善していけば、効率が格段にアップするはずですので、ぜひ一度試してみてください。

参考

Alistair.Cockburn.us | Reflection workshop
「振り返り」をするかしないか、で変わること。振り返りは、未来の自分へのアドバイス…? | トレマガ
2018年の目標設定にも使える! “振り返り”に役立つ5つのフレームワーク|ferret [フェレット]
KPTとは | ふりかえりのフレームワーク・進め方・成功のコツ・ポイント | ビヨンド(Beyond)

*1:計画[Plan]、実行[Do]、評価[Check]、改善[Action]を繰り返していく手法のこと。

サークル活動を紹介します!

こんにちは、fuj_takです。

今回はラクスのサークル活動について紹介します!

サークル活動について

サークル活動は、ラクスで働くにあたって、モチベーション向上や信頼関係を築くこと、ワークライフバランスを充実させることを目的としています。 また、サークル活動に対して会社からの補助を受ける事ができます。

業務に近い内容だけでなく、趣味を通じて交流を図るサークルなど様々で

などです。 その他にも多数のサークルがあります。

ボードゲームサークル

私が参加しているサークルは「ボードゲームサークル」です。 平日の業務時間後、課/部署問わず色々なメンバーが参加しています。

ボードゲームといっても、広く知られている人生ゲームやモノポリーではなく、

といったもので、今まで名前を聞いた事がないものばかりでした。 始めはルールに混乱するのですが、一度やってみると大体ルールを理解できるようになりました。 どれも奥が深く、日頃パソコンやスマホにばかり目を向けている自分にはとても新鮮で楽しいです。

日頃なかなかコミュニケーションを取りづらいメンバーともボードゲームを通じて交流を図れるので、社内の交流の幅も広がるし、リフレッシュにもなるんですよね。

f:id:fuj_tak:20181126084740j:plain f:id:fuj_tak:20181126084802j:plain f:id:fuj_tak:20181126084828j:plain

私のおすすめはドミニオンです! ゲームのルールを様々なバリエーションで組み合わせられるので、毎回違った面白さがあるんですよ。 こんな名前のカードがあって、なんか心をくすぐられます。

  • 地下貯蔵庫
  • 宰相
  • 海の妖婆
  • 策士

わが子が成長したら一緒にやろうともくろんでいます。 まだ1歳と3歳なので今は一緒にできませんが(笑)。

社内に広いリフレッシュスペースも備えているため、ボードゲームだけでなく様々な活動で社内の環境を活用できるようになっています。 www.wantedly.com

ラクスでは業務だけでなく、サークル活動などのワークライフバランスも意識しています。 業務もサークルも楽しみながら、楽しいエンジニアライフを送っていきたいと思います!

大阪開発ビアバッシュ~11月「新機能特集」~

こんにちは。エンジニアのmickey-STRANGEです。

はじめに

今回は先日、大阪オフィスで開催された11月ビアバッシュをご紹介いたします。
前回のビアバッシュ記事はこちら↓ tech-blog.rakus.co.jp

テーマ発表

11月のビアバッシュのテーマは新機能特集でした。ラクスの各製品の開発者にこんな機能作った、ここがんばったよ、ここ苦労した、というお話をしていただきました。
また、テーマ発表の後にはLT発表もあり、内容たっぷりのビアバッシュでした。

Mail Dealer

今後リリース予定の機能についての発表でした。
いきなりですが、未リリース機能なので、内容は社外秘。本ブログでお伝えすることは出来ません…
ですが、求められる要件と実装面の課題との狭間での激しい闘いのお話を聞くことが出来ました。

f:id:mickey-STRANGE:20181128161149p:plain

配配メール

今年7月にリリースした配配メールv5.0の機能についての発表でした。
配配メールv5.0ではデザイン変更、複数ユーザ対応を実施したそうですが、デザイン変更は全画面ですし、複数ユーザ対応も権限など全機能に関わる部分があり、圧倒的なタスク量だったとのことです。
改修対象ソースの洗い出しや、全画面の現状確認+テストに苦労したというお話を聞くことが出来ました。

f:id:mickey-STRANGE:20181126190349p:plain

楽楽精算

楽楽精算では、ユーザ操作を自動化する機能を開発しており、その中でもiOSアプリについての発表でした。
iOSアプリは、領収書明細の自動入力を実現しています。※電子帳簿保存法オプション必須の機能
図メインのスライドになると何故か右から左の資料になっている点が気になりました。

f:id:mickey-STRANGE:20181126191237p:plain

Chat Dealer

既存機能のチャットボットを強化する新機能として開発された「ボットレポート」についての発表でした。
使用中のチャットボットの設定をブラッシュアップするために使用される機能で、実際にデモを交えて解説していただきました。
チャットボットの設定画面がそこはかとなく働くDBの自動処理設定に似ている気がしたのは私だけではありませんでした。

f:id:mickey-STRANGE:20181126193849p:plain

働くDB

自動処理ジャンプパーツについての発表でした。
オプション機能ですが、ジャンプパーツを使用することによって、条件分岐後に同じ処理をする場合の設定がきれいになるそうです。
before-afterを例で挙げていただきましたが、たしかにパーツ数が減って見やすくなっている気がします。

f:id:mickey-STRANGE:20181126195138p:plain f:id:mickey-STRANGE:20181126195147p:plain

LT発表

LT発表は3人の発表者が登壇してくださいました。
内容は自由で、テーマに関係なく、思うままに発表していただきました。

街ブラUIレビュー

以前にも街中のBAD UIを発表して下さった方が、その続編ともいえる内容での発表でした。
言い回しのおかしい説明や、何かを目立たせるための強引な注意書きは定番の内容ですが、発表の中で気になったのが下の写真です。「電光掲示板を見たあと絶対に時計を確認しますよね」と聞いたときのアハ体験がとても印象的でした。

f:id:mickey-STRANGE:20181126201452p:plain

CIフレンドリなDBドキュメント生成ツールでドキュメントの最新を維持し続ける

外部スライドを使用してのツール紹介の発表でした。
tblsというツールの紹介でしたが、肥大化したDBに対して、後付けでテーブル定義をすぐに作成できるというのは非常に魅力的なツールだと感じました。

speakerdeck.com github.com

Meetupをはじめよう

先日開催されました、Rakus Meetup Osaka #1についての発表でした。
なぜ開催するのか、開催すると何が嬉しいのか、から始まり、開催するにあたっての心構えまでをまとめて発表していただきました。

f:id:mickey-STRANGE:20181126203641p:plain

おわりに

11月のビアバッシュをダイジェストでお送りいたしましたが、いかがでしたでしょうか。

各製品の新機能/オプションについて気になった方は、
・ご利用中のお客様は、サポート窓口もしくは各製品のサポートサイト
・新規でご検討のお客様は、製品ページからのお問い合わせ
にて詳細をご確認くださいませ。

Laravel を使ったアプリを Heroku へデプロイする Tips

f:id:Y-Kanoh:20181120141531p:plain

最近、自宅で Laravel を使ったアプリを作成しています。 せっかく作ったアプリなので、公開しようとしたのですが、あくまで趣味の範囲であり、有料の環境を使おうとは思えず、Heroku へデプロイすることにしました。 今回は、Heroku でLaravel アプリをデプロイするための手順を簡単に説明します。

前準備

Heroku のアカウント作成と、Heroku CLI のインストールは事前に済ませてください。

Profile の作成

Heroku アプリの設定値を書き込む Profile を Laravel プロジェクトの直下に作成し、以下の内容を書き込みます。 これにより、Webサーバに Apache を使用し、Laravel の public ディレクトリをドキュメントルートにすることができます。

web: vendor/bin/heroku-php-apache2 public/

ファイルを作成次第、master ブランチに Profile を commit します。

.envファイルについて

Laravel の .env ファイルでは、ローカルの環境変数を設定できます。 Heroku へのデプロイは、Git を用いてリポジトリを Heroku へ push することで行うため、 git の管理外である .env ファイルを Heroku へ設置できません。 そのため、config ディレクトリ内の環境変数を Heroku 環境で使用したい値に変更しておきます。

Heroku アプリ作成

Laravelアプリのディレクトリに移動し、heroku loginコマンドでメールアドレスとパスワードを入力し、Heroku にログインします。 その後、Heroku へ PHP アプリを作成するために、heroku createコマンドを実行します。

> heroku login
heroku: Enter your login credentials
Email [xxxx.xx.xx@xxx.xx]:
Password: *******
Logged in as xxxx.xx.xx@xxx.xx

> heroku create my-app

実行できたら、heroku appsコマンドを実行することで、Heroku にアプリケーションが増えていることがわかります。

Heroku へ push する

Heroku へアプリが追加出来たら、作成したプロジェクトを Heroku へデプロイします。 デプロイと言えど、やることは Heroku へ master ブランチを push するだけです。

> git push heroku master

少し時間がかかりますが、push ができればデプロイ完了です。

メールの送信設定

作成していたアプリでは、メールを送信する必要がありました。しかし、Heroku から直接メールを送信することはできないので、他の方法を考える必要があります。 今回は、Gmail に対して SMTP 接続を行い、メールを Gmail を用いて送信するようにしました。 手順としては、Google アカウントにて、GmailSMTP 接続を許可したうえで、config/mail.php環境変数を以下のように変更します。

'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp.gmail.com'),
'port' => env('MAIL_PORT', 465),
'from' => [
        'address' => env('MAIL_FROM_ADDRESS', 'my.gmail@gmail.com'),
        'name' => env('MAIL_FROM_NAME', 'Fromの名前'),
    ],
'encryption' => env('MAIL_ENCRYPTION', 'ssl'),
'username' => env('MAIL_USERNAME', 'my.gmail@gmail.com'),
'password' => env('MAIL_PASSWORD', 'xxxxxxxxxxxxxxxx'), // Gmail設定時のパスワード文字列

これにより、Laravel アプリからメールを送信することができるようになります。

その他

その他、Heroku ではカスタム次第でいろいろな機能が使えます。 ちょっとしたアプリ作成や、実装の練習成果を公開する場合は、非常に便利ですね。

参考サイト

qiita.com

Copyright © RAKUS Co., Ltd. All rights reserved.