FOLIOで学んだマネジメントやリーン開発の知識を本の執筆に活かす

これは、FOLIO Advent Calendar 2018 5日目の記事です。

FOLIOでは2年目のアドベントカレンダー!クリエイターも増えて、去年とはまた違うメンバーで埋まっていて毎日楽しみです。

突然ですが、今月生まれて初めての著書が出ます(@syobochimと共著)。

book.impress.co.jp

出版社の方とコンタクトを取り始めたのは1月だったので、おおよそ1年近いプロジェクトを終えたことになります。実際に書いていた期間はもっと短い(後述)ですが、いわゆるスタートアップであり日々全力疾走するFOLIOで社員をやりながら、業務時間中には一切執筆作業をすることなく*1なんとかやり遂げることができました。

ここまで来られたのは、JavaコミュニティそしてFOLIO、この2つのおかげだと思っています。この記事では後者にフォーカスし、書く際のプロセスや心構えについて考えていきます。一方、前者に関することも、また発売後に別の記事にしたいと考えています。そちらは、多少本の内容にも触れたものにする予定です。

😌モチベーションとの戦いを制する「気合い」以外の方法

今回の執筆は、書く内容自体の難易度が自分のレベルよりも高いわけではなかったし、文章を書くことにはあまり抵抗がないし、自分を突き動かすことこそがポイントでした。そして、年齢を重ねるごとに改善はしているものの、自分は何よりそれが苦手なのです。そこで、終えるために行った工夫やFOLIO社員に教わったことを3つ紹介します。

👆遠い目標と近い目標を立てる

  • 長期的なモチベーションを保つための遠い目標、すなわち、達成したらどんないいことがあるか
  • 短期的なモチベーションを保つための近い目標、すなわち、何をやっていくべきか

を念頭におくようにしました。遠い目標ははじめに妄想しながら設定して、やる気を失ったときに度々思い出す用途で使っていました。

  • Gitについて誰よりも分かりやすく説明してつまづく初心者を助ける
  • 印税をもらうという体験をする
  • 国会図書館に自分の本が並ぶ
  • 表紙の似顔絵*2ネタ思い出にする

などです(赤裸々)。それに対し、近い目標は、担当章が決まった時点で、

  • Gitとは何かを書く
  • forkについて説明する
  • LGTMについて紹介する

といった粒度ですべての章に対し細かい単位で設けました。
遠い目標があることでやる気を維持し、近い目標があることで、次やることが明確になり手を止めることなく進み続けられるというわけです。何気なくこういう取り組みをしている人は多いような気もしますが、心理学で「長短比較」という名のついた手法だそうですね(『やってのける~意志力を使わずに自分を動かす~』で知りました)。

👆作業のWIP制限を設ける

効果としてはこれが1番大きいと実感しています。

WIPとは、Work In Progressの略で、完了していない仕掛りの作業を指します。特にリーン開発の文脈において、チームが同時にWIPを抱えすぎるのはアンチパターンとして語られることが多いです。今回の執筆はチームというより個人作業*3でしたが、考え方は十分活かすことができました。

これを心がけられたのは、間違いなく@Mura_Mi (同僚) たちが中心となって会社でいろいろ教えてくれてきたためです。WIP制限については、今年の3月頃、フロー効率とリソース効率*4の勉強会が開かれたことで気にするようになりました。FOLIOには #study プレフィックスがつくチャンネルが色々あり、日々知見を共有したり議論をしたりしているのですが、その勉強会は #study-lean-agile に集まった有志に向けてのものでした。

では、どんな執筆の進め方をしたか明かします。全部で5章担当したのですが、基本的には章ごとに作業を進めていきました。その上で、WIP制限を原則1 (レビュー進行中のみ2) として、これだけは絶対に守ると決めました。その結果、各章のPRを振り返ると、着手期間はそれぞれ次のようになっていました。

f:id:ihcomega:20181204023010p:plain
各章の着手期間

(あくまでこれは1回目に出した本文の原稿がLGTMとなるまでのようすで、この後スクショの差し込みや細かい手直しをしたり、さらに全章何周ずつか見直したり、後続の作業は山程ありました。)

複数の章に同時に手をつけている期間はほとんどなく、大体着手した順に完了まで運べていることが分かります。これがどう良かったかを伝えることで、なぜWIPがよくないかを考えてみることにします。

コンテキストスイッチを防げる

作業の切り替え時には、頭の切り替えを伴います。さらに、前やっていた作業に戻る場合は「何をどこまでやっていたか」を思い出す必要もあり、非常に時間やパワーを使います。言うまでもなく、同時に複数の作業をやると切り替えも多発してオーバーヘッドがどんどん大きくなるというわけです。WIP制限をしておけば、ある期間に考えるべきことを減らすことができます。

終わったことは忘れられる

先ほど思い出すのにかかる時間を減らせると紹介しましたが、そもそも思い出さなくてよくなるのも嬉しい点です。着手したものから順に完了させるようにしたら、一度完了まで到達したあとはしばらくその作業について考えずに済みます。今日の日付や昨日食べたものすら覚えていられないのに、複雑な作業内容をいくつも覚えているなんて難しいことです。

早めにフィードバックを受けられる

着手した順に作業が完了するということは、完了したものからレビューに回せるということを意味します。WIPが多く、どの章も終盤に完了を迎えるということになると、レビューの開始、そしてフィードバックをもらうのが遅れます。早めに気付いていたらそれ以降書く際に気をつけられたことも、終盤まとめて修正するとなると大変です。遅れることで時間的成約により妥協せざるをえなくなる可能性もあるので、クオリティが下がる原因にもなります。

やる気を保ちやすい

多くの章に手をつけると、たくさんの章の進捗があって一見良い気もしますが、「ひとつも(あるいは、ほとんど)完了していない」という状態が比較的長く続きます。これでは、TODOリストやissueに表れるようなタスクが消化できず、何も進んでいない気がして疲弊します*5。一方、WIP制限があると、少しずつ「終わった!」という体験を積み重ねられるので、小さな達成感を感じることができてちょっぴり安心します。

終わる時期の見当がつけやすい

WIPが多いと(つまみ食いのように好きなところから着手するような形をとるとさらに)、全体の何%終わっているのか図るのが意外と難しいです。制限しておけば、WIPとなっている章の進捗さえ分かったら、残りの章は終わったか終わってないかのどちらかなので、全体に対するボリュームをそのまま進捗に換算しやすいです。

レビュアーのWIPを減らせる

レビューがある場合、上記のような恩恵をレビュアーにもおすそ分けできると考えています。終盤にレビュー爆弾を送りつけることなく終えられるわけです。執筆もレビューも人がやる作業であることには変わりなく、WIPが多いと頭の切り替えが辛いし、心理的な負荷が高まります。

😞スケジュールとの戦いに敗れた「本業が多忙」以外の敗因

👆プロジェクトバッファを使ったマネジメントをしたかった

色々うまくいったことを並べましたが、失敗したり迷惑をかけたりしたことも多々ありました。1番大きいのがスケジュール管理で、脱稿予定日を出すための見積もりが何度も派手に外れた上に、ケアも疎かでした。もちろん本業の状況も刻一刻と変化するため、作業できる時間が安定しないというのは仕方ないことではあります。そうした状況だからこそ、もっと見積もりおよび予実管理に頭を使うべきでした。

これも同じく#study-lean-agileや実際のプロジェクトでの学びですが、各タスクの作業時間見積もりのうち、バッファにあたるものをすべて合算しプロジェクトの終わりに置く方法があります。

f:id:ihcomega:20181205035955p:plain
バッファのとりかた-1

f:id:ihcomega:20181205040058p:plain
バッファのとりかた-2

上の図でいうと、 バッファのとりかた-1 ではなく バッファのとりかた-2 のようなスケジューリングをするということです。作業中は予定をはみ出てバッファを食いつぶしたらそれを把握しておき、各タスクの進捗とバッファの消化状況から順調なのか、危険で対策を打つべきなのか判断するといった管理をします。今回でいうと、バッファの消化状況が不穏であれば出版社にアラートをあげるといった対応をすることで、締切近くなって「すみません、出来ませんでした」とゴメンナサイするよりはマシな状況に持っていくことが可能です。
また、実はモチベーションとの戦いにも有効です。タスクごとにバッファを設けると、結局バッファ込みの時間で終えようという心理が働いてしまいがちですが、それを取り除くことでタスクの締切を守ろうという動きを取りやすくなります。

かなり前に立てたスケジュールのスクショを引っ張り出してきました。このときは全体のバッファを設け、やる気だけはあったことが伺えます。

f:id:ihcomega:20181205040756p:plain
脱稿予定が8月だった頃のスケジュール

しかし、当時

  • バッファを設けたところで、何をウォッチしどうマネージすべきなのかを理解していなかった
  • 余裕がなかった
  • 妥協してしまった

などから途中で諦め*6、失敗に終わっています。『エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング』いわく、納期の重要な案件とも相性がよいようなので、(融通はきくものの)締切という概念の存在する執筆において取り組む価値はあったなぁと今になって残念に思います。

😍多岐にわたる同僚のヘルプ

ここからは、感謝の意を表すちょっとしたおまけエピソードです。

先輩執筆者たちのアドバイス

幸いFOLIOでは身近に執筆経験者がたくさんいたので、迷ったときに話を聞いて救われていました。

GitHubポケットリファレンス (POCKET REFERENCE)

GitHubポケットリファレンス (POCKET REFERENCE)

特に、@yasuharu519は、直前にGitHubの本 (競合…!) を出していたため記憶が新しかったということもあり、どんな進め方したか教えてもらったり、「完璧を求めたくなるけどできる限りやればそれで十分ですよ」「印税出たら寿司でいいですよ」などと言われたりしたおかげで勇気が出ました。

ストレスフリーな作業環境の提供

環境というと、執筆はマークダウンで行って、GitとGitHubを使って・・・みたいな話もしたいですが、ここでは作業マシンの話。今回、Windowsスクリーンショットを撮ることになったのですが、持っていなかったので同僚に借りました。

社内Slackにて
「どなたかWindows端末貸していただけませんか」
「使ってないThinkpadありますよ」

って@d_akatsukaに渡されたのがメモリ24GBも積んだハイスペックマシンでした。壊したらどうしようと怯える日々でしたが、それはもうスムーズに、滞りなくスクリーンショットが撮れたのでした。


偶然にも著書の販売がタイムリーだったのでFOLIOの業務と直接関係のない内容となりましたが、ちょっぴりFOLIOの取り組みやメンバーを紹介するお話でした!

執筆は、8月に終えるつもりだったのが9月までかかっている時点でお察しですが、決してスムーズに進んだとは言えません。しかし、終わらせるための道具は気合いのみ、という心許ない状態で作業するのではなく、良しとされている方法で自分をコントロールするために工夫ができたのはポジティブに評価したいです。おそらくこの1年間くらいでのFOLIOにおける学びや考え方の変化がなければこうはなっていなかったでしょうし、事態はより悪化していたことが予想できます。

#study-lean-agileチャンネルはほんの一例ですが、FOLIOには情報を持ち寄る場があること、そしてそれが活発であることがとても嬉しいです。しかも、学んだ内容はすぐに業務で活かす取り組みが日々見られるし、今回書いたように、個人でも試したくなる、あるいはより深く調べたくなるようなものが多いのがさらに嬉しいです。今どき社内勉強会なんて珍しくないものの、FOLIOのそれはとても質が高いと思っているし、実践的なのです(ありがたい)。たまにメンバーが社内勉強会のスライドを公開したりブログを書いたりしていますが、面白いものが多いのでとってもオススメです😋

さ〜て明日は!隣の席のDDDお兄さんこと@yoskhdiaによる、「Scalaを例に『仕様』パターンを実装する」です!

本記事は著書の宣伝行為ではありません。


参考文献

*1:仕事にも執筆にも集中できず何もかも効率が悪くなることをおそれ、仕事中は急ぎの連絡を返す程度にとどめ、なるべく本の進捗を出すことは考えないようにしていました。

*2:冒頭の商品ページ参照。著者の異常にリアルな似顔絵が掲載してあります。

*3:共著とは言え、ほぼ100%分業していました

*4:フロー効率とリソース効率についてはリクルートさんのフロー効率性とリソース効率性について #xpjugの資料が分かりやすいです。

*5:もちろん、章より小さい単位でタスクを作成すれば消化できますが、章で切るのはちょうどいい粒度だと感じていました。タスクが細かくなりすぎると、今度はメンテが大変になる可能性があります。

*6:最近の業務ではやっています!

*7:WIPについての章をパラパラとめくってみたら、まさに「この本の執筆時、色々な章に手を付けてしまい失敗した」というコラムがありました。まるかぶりだ!

JOnsenでアンカンファレンスが始まるまで #JOnsenUnconf #JOnsen

ここ最近、Javaのコミュニティに出入りしているとよく聞く「JOnsen」というイベント。初めて参加しているので、ちょっとずつ様子を書き残します。

どんなイベント?

jonsen.connpass.com

温泉地に集いアンカンファレンスをする!それだけ。2017年から始まり、年1回の5月開催です。
企画や進行はStephenSebastianがオラクルの伊藤さんと一緒にやってくださっています。2年前に来日した際、北海道の温泉で思いついたイベントだそうです。
ちょうどJava Day Tokyoというカンファレンスのタイミングと合っていることもあり、海外のJavaチャンピオンやJavaエキスパートもたくさん参加します。彼らと2泊3日一緒に過ごすことができるあまりにも濃いお泊りイベントなのです。
ちなみにオラクルが宿泊費を負担してくださるので、交通費だけで最高温泉に行けちゃうんだな😉今回は露天風呂が本当に素晴らしい箱根の宿!!芦ノ湖に浸かってるみたいだったし富士山も見えました。

アンカンファレンスって何?

参加者がアイディアを出し合って、セッションのトピックをその場で決めて行うカンファレンスです。
JOnsenでは、テクニカルなトピック (Java SE 9、Javaの新しいリリースサイクル、マイクロサービスなど) も、そうでないテーマ (コミュニティ、教育、プレゼンテーション、カンファレンスなど) も扱います。誰かが資料を作って講義をするようなことはせず、皆で輪になってディスカッションする形式を取ります。


ここからはJOnsen 2018の報告です💁

オープニング

参加者が集まったら、JOnsenとアンカンファレンスについての説明がありました。
JOnsenは "The most relaxed unconference" であること、そして次のようなルールがあること。

  • 誰でも、どんな内容でも受け入れられる。ここは「安全な場所 (safe place) 」である。
  • (同時に2セッションが開催されているが、) いつでも出入りしてもう一方の部屋へ行ってよい。
  • 誰かが両手を上げたら「静かにして話を聞いてね」の合図である。

f:id:ihcomega:20180519220527p:plain:w120
大事なアナウンスをしたい1人が両手を上げだすと、皆黙ってそれに続き、話者に注目する。ディスカッションが盛り上がっていてもすぐ静かになってとてもよい。

シャイで英語に苦手意識のある日本人が多いため、「英語が母語じゃなくても大丈夫だからね、ここでは決して批判されないよ」ということがとても強調されていたのが印象的です。

さて、以上を皆が理解したら、自己紹介とトピックのアイディア出しに移ります。
f:id:ihcomega:20180519220018j:plain
輪になって、1人ずつ付箋に書いた案を説明していきます。うう、開始時、部屋がやたら暗かったのもあり写真の品質が悪い・・・

うろ覚えですが、皆が挙げていたトピックの例を。

  • プロダクション環境でのマイクロサービス(教科書的な話ではなく実践的な内容)
  • 関数型プログラミング
  • ワークライフバランス(仕事と、OSSへのコントリビュート/ コミュニティ活動)
  • 日本の小学生へのプログラミング教育
  • カンファレンスでスピーカーをするにあたって大事なこと

初JOnsenということもあり、この時点でかなり緊張していました。知らない強そうな方がたくさんいるし、英語だし、内容が適切なのかな〜とかどうしても思っちゃうし。ですが、本当に何を言っても許される雰囲気を皆が作り出してくれ、今思えば心配することは何もありませんでした。
記録も兼ねて、挙げたトピックをひとつ紹介。最近公私ともに忙しかったこともあり、持ちかけたのは「皆仕事以外で色々な活動をしていると思うけど、タイムマネジメントとかモチベーションの管理どうしてる?」といった内容です。ちょうど社会人になってOSSへの貢献が難しいと感じ始めたというきつねくんのトピックとマージされ、2日目に扱われることとなりました。
30人程度の参加者が挙げた付箋は結構な数になりましたが、タイムテーブルの決定は思ったよりスムーズでした。いい感じにトピックをカテゴライズしながら進行してくれるオーガナイザーたちの慣れが大きいですねー。

く〜ここから本編ですが、今日は疲れたし寝てしまいます😪つづく・・・
同室の人々、晩酌続けてるのか全然帰ってこない。と思ったけどまだ23時かー。

MTGにPCを持ち込まない習慣が思ったより良い

最近、ノートとペンで戦う場面を増やしている。もちろんケースバイケースだけど、自分用のメモはこれで十分、むしろプラスとなる部分が多いなと思い始めた。
それまではもうPCを触りながらMTGへ参加することに慣れきって、思考停止状態に近かったのでとても新鮮。

いいこと

  • MTGの度にPCのコード類をいちいち抜き差ししなくてよい
    • 電源アダプターとか、モニターとつなぐケーブルとか色々。地味に面倒だから嬉しい。
  • MTGに集中できる
    • これが1番大きい。うっかりSlack見たり、書きかけのコードにちょっとだけ手を入れたりしちゃわないので、集中度や理解度がアップする。
  • 図や絵も気軽に描ける
    • アイディアを出したり入ってきた情報を整理したりしやすい。
  • 後から見返しやすい
    • あの時のメモは大体この辺にあるなーとすぐ見当がつくのでよい。ファイルみたいに見つけやすいような命名を考える必要もない。もちろん検索は出来ないが、それで困るような内容のメモはない。
  • 文字を書くリハビリになる
    • これはおまけだけど、漢字忘れとかに立ち向かえている気がする。

よくないこと

あくまでPCとノートを自分なりの基準で使い分けているという前提だけど、今のところ特に思いつかない。ノートにとった記録をデータにしたい時は困るんじゃないの?という話だが、そういうときはもちろんPC持っていってその場で書いているし、ノートの写真で済む場合も結構ある。

という小さな記録でした。今日もお疲れ様です。

TrailblazerのReformを使ってRailsのフォームとモデルを分離する

これはFOLIO Advent Calendar19日目の記事です。昨日は@asuyakonoの「デザイナーの僕がいかにしてビデオゲームのUIから「インタラクション・デザイン」を学ぶのか」でした。ゲームをやらない私にとってもめっちゃ面白くて分かりやすい記事だったし、ブクマ数もすごいことになっていました。さ、さすが・・・
さて、このアドベントカレンダーは2回目の登場です。前回は割とエモい記事(証券会社のエンジニア・デザイナーが社外でも最大限活躍するためにFOLIOで取り組んでいること)だったので今回は技術的な話を・・・ということでRuby on Railsについて書きます。

FOLIOでは、サービスとして外部に公開しているフォリオのみならず、社内で証券業務を行うために使うシステムを自前で開発しています。Scala製のマイクロサービスたちがバックエンドに構えていて、そのAPIを用いて機能提供するクライアントとして稼働しているのがRailsで作られたアプリです。最近は専らそのシステムを担当しており、入社前はほとんど書いたことのなかったRubyとも仲良くやっています(たぶん)。


今回は、FOLIOでも一部導入しているTrailblazerというgem群から、Reformというgemについて調べてみました。

業務において

  • バリデーション、エラーハンドリング、エラーメッセージの指定をどのレイヤーでやるのがよいかな〜って悩んだ経験があること
  • モデルクラスにおいて、入力値(フォーム)とAPIから受け取る値の区別が曖昧で管理がしづらくなっているのを何度か見かけたこと

がきっかけです。

Trailblazerの概要

github.com

TrailblazerはRubyフレームワークに抽象レイヤーを提供するgemの集まりで、モデルやコントローラーからビジネスロジックを排除することを目指しています。純粋なRails wayでの開発にありがちなクラスの肥大化を防ぎ、メンテナビリティを上げるのに一役買ってくれそうなアーキテクチャです。
READMEも公式ドキュメントも丁寧だし、無料で手に入る情報だけで大事なことが詳しく分かります。

trailblazer.to

Trailblazerの作者が思想・使い方などについて書いた本もあって、最近気になる箇所だけつまみ食いのように読んでいます。著者も「興味のあるところから読んでね!」と言っているし、途中の章からでも理解できるような構成となっていて良いです。

leanpub.com

余談ですが、日本語の情報が少ない印象を受けますね。

Trailblazerを構成するgemたち

先程gemの集まりと述べましたが、どういったものがあるのか簡単に見てみます。

  • Operation: サービスオブジェクト。ビジネスロジックはこれに持たせ、モデルやコントローラーからは取り除く。
  • Cells: UIのパーツを表現するオブジェクト。テンプレートをレンダリングするオブジェクトとも言える。
  • Reform: モデルにバリデーションのためのフォームオブジェクトを提供する。
  • Representable: オブジェクトとJSONXMLなどドキュメント間の変換を行う(レンダリング・パース)。

その他、まだバージョン1.0の出ていないRoar、Formula、Disposableなんかもありますが割愛します。

Operationの使い方をざっと

Trailblazerの大きな特徴でありメインともいえる(個人の感想)gemです。Reformの解説でもちらっと登場するので簡単に紹介します。

Operationはいわゆるサービスクラスにあたり、ビジネスロジックカプセル化するのに有効です。サンプルコードを先に出します。

class Hoge::Create < Trailblazer::Operation

  step :process_hoge!
  step :process_fuga!
  failure :log_error!
  success :process_piyo!

  def process_hoge!
    # 処理。異常値を返したらlog_errorへ移る。
  end

  def process_fuga!
    # 処理。異常値を返したらlog_errorへ移る。
  end

  def log_error!
    # エラーハンドリングの処理。前段の処理でトラックが左側に移ったら実行される。
  end

  def process_piyo!
    # 処理。前段の処理でトラックが左側に移っていなければ実行される。
  end
end

ビジネスロジックを処理のまとまりごとに分け、それぞれメソッド(上の例で言うとprocess_hoge!とかlog_error!とか)として定義します。

http://trailblazer.to/images/diagrams/overview-flow-animated.gif
※公式(Trailblazer: Operation Overview)より

メソッド化した各処理は左右2トラックのフロー(パイプと呼ぶらしい)に分かれ、正常系では右側のトラックを上から実行していき、異常系に遷移したら左側のトラックへ移ります。定義する際に step, success, failureといった3つのAPIを使い分けることでどちらのトラックに配置するかを指定し、意図した順序で呼び出すことが可能です。

  • step: 処理を右側のトラックに置く。異常値を返す処理が実行された時点で、パイプが左側のトラックへと移る。
  • success: 処理を右側のトラックに置く。処理の返却値は考慮しない。
  • failure: 処理を左側のトラックに置く。エラーハンドリングが目的。処理の返却値は考慮しない。

ネストが減ってフラットに処理が並ぶので流れを追いやすいし、正常系・異常系に分けて考えられるので分かりよいです。

Reformの使い方をじっくり

さて、この記事の本題へ。

特徴

Reformは先に書いたとおりバリデーション用のフォームオブジェクトを提供します。

  • フレームワークに依存せず、Rails, Sinatra, Hanamiなど多くのプロジェクトで使える
  • データベースは意識しないので、どんなORMと一緒でも使える
  • データベースアクセスはせず、モデルのプロパティの書き込み・読み込みのみ行う
  • モデルをフォームオブジェクトにマッピングすることが出来る

といった特徴がありますが、このあとの使い方を見てしまった方が理解しやすいはずです。

使い方

なお、ここからはビールが当たるキャンペーンの応募フォームを想定して話を進めます。画面の構成要素はこんな感じ。

  • 名前入力用テキストフィールド
  • 住所入力用テキストフィールド
  • あなたは20歳以上ですか?確認用チェックボックス

f:id:ihcomega:20171219095553p:plain ※イメージ

定義

ではコードと一緒に使い方を見ていきます。
Reform::Form を用いてクラスを定義するところから。フィールド定義はproperty, collectionというキーワードで行い、バリデーションもこのクラスで指定します。

class ApplyBeerForm < Reform::Form
  # フィールド定義
  property :name
  property :address
  property :over_nineteen
  
  #ActiveModel::Validationを用いたバリデーション
  validates :name, presence: true, length: { maximum: 20 }
  validates :address, presence: true, length: { maximum: 100 }
  validates :over_nineteen, acceptance: true
end

バリデーションの定義はActiveModelの他にdry-validationも用いることができるようです。というかActiveModelは非推奨となっている模様ですね・・・(詳しくは: installation)。

なお、オペレーションの中ならcontractを定義してやるとReform::Formインスタンスが生成されます(詳しくは: validation)。

contract do
  property :name
  property :address
  property :over_nineteen
  
  validates :name, presence: true, length: { maximum: 20 }
  validates :address, presence: true, length: { maximum: 100 }
  validates :over_nineteen, acceptance: true
end

Reformはフォームとモデルを分離する仕組みを取り入れている(詳しくは後述)ので、両者を別物として扱うのが比較的容易です。そのため、例えば「フォームには存在するがモデルには不要な値」なんかも自然に定義出来て便利です。この例だと、20歳以上かのチェックがそれに該当しますね。

インスタンス生成

コントローラーかオペレーションでインスタンスを作ります。
まず、Applicant(応募者)インスタンスを新しく作ってフォームインスタンスに渡すパターン。

@form = ApplyBeerForm.new(Applicant.new) #モデルのインスタンスを生成して渡す

続いて、作成済みApplicantを渡すパターン。渡したインスタンスは編集対象となります。このとき、Reformが既存のApplicantインスタンスに1度だけアクセスし、値を読み込んでくれます。

@form = ApplyBeerForm.new(Applicant.find(1)) #findしたモデルのインスタンスを渡す

バリデーション

#form_forとかを使ってフォームインスタンスレンダリングしたのち、validateメソッドを呼び出します。バリデーションの対象はフォームオブジェクトのフィールドとして定義した値のみで、それ以外が渡された場合は無視されます。

if @form.validate(params[:applicant])
  @form.save #後述
else 
  #エラーハンドリングする
end

バリデーションの結果、問題なかった場合はフォームに値が反映されます。一方、バリデーションエラーとなったら、errorsがエラーメッセージを返します。
重要なのは、値が有効で無事フォームの値が更新されたとしても、モデル側(ApplicantModel)にはまだ変更が入らないことです。

モデルに反映・永続化

インプットをモデルにも反映するには、#save#syncを呼び出します。これにより、Reformがモデルのsetterを使って値を書き換えにかかります。

@form.save #モデルに反映し、永続化する
@form.sync #モデルへの反映のみ行う

バリデーションが終わり、明示的にメソッドをコールするまではモデルの更新が行われないというわけです。フォームとモデルが、意味的にも実際の挙動としても綺麗に分かれてくれていることがよく分かりましたね。

順番をおさらい

Reformの使い方を追ってきましたが、流れをまとめるとこんな感じです。

  1. 定義
  2. インスタンス生成
  3. バリデーション
  4. モデルに反映・永続化

この手順を踏むことについて、Trailblazerの作者は「やることが多くて面倒だと思うかもしれないけどシンプルなんだよ」みたいな予防線を張ってますが、自分は割とすんなり理解・納得できました。

ちなみに、序盤でフォームの扱いに悩んだことがあると書きましたが、最近フォームを扱う画面を作る際は

  • フォーム用モデル(Reform::Formではなく、form以外のモデルと同様に定義している)をつくって、そのクラス内でバリデーションする
  • オペレーションにてバリデーション結果をチェック(し、エラーハンドリング)する
    • バリデーションにひっかからなければ右側のトラックで次のステップへ進む
    • ひっかかれば左側のトラックへ移り、エラーメッセージをコントローラーへ返す

こんな感じにしていて、これはこれで割といい感じにまとまりつつある気はしています。ただ、Trailblazerだけで教科書通りやるとこうなるんだなーという学びは面白かったし、フォームもモデルも複雑な画面で使うとどうなるのかしらという思いがあるので、業務でもちょっと試してみたいです。


Trailblazer、FOLIOでは主にAPI呼び出しに関連する部分から徐々に取り入れています。そういった部分的な導入により既存コードのリファクタリングをしていく方針を作者も良しとしており、本でも推奨されています。それもあってRails wayとの共存がしやすい作りになっており、導入しやすいのもメリットかなぁと思います。
機能はまだまだたくさんあるし、また何か困ったことがあったらちょっとずつ試してみたいなーと思います。自分が担当しているシステムはドメイン知識もたくさん要求されるし複雑な部分もあるので、せめてアーキテクチャは工夫してメンテしやすさを追求していきたいものです💪

モデリング言語の魅力を知り、快適な図示ライフを送ろう

これはGeek Women Japan Advent Calendar 7日目の記事です(大幅納期遅延ごめんなさいごめんなさいごめんなさいごめんなさい)。

物事を理解するためのアプローチには色々ある中で、自分は割とを大事にしています。よく「人に説明出来てこそ本当に分かったとみなせる」とか言う気がしますが、言葉での説明のみならず、理解した内容を頭の中で図示出来るかを考えることが多いです。wikiを書いたり、プレゼンで何らかの概念を説明したりするときも、チャンスがあれば内容を噛み砕いて図を入れるようにしています。
個人的には、全体をパッと把握することも部分にフォーカスすることも可能な一枚絵で表現するのが好きです(上手に出来るとは限らない)。

さて最近、ちゃんとルールのある図…というか所謂モデリング言語を学ぶことが面白いし、何より便利だと感じています。今更かよとは思うんですが、以前は超オリジナルなお絵かきか、クラス図、フローチャートくらいしか使ってこなかったんですよね。それ以外は正直「納品のために整理するドキュメント」みたいな良くない思い込みのもと、価値も分からぬまま敬遠(反省)。しかし、図を描くのはゴールではなく目的を果たすための手段だと実感して以来、態度を改めました。

というわけで、モデリング言語について個人の感想レベルですが綴ります。


まずモデリング言語とは何ぞやという話ですが、とりあえずWikipediaを覗く程度としましょう。色々あるなぁ・・・VRのとかもある。Javaモデリング言語っていうのもある。へぇ・・・
モデリング言語 - Wikipedia

良いところ

積極的に使うようになってから感じたうまみを挙げてみます。

  • 作業の本質だけに時間を割くことが出来る
    表現の仕方やレイアウトを考える時間が無駄なケースってありますよね。モデリング言語の本来の目的と自分がやりたいことがぴったりマッチした場合とか、見せ方にこだわる必要がさほどない場合とか。そんなとき、ルールが決められている記法に頼ってしまえばすぐに手を動かせます。設計なら設計そのものだけに時間や労力を費やせますね。
  • 誰にでも分かる
    図を共有さえすれば相手がすぐに理解できるのはとてもよいです(まぁ標準化ってそういうことなんだけどw)。メンテする人を選ばないのも利点ですね。独自ルールで書かれた図はどうも他の人が手を入れにくいものです。
  • ツールが豊富である
    ユーザーが多く、広く普及したモデリング言語だと特に、便利ツールも色々あります。例として、愛用しているPlantUMLを後ほど挙げてみます。
  • 先人の知恵がつまっている
    経験値や知恵の蓄積によって練られた記法なので、上手く使うと便利です。ここぞというときに活用出来るようにしておくと頼もしいのは自然なことですね。

付き合い方

いつもこんな意識で使ってるよーという話もしておきます。

  • 学習コストを恐れない
    モデリング言語には分厚い仕様があったり、いつ使うねんっていうコンポーネントが存在したりするもので、一見複雑に見えることもあります。しかし、自分の表現したいものが必要とするのはきっと一部。見よう見まねで使ってみたら手に馴染むかもしれません。
  • 使う図に迷ったら、まずラフに描いてみる
    何かを図示しようと意気込んだ時、「この内容なら使えるモデリング言語あるかも!?」という直感が働いたらとりあえずググってみましょう。使えそうなものが運良く見つかったら、途中までざっくり描いてみるとよい気がします。複数候補がある場合の比較にも使えます。自分はnu boardを使ってお絵描きしてみることが多いです(FOLIOではnu boardが流行っている・・・というか結構多くの人が持っていて、影響を受けて購入した)。
    例えば、会社で某承認フローを分かりやすく表現したくてスイムレーンを採用したことがあるのですが、そのときはまさにこんなプロセスを踏みました。
  • レイアウトにこだわる余地があればこだわる
    格通り描くものの、色とか文字の大きさを使い分けることでより効果的な図に出来そうだったらトライしています。

仕事での活用例

仕事では主にUMLやBPMNを使う日々('ω')せっかくなので図の活用例とツールを紹介してみます。

シーケンス図を用いてコミュニケーションすることがこれまで何度かあったのですが、そんなときに同僚たちの真似して使い始めたPlantUMLというツールがとても便利です。

PlantUMLを使うと、こういうDSL(書き方は公式を参照してね)を描けば

@startuml beer.png
actor よこな as yokona
participant 注文用タッチパネル as orderMachine
participant コックさん as cook
participant ウエイター as waiter

loop
yokona -> orderMachine: 注文🍺
note left: 飲みたい
orderMachine --> yokona: 注文結果
orderMachine -> cook: 注文内容
cook -> waiter: 料理🍺
waiter --> cook: 了解
waiter -> yokona: 提供🍺
end
@enduml

画像を吐き出してくれます👏
f:id:ihcomega:20171210133409p:plain

処理が複雑だとか、整合性を担保するため情報を整理したいとか、理由は色々ありますが開発者が必要だと思ったらシーケンス図を描くことが割とよくあります(強制ではなく都度判断している)。コードを書き始める前にシーケンス図だけレビューして認識をすり合わせると手戻りやバグの防止になってよいです。pumlファイル自体はテキストなのでGitで差分も見られるし。
あとはユニットテストを描く時網羅性の確認に使ったりもします。簡単に言うと、全部の矢印に大してテスト書けてるかなーとかalt網羅してるかなーとかチェックする感じです。これもわざわざ改めてパターンを洗い出す必要がなくて便利だなーと思ったことがあります。

ちなみに私はIntelliJ IDEAにPlantUMLプラグインを入れて使っています。

編集中はリアルタイムに図が表示され続けるし、
f:id:ihcomega:20171210133434p:plain

文法の間違いにもすぐ気付くことができます。
f:id:ihcomega:20171210133454p:plain

PlantUML、社外のエンジニアお友達に聞くと意外と知られていなかったりするみたいなので、本当にライトですが紹介してみました。クラス図や状態遷移図など、他にも色々描けます。

適材適所('ω')

ところで、当たり前ですが全ての図という図をモデリング言語で表現したいわけではなくて、大事なのは使い分けです。オレオレ記法の方が目的を達成する近道だと判断したならばそれもよいと思います。

不要なコストをかけずに、伝わりやすい表現ができるのは何か?というのを考えて、最適と思われる選択をしていきたいものですね。知っている図は活用しつつ、時々新しい図もインプットしながら華麗な図示ライフを送りましょう💪

証券会社のエンジニア・デザイナーが社外でも最大限活躍するためにFOLIOで取り組んでいること

これはFOLIO Advent Calendar 2017 1日目の記事です。

株式会社FOLIOというテーマ投資型オンライン証券サービスを提供している会社でバックエンドエンジニアをしています、よこなです。
会社のことをブログに書くのは5月の入社エントリ(リンク)以来。おかげさまで入社して半年以上たちました!毎日クソ楽しいです。自慢。

今日は入社以来開発の傍ら取り組んできたFOLIOブランディングについて書いてみます。「ブランディング」が何かはこのエントリ内で徐々に明かしていきますが、OSSに貢献したりイベントで登壇したりQiitaに記事を書いたり、そういった「社外でのアウトプットに関するなにか」だと思って読み進めていただければ幸いです。設立2年目のスタートアップということもあって、いけいけどんどんの精神でがむしゃらに活動しています!という話ではありません。既視感ある内容だと侮ることなかれ・・・我々はスタートアップ企業であると同時に証券会社なのです。そんな金融機関ならではの一味違うチャレンジについてご紹介します!

ちなみに私、19日(火)もこのアドベントカレンダーに参加しており、そちらでは技術の話をする予定です。

クリエイターブランディングのこれまで

まずお伝えしておきたいのですが、FOLIOではものづくりをしてユーザーに価値を届ける存在、すなわちデザイナー・エンジニアをあわせて「クリエイター」と呼んでいます。

立ち上げ - FOLIOメンバーが活躍している場を知るところから

同僚の伊藤 (@itohiro73)と、「クリエイターの対外発信、推進していきたいね〜」とか「FOLIOでもエンジニア向けイベントやりたいな」とか言いつつ行動しだしたのがことの始まりです。

ちなみに推進と書きましたが、「もっと外へ出ていこう」「アウトプットしてみよう」といったはじめの一歩を支える働きかけみたいなことではありません。それをするまでもなく、イベントで登壇したりブログをバズらせたり本を出したりと、FOLIOのクリエイターたちは社外でも活躍している状況でした。なので、そういった個々の活動を会社のイベント*1と連動させてより大きくポジティブな効果を生み出すとか、イベントのスポンサーシップや個人へのインセンティブなどで支援すべく制度を整えるとか、戦略的に動く組織を作るイメージでした。

はじめは伊藤と私というJavaコミュニティ寄りな人間だけの組織だったので、その他インフラ、フロントエンド、iOSAndroid、デザイン、サイエンス担当のクリエイターたちにランチを食べつつヒアリングするところから始めました。コミュニティやイベント事情、OSSのこと、情報収集でどんな人やサイトをウォッチしているかなど、色々教えてもらったのを覚えています。
ブランディングを手探りでスタートして分からないことだらけな上に、入社したばかりでまだ皆とのコミュニケーションにぎこちなさも残っており、毎回緊張しながら臨んでいた記憶が・・・。でも、未知の世界だったデザイン界隈やサイエンスのことを知れたり、皆の思いが聞けたり、今考えても貴重な場だったなぁと思います。ちなみに、FOLIOアドベントカレンダーをやろうという話があがったのもフロントエンドエンジニアとランチした場でした。

皆に聞いた話を参考にしつつ、まずはカンファレンスレベルの大きめなイベントをウォッチするところから始めました。あとは、自分の専門外のイベントであっても社員が登壇する時は足を運んでみました。ブランディングとして出来ることは様々ですが、技術イベントは入り口として自分に合っていたためです。準備なしに参加できるし(運営・登壇者のみなさまありがとうございます・・・)、雰囲気を掴むのにちょうどよいし、元々コミュニティ運営をやっているのもあってイベントが好きだし。抵抗なく取り組めるところからやっていったのは今思えばよかったです。活動を継続できている理由にもなっている気がします。

徐々にFOLIOからの発信も増加、反応も上々

もはや何がきっかけだったかも忘れましたが、FOLIOがメインで進める発信にも取り組んでいきたいねという声が挙がるようになってきました。入社して2ヶ月もした頃には「ブランディング」という言葉も社内で広がりつつあったし、クリエイターブランディングチームとして定例MTGを始めたりもして組織らしくなっていきます。メンバーも増えた上に、人事やマーケティング担当も巻き込んで、色々やれるようになりました。

FOLIOからの発信でどんなことをやってきたかについては、実際にものを見ていただきたいです!

Wantedlyでのクリエイターインタビュー記事

いろんなチームのクリエイターに、取り組んでいる仕事や大事にしていること、ビジョンなどについて存分に語ってもらう記事です。人事担当と協力して作ってきました。メンバーの個性がよく出ているし、FOLIOで働くことのイメージが伝わりそうな、個人的に気に入っている企画です。

www.wantedly.com
www.wantedly.com
www.wantedly.com

reladomo-scalaというOSS

FOLIO初のOSSです。
github.com

次の記事に詳しく記載していますが、開発秘話や機能については社外のカンファレンスで語られたこともあります。
www.wantedly.com

そんなこんなで色々試みていますが、最近我々の発信が届いているなーと感じさせるエピソードも出てきました。採用面接にお越しの方が「記事を見て興味を持った」とおっしゃってくださったり、エンジニアの友達が「Reladomo面白そうだね」と声をかけてくれたり。嬉しいことですね。

衝撃の事件

順調に手を広げながら挑戦を続けていたのですが、とある事件が起こります。
技術イベントで会社としてノベルティを配ろうとしたところ、コンプライアンス部からストップがかかったのです。別におかしなものを配ろうとしたとか、道徳的に良くないアイテムを用意したとかではありませんwクリエイターにとっては至って普通の、FOLIOオリジナルグッズでした。

何やら急に出てきたコンプライアンス部って?馴染みのない方もいらっしゃるかもしれませんが、法令違反のリスクなどを未然に防止し、経営や組織の健全性維持のため存在する部署です*2

さて、肝心のノベルティ待ったの理由は

「広告」に該当する可能性があるため、金融商品取引法等の規定に抵触していないか審査の必要がある。

ということでした。

???

法?規定?????

驚きました。

いやいやそんなこと言われても、エンジニアやデザイナーのイベントで法律まで意識するとか聞いたことある?どこがダメ?なんでダメ?広告だなんて、そんなつもりないからセーフでしょ。
色々な思いと言い訳と疑問とが浮かんできたのを覚えています。そして、それを持ち出してコンプライアンス部を説得・・・というか論破すればなんとかなるもんだと思っていました。

しかし審査の結果どうにもならず、そのときはノベルティを配ることを断念。当時は正直全然納得がいきませんでしたが、金融機関における「コンプライアンス」の存在が自分の中で大きくなり始めた出来事でした。おそらく他のクリエイターたちにとっても同じだったはず。

必死に環境整備する今日このごろ

先に述べた事件は衝撃が大きく印象的であったものの、何も急に厳しいことを言われたとか、いきなり禁止をつきつけられたとか、そういうわけではありません。FOLIOは創業当時から、ノベルティ配布に限らずコンプライアンス部による社外活動の管理を行ってきています。

一方で、管理体制があるのみでクリエイター側の理解は十分でなく、そこに改善の余地があるのも事実でした。門外漢なのでよく分からないけどコンプライアンス部の言うとおり動くしかないな・・・という状態(ノベルティを諦めたときは正直そんな感じだった。今これを読みながら、なぜかノベルティ配布を禁止されたっぽいな?どういうこと?って思っているあなた、その感覚です)は望ましいものではないので、クリエイターも法令遵守の意識をきちんと持った上で、適切な判断が出来るような仕組みづくりこそが必要でした。

こうした課題をふまえ、最近は目下そういった整備に取り組んでいます。ルールをメンテナンスしたり、その背景や考え方などを正しく伝えるための研修を行ったり、 クリエイターからの疑問に答えるべく有識者への確認や調べ物を行ったり・・・。

技術コミュニティで「金融機関に勤めながら、全社を巻き込んで対外活動に向けた取り組みをしています!」というような方には会ったことがないし、私のキャリアに証券のバックグラウンドは一切ないし、新しいことだらけ、戸惑いだらけです。でも、「資産運用をバリアフリーに。」というミッションで「金融の難しさ」を取り払うことを目指す我々にとっては、これも宿命といえるべき挑戦だと捉えています。入社前は、半年後に自分がこんなことしてるなんて予想もしていませんでしたがw

Advent Calendarも証券会社としては新しい取り組みであり、こうして形になって、25日間完走を目指す段階に至ることが出来たのはとても嬉しいことなのです。いやぁほんとうに。

なお、法令遵守の環境整備といっても、ただ制約を課す、活動を制限するといったものではなく、のびのび情報発信できる環境を目指しながらも「絶対にこれは守らないといけないよね!」という意識や自覚が皆の中に根付くような取り組みを目指しています。究極の理想形までの道のりは険しそうですが、協力者としてコンプライアンス部がいてくれるので少しずつ前進中です。同じインプットに対し必ず同じアウトプットが返ってくる関数が大好きなエンジニア脳にとって、「法解釈」というものはなかなか理解が難しいですが、ちょっとずつ考え方も学んでいます。

今は少なくとも、ノベルティにNGが出たとき真っ先に思った「コンプライアンス部を論破」しようという思想には至らなくなりました。月並みですが、歩み寄ってこそ会社としてのパワーが発揮されるからです。たとえ社員を論破したところで、我々が対峙するのは法律であり、国なのです。大きい・・・!同じ方向を見て力を合わせようとするのが、証券会社のブランディングチームとして大事な心構えかなぁと思っています。

知っていることも、大事にするものも、これまでの働き方も、すべてがあまりに違う者同士で協力するのは面白くもあり、難しくもあります。でも順調に、知らないところをカバーし合い、文化の違いも考慮しながらポジティブに頑張っているところです。例えばコンプライアンス部のメンバーがSlack、Confluence、GitLabなどを覚えて使ったり、クリエイターが証券外務員の資格を取ったり、法律を学んだり。

そんな中、ブランディングというミッションをいかにスピーディかつ効果的に遂行するか、そこがブランディングチームの腕の見せ所です。とにかく我々に何が出来るか?どうやったら上手くいくか?頭の回転を止めず、諦めず、考え抜くことを大事にしたいです。まぁ弊社のクリエイターたちはおかしいと思ったら何でもズバズバ言ってくれるので、意味のないことや効率の悪いことをやろうもんなら皆が軌道修正してくれる安心感もありますw

なぜ続けられるのか

色々書いてきましたが、ぶっちゃけ、なんかめんどくさそうですよね。法律なんて、聞いただけでぎょっとするし。一体なんでそんなことまでして・・・と思う方も多いのではないでしょうか。自分も(良くも悪くも)ゆるふわweb系エンジニアであることに慣れていたので、外野だったらそう感じていたに違いありません。

なぜやるか。それはただFOLIOが魅力的で、挑戦したいと思うからです。FOLIOは代表の甲斐が公言しているくらい、クリエイターを大事にしてくれる会社です。それぞれが抜きん出て得意なことを持った、魅力的なメンバーが集っています。それは私が語るまでもなく、きっとこのあとに続くAdvent Calendarの記事をご覧いただければ伝わるはず。

そんなFOLIOメンバーの面白さとか、よいサービスを全員が真剣に考え高いスキルをもって作り上げようとしている会社なんだなーってこととか、その他あれもこれもいろーーーんなよい側面がもっと広がっていったら嬉しい!そんな思いで挑戦するクリエイターブランディングチームなのでした。

さきほども述べましたが、証券会社によるAdvent Calendarはきっと前代未聞!?25日間ぜひぜひチェックしてくださいな〜!!!


全てが挑戦続きのFOLIOは、一緒に働く仲間を全力募集しています!

私がいるバックエンドチームの求人はこれ:
www.wantedly.com

他にも幅広く募集しています:
www.wantedly.com

まずはぜひ遊びにお越しくださーい!(最近移転もしたよ: FOLIO Office Tour @半蔵門 | 株式会社FOLIO)

以上、お付き合いいただきありがとうございました。明日はchocoiさんの「AWS Direct connectの利用に関して」です!

*1:例: サービスのローンチ、業界にインパクトあるメンバーの入社

*2:そもそもコンプライアンスとは、経営や組織の健全性を維持するために、法令や諸規則に基づき、ルールが制定された趣旨や背景を十分に熟知し、それらを遵守し実践していくこと

JJUG CCC 2017 Fallで基調講演する機会をいただいた #jjug_ccc #ccc_e1

11月18日(土)、ミッキーさんの誕生日にJJUG CCCを開催しました。

転職したての頃からJJUG幹事業はお休みモードにさせてもらっていたので、今回運営にはほとんど協力できておりません。ぼちぼち復活していきたいな・・・

しかし、基調講演という大きなミッションをいただくことが出来たので、そちらには全力投球しました。


幸運にも新卒1年目のときにコミュニティと出会い、会社にいるだけでは出来なかったであろう色々な経験をしてきた身として、これまであったことや思っていることを伝えたかったセッションです。ギリギリ若手を自称できる(?)今だからこそできる話をしてきました。
資料は公開しているものの、語った言葉こそが大事なので、とにかくご参加いただけた方が少しでも楽しんでくださっていれば幸いです。朝早くからありがとうございました。


(こちら嬉しいツイートオブザイヤー受賞)

そのあとはちょっとだけ幹事の仕事もしましたが、15時くらいから抜歯のため1度抜け(抜歯だけに)、戻ってきてマスクのまま懇親会を楽しみ、二次会には出ず直帰して1日を終えました。お酒が飲めず我慢している私に「アルコール消毒しよう」と言ってくる大人がたくさんいるJJUGが大好きです( '_' )

ということでこれまでと比べたらあまり参加した感がないのですが、色々な方に会えたよい1日でした。
幹事、ボランティアスタッフ、登壇者、参加者のみなさん、本当にありがとうございました。お疲れ様でした。また半年後!