Misoca に必要なことを全て受入プロジェクトで学ぼうとしたら驚いた

こんにちは、@mallowlabs です。 10月から Misoca にジョインし、現在は東京からリモートワークをしています。 入社日に台風の影響で新幹線が止まってしまい、初日から休みそうになりましたがなんとか入社できました。

Misoca では入社後、受入プロジェクトに配属されて、仕事の進め方を学んでいきます。私の場合には、@zetta1985Misocaに必要なことは全て受入プロジェクトで学んだ という記事を熟読してからプロジェクトに望んだので進め方のイメージはあったのですが、それでもいくつか驚いたことがあるので紹介したいと思います。

ということで先に以下の記事を読んでおくと読みやすいです。 tech.misoca.jp

受入担当はフルリモート勤務

私は東京で働いていますが、受入プロジェクトのはじめの2週間は名古屋の Misoca のオフィスで働きます。 ですが、なんと受入担当はフルリモート勤務の方です。 Slack や Zoom を使ってやりとりし、ペアプログラミングも Slack で画面共有しつつ、Visual Studio Code の Live Share を使って行いました。

最初の印象としては「名古屋に滞在してるのに名古屋勤務の人と一緒に仕事しないの!?」と少し驚きましたが、Misoca はリモートでもオフィスでもどちらでも普通に働ける環境を作っているので、最初の段階でリモートを前提にした働き方を学べたのでとてもよかったです。

以前はオフィス勤務の人が受入をしていたようですが、リモートの人が受入をやってもいいよね?という感じでフルリモートの人も受入をやるようになったそうです。

1ヶ月プロジェクトの前に数日で終わる小さなプロジェクトがある

Misocaに必要なことは全て受入プロジェクトで学んだ ではいきなり1ヶ月のプロジェクトに配属されていたので、そういう心持ちでのぞみました。 ですが、実際には簡単なエラーメッセージの修正を行う小さなプロジェクトから始まりました。

このプロジェクトでは、GitHub を使った開発の進め方の説明や、ヘルプページの変更をどのように進めていくかなど、開発やリリースプロセスの学習をしました。 Ruby はもちろん GitHub を仕事で使うのも初めてだったので、基本的なところから確認ができました。

いきなり1ヶ月のプロジェクトをやるつもりで入社したので、こういうチュートリアルを兼ねたプロジェクトがあるのはとても助かるなと思いました。

受入プロジェクトで画面を変えることもある

Misocaに必要なことは全て受入プロジェクトで学んだ では

  • 実装難易度が低い
  • UIに影響を与えない(見た目の変更がない)
  • DBマイグレーションが必要
  • データマイグレーションが必要
  • 運用担当との調整が必要

といった特性が挙げられていましたが、私の場合には以下のような特性のプロジェクトでした。

  • 実装難易度が低い
  • UI を変更する
  • UI をどうするかは詳細は決まっていない(仕様の調整から始まる)
  • DB マイグレーションは必要
  • 運用担当との調整が必要

「受入プロジェクトなのでまずは裏側から触るのかー」と思っていただけにこれも驚きでした。 入社していきなりいろんな人との仕様の調整を行うのは正直大変でしたが、受入担当の方がリードしてくださったのでなんとかなりました。

「一つのやり方にこだわらず、いろいろやってみる」という Misoca の文化がこういうところにも出ているのだと感じています。

数日のプロジェクトでもふりかえりをしっかりやる

Misoca ではふりかえりをとても大切にしています。 前述のエラーメッセージを修正するだけの簡単なプロジェクトでも、プロジェクト終了後に「事後検証」と呼ぶ、「何か学びはあったか?」をふりかえるイベントを実施しました。

正直な印象として「こんなに小さなプロジェクトでも事後検証をするんだな」と思いながら参加していましたが、受入プロジェクトの中でわかりづらかったことや、不安に感じたことを共有したら、それが学びとして記録・共有され、それを解消するような対応(今回は esa 記事の修正や受入フローの改善)がすぐに行われました。

Trello で振り返り:

f:id:mallowlabs:20181107134329p:plain:w320

esa を修正:

f:id:mallowlabs:20181107134344p:plain

代表の豊吉が 「PDCAって本当にまわるんだ〜」 と何度も思うと言っていましたが、まさに同じ気持ちになり、Misoca のプロセス改善へのしっかりとした取り組みに驚きました。

まとめ

私が受入プロジェクトで感じた驚きを記事にしてみました。 受入プロジェクトを通して Misoca の常に改善していくやり方を体感でき、驚きつつも Misoca の文化やプロセスを学べたと思います。 受入プロジェクトについて @zetta1985 の場合とは少し違った角度から紹介できていれば幸いです。

採用

Misoca では受入プロジェクトだけでなく、プロセスや、そして世の中を改善していきたいエンジニアを募集しています!

www.wantedly.com

わかった気になれるKaggle入門

こんにちは。 開発者ブログに初めて投稿します。id:toyoshi です。 先週Misoca社のSlackの褒めチャンネルを紹介しましたが、私があそこで褒められたことがあるのは「Zoomでスペースを押してる間ミュートが解除されるようになるオプションを教えた」「アンケートの質問を考えるのが早い」の2点です。本来の仕事の方でも褒められていきたいです!

さて、今回のエントリでは先日社内で開催したKaggleの勉強会の内容を紹介します。やったことがないと難しそうなイメージのあるKaggleですが実は入門だけなら知識ほぼ0でも大丈夫なのです。このエントリを参考にぜひ入門してみてください。

今回のゴール

Kaggleでアカウントを作り、コンテストに参加して、予測を提出するところまでを目指します。 環境の準備なし、プログラミングなし、統計の知識なしでKaggleの予測提出までの流れがわかるようになっています。

そもそもKaggleとは

データサイエンスプロジェクトのコンペ(Competition)をやっているWebサービスです。AtCoderのデータ分析版。企業主催のコンペもあり賞金が出ることもあります。

どんなコンペがあるか

どんなコンペが開催されているのか一部を紹介します。

アカウント作成からコンペチャレンジの流れ

まずは全体を把握しましょう。下記のような流れになります。

  1. アカウント作成
  2. コンペを選んで参加登録
  3. 提供されたデータを使って分析・予測をする
  4. 予測を提出。点数・順位がでる。
  5. 納得いくまで3に戻る
  6. コンペの結果が出る
  7. 2に戻る

アカウント作成

さっそくアカウント作成から始めましょう。無料です。 Kaggle: Your Home for Data Science

画面の基本(グローバルメニュー)

Kaggleはコンペをやるためだけのサービスというわけでもないのでグローバルメニューに色々あります。簡単に説明します。

f:id:toyoshi:20181101193700p:plain

Competitions・・・コンペ一覧
Datasets・・・配布されているデータセット一覧
Kernels・・・公開されているJupyter NotebookのKernel一覧
Discussion・・・ディスカッションの場
Learn・・・各種情報

コンペを選んで参加登録

まずはコンペを選んで参加登録します。Kaggleには入門者向けのコンペ「Titanic: Machine Learning from Disaster」が用意されていますので今回はそちらに参加します。

まずはコンペ一覧ページから検索するなどしてタイタニックのコンペを開きましょう。

Titanic: Machine Learning from Disaster | Kaggle

f:id:toyoshi:20181101194621p:plain

「タイタニック:〜大惨事で機械学習を学ぼう 〜」という入門用コンペです。内容としては乗船者のリストから生存者を予測するというものです。

個人的には乗船者の直接の家族はまだ当然存命なので不謹慎な気もしますが「Join Competition」を押して参加しましょう。

コンペのゴール

乗船した人のリストを使って、誰が生き残ったかそうでないかを予測します。 簡単にいうと死んだかどうかを0と1で表したCSVを作ってアップロードすればよいです。簡単そうでしょう?

なんかわからんけどまずは提出だ!

テスト駆動開発におけるRED、GREEN、REFACTORの考え方にしたがって、まずはいい加減な内容でいいので予測を提出してみましょう。 例えばこんなデータはどうでしょうか

スクリーンショット 2018-10-17 10.44.53.png (66.1 kB)

zero_fill_submission.csv (3.3 kB)

これは全員生き残らない(Survived=0)という予測ですね。

First submission

画面右の[Submit Prediction]から提出します。 すると即座にスコアと順位が表示されます。これを提出するとスコアは0.626です。正解率62.6%という意味ですね。つまり全員死亡で提出したので、タイタニックからの生還者はおよそ38%(1-0.626)しかいなかったということがわかります。

さあ、おめでとうございます!

スコアはそれほど良くないし、順位は低いですが、Kaggleでアカウントを発行し、コンペに参加して、予測を提出するという当初の目的をもう達成しました。

もう少しだけましなデータを送信してみよう

提供されているデータのところに、女性が全員生き残ると予測した場合のCSVというのが用意されているのでそれも提出してみましょう。

f:id:toyoshi:20181101200103p:plain

するとさっきのよりスコアがよくなるはずです。おそらく0.626から0.765とか。映画「タイタニック」にも救命ボートに女性や子どもを先に乗せていたシーンがありましたね。

さらに進めてやるには?

当日の勉強会ではさらに決定木を使って予測するデモもやりました。今回はやりませんが皆さんはもうKagglerですのであとは好きなようにデータを料理して高みを目指してください。次に紹介するようなサイトでは決定木や、ランダムフォレストといった手法の使い方をとてもわかりやすく解説してくれていますので参考になるでしょう。

まとめ

このエントリではKaggleのアカウントをつくり予測を提出するところまでをやりました。環境の準備なし、プログラミングなし、統計の知識なしでKaggleの全体像が掴めたかと思います。

タイタニックの事例が入門問題として素晴らしいのは有名な事故なので推理がしやすいということです。今回紹介した女性や子どもの方が生存率が高いということ以外にも、タイタニック号沈没事故 - Wikipediaなどを見ると1等船室の方が2、3等船室より生存率が高いことがわかったりもします。他の人のKarnelをみてみると、名前の敬称から特別な敬称の人は生き残りやすかったのではという仮説をたてたり、家族が多いと逃げ遅れやすいのではないかといった仮説を立てている人もいました。

さらに次のステップに進むには他の人が公開しているKarnelを読んでみたり、以前紹介した📚最近弊社で買ったデータ分析入門書📚 - Misoca開発者ブログの書籍を手にとってみてはいかがでしょうか。

採用

Misocaではサービスの改善のため仮説を立てる時や施策の検証などでデータ分析を使っています。データドリブンな改善に興味のあるエンジニアの皆様をお待ちしております!

www.wantedly.com

褒めるチャンネルを作ったらポジティブなフィードバックが集まって来て嬉しくなった話

Misoca開発メンバーの北村です。

先日Misocaの有志で岐阜県の金華山にハイキングに行きました。私は3歳の長男を連れて参加。 金華山は登山口からの標高差が300mほどで、子どもも楽しめる良い山でした。*1 これからの季節は天気が良ければ冠雪した御嶽山や南アルプスを眺めることができそうです。

f:id:RKTM:20181014113220j:plain

さて、子ども連れの登山・ハイキングで避けたいのは、山で「疲れた」「怖かった」というネガティブなイメージが子どもの心に残ってしまうこと。継続的に山に親しんでもらうためには、その登山が良い思い出、成功体験として刻まれて欲しいものです。

そのために私が実践していることは、「褒める」ことです。

登山口が見えるようなところまで登ったら「あんなところから登ったんだよ、すごいね!」、下山したら山頂を振り返り「あんな高いところまで頑張って登ったね!えらいね!」と褒めます。おかげで、今のところはお山に行くことは長男にとっても楽しい遊びとなっているようです。


さて、Misoca開発者ブログを読んでいるみなさんも、褒められると嬉しいですよね?

Misocaでメンバーを褒めるSlackチャンネルを作ったよ

MisocaではSlackにメンバーを褒めるチャンネル#praiseチャンネルが存在しています。

開発メンバーだけでなく、誰だろうと褒めます。仕事に直接関係あろうとなかろうと褒めます。

今日はMisocaの褒めチャンネルの模様をご紹介します。

褒められると嬉しい

電話応対力の高い人はすごい。電話苦手なエンジニア勢からするとリスペクトです。アプリのテストもやってくれていつも感謝しています。

f:id:RKTM:20181024183703p:plain

f:id:RKTM:20181025163247p:plain

技術の悩みも相談してもらったら感謝。

f:id:RKTM:20181024181156p:plain

メインの仕事とは関係ない貢献も、拾って感謝。 f:id:RKTM:20181024175747p:plain

ビジュアルテスト、最高です

コード変更の前後で意図しない見た目の変更がないかチェックしてくれるビジュアルテスト。安心してリリースできます。 f:id:RKTM:20181025163441p:plain

ビジュアルテストの詳細はこちらから。 tech.misoca.jp

リファクタの現状分析と取り組み方が判りやすかった。

f:id:RKTM:20181024180312p:plain

下記記事で解説されている色分けや取り組み方について、ポジティブなフィードバック。 tech.misoca.jp

色々と褒め&感謝

モバイルエンジニアもサーバーに入ってコマンドを実行できるようになって、作業がスムーズに。 f:id:RKTM:20181026100637p:plain

1日に3praise獲得。MVPです。 f:id:RKTM:20181026100742p:plain

Misocaのパフォーマンスが改善しました。キビキビ動いて最高です。対応してくれてありがとう! f:id:RKTM:20181024182009p:plain

分担していこうという決意表明。

f:id:RKTM:20181024182126p:plain

ドキュメントを書くには手間がかかりますが、後からペイします。 f:id:RKTM:20181026101324p:plain

助け合い、大事

困ったら声を上げる➞皆が助ける、という流れ。

f:id:RKTM:20181024180756p:plain

助け舟を差し出せるって素敵。 f:id:RKTM:20181026101504p:plain

属人的な対応から、仕組みで改善していくきっかけへ

f:id:RKTM:20181026104727p:plain

自分で自分を褒めてもいいんですよ

いい仕事したら自分を褒めていこう。

f:id:RKTM:20181024181330p:plain

トラブルシュート、臨機応変に動かないといけないし、旗振り役を買って出るのはなかなかプレッシャーがあるから大変です。自分で自分を褒めたい(というか褒めた)。

f:id:RKTM:20181024184139p:plain

文脈がないと他の人にわからないので注意

理性とは?

f:id:RKTM:20181024180251p:plain

神?すごーい?

f:id:RKTM:20181024181524p:plain

最後に

皆さんの職場では、メンバーを褒めていますか?メンバーから褒められていますか?Misocaではこれまでご紹介してきた通り、活発に褒めたり褒められたりしています。

個人的に嬉しいことは、「誰も拾わないこぼれ球タスクで、自分も積極的にはやりたくないけど状況的に自分がやるしかないなー」というタスクを拾ったことを感謝されることです。貢献を評価してくれる人がいれば、気分良く働けます。

採用

Misocaでは、褒めたい/褒められたいエンジニアを募集しています!

www.wantedly.com

*1:金華山は低山と言えど、馬の背ルートなど、危険なルートもあるのでご注意ください

Android版Misocaのマルチモジュール対応

こんにちは!アバター化して可愛くなったこまたつです!!
この前オフィスに来たお客さんに「声はオッサン」て言われたのですが、最近ボイチェンカラオケにハマっていて声も可愛くなってきました。

みなさんのプロダクトはマルチモジュール対応してますか?

InstantAppやDynamicDeliveryなど、新たに追加される機能はマルチモジュール前提のものも多く、強めの圧を感じるようになってきましたね。
今回はMisocaのAndroidアプリでどんな感じにマルチモジュールの対応を行っているかを共有します。
ライブラリ以外のマルチモジュール初挑戦だったので理解の浅い部分が多いのですが、みなさんからの優しいつっこみお待ちしております。

Misocaは請求書作成をメインとしたサービスですが、請求書以外にも業務フローに合わせて見積書や納品書を作成できます。
Androidアプリでは先日のv3.0リリースでこの3種類すべてに対応しました。
文書はそれぞれ微妙に異なっていて、たとえば郵送ができるのは請求書だけという作りになっています。
そこで、次のようなモジュール構成を考えました。

f:id:komatatsu:20181019144328p:plain

これを考えたときには実はまだ見積書と納品書の機能は存在しておらず、ひとつのモジュールに請求書とログインなどの機能が入っている状態でした。
先行するiOS版に比べて機能的に貧弱ということもあり、ひとまず次の形で見積・納品書の機能を追加することにし、請求書の分離作業は後回しにしました。

f:id:komatatsu:20181019144921p:plain

これらの機能は新規に追加されるコードだったので穏便に分割することができました。
それと同時に新たな問題点が見つかりました。
アプリには取引先に紐づく各文書をタブで切り替えて見られる画面があります。

f:id:komatatsu:20181019144423p:plain

この画面があるせいで、処理を完全に分割するのが難しくなってしまいました。
この画面はbaseモジュールに入っていますが、baseを見積書や納品書のモジュールが参照しているため、逆向きの参照が入れられません。
またモジュールをまたぐ画面遷移とモジュール内の画面遷移でIntentの取得方法が変わり複雑度があがってしまいました。
コードを書くときはなるべくモジュールを気にせずに書ける様にしたいです。
これらはまだ解決方法を模索中ですが、ほかにも小さな問題をいくつか解決しました。

BuildFlavorsで設定したapplicationIdがBuildConfigから取れない

取れない(つらい)
仕方ないので activity.packageName を使うように書き換えました

AndroidManifestを分割しなかったのでテストがこける

全部appに書かれたままほっといたらInstrumentation Testがコケるようになってました。
モジュールごとに適切に分割することで解決しました。

proguardのminifyをかけると動かなくなる

packageは変えてないのですがentity類をbase moduleに移動したら、引数なしのコンストラクタが無いエラーが出るようになってしまいました。
entityは基本的にkotlin data classを使っているのですが、今まではGsonがUnsafeを使って処理していたものがminifyによってうまく動かなくなったみたいです。
一次対応としてproguardのルールを変更しましたが、ちゃんと引数なしのコンストラクタを作ってあげたほうが良さそうです。

そんな感じで、まだまだいろいろ問題が出てきそうな雰囲気を感じます。
モジュールの分け方も文書ごとに分けるのではなくもっと適切な分割方法があるのでは?などとissueを立てて議論しています。
アプリを成長させて行くためにも開発しやすい状態を作るのが重要だと思います。
ただ分割しただけでは何も始まらないので、これから試行錯誤を繰り返しつつ少しずつ馴染んで行きたいと思います。

採用

Misocaに興味のある方はぜひフォローしてくださいね

技術書典5で Misoca/晦日 TECH BOOK #1 を頒布します

こんにちは、@corocn です。 最近はカレーとゴリラにはまっています。ゴリラはtwemojiのゴリラが一番可愛くておすすめです。

技術書典5で技術同人誌を頒布します

f:id:corocn:20180926095125p:plain:w300

本題ですが、2018/10/08 に開催される 技術書典5 で、エンジニア有志による合同誌を頒布します。

本のタイトルにMisocaという名前はついていますが、Misoca内で実際に扱っている技術にとらわれず、 エンジニアがプライベートで触ってる技術を中心に広く語る本になっています。アバター出社の話もありますよ。

オッ!って思ったらチェックしてもらえると嬉しいです!

techbookfest.org

また、個別でサークル出展するエンジニアもいますので、合わせてチェックしてみてください!

内容

ちらっとタイトルだけ紹介しておきます

  • Buildkite: Railsの並列分散並列テストを環境を手に入れろ @corocn
  • 5分で分かる JWTとその応用 @corocn
  • Numo::NArrayとNumo::Linalgの紹介 @y0shoku
  • ReactでCLIツールを作ろう @renyamizuno_
  • beyond the telework @k0matatsu

表紙は社内のデザイナーさんに作ってもらいました!渋い!かっこいい!

場所

き-10 です。真ん中あたりの壁際を探してください!

f:id:corocn:20180926100837p:plain

最後に

当日は私も売り子してますので、気軽に遊びにきてください。 それでは会場でお待ちしています!

採用

Misocaでは、技術書が大好きなエンジニアを募集しています!

レガシーなフロントエンドコードを整理するためにどう立ち向かったか

2エントリ連続でこんにちは、@mugi_unoです。

名古屋には台湾ラーメンイタリアンという名物があるそうです。

富山県民の私には理解が追いつきませんでした。


フロントエンドでの金額計算処理

さて、Misocaは請求書作成サービスなので、金額計算処理が欠かせません。

フロントエンドも例外ではなく、消費税額や合計額を算出するロジックが存在します。

機能変更が必要になった!!

諸事情により、そのロジックに変更を加える必要が生じました。

長くプロダクトを支えてくれていた存在ですが、内容的にはいわゆるレガシーなコードで、たびたび開発者ミーティングでも課題として挙げられることがありました。

git log で確認してみると、該当コードに対しての機能的な変更は2015年の冬から行われていません。

f:id:mugi1:20180907094553p:plain:w400

何が問題だったのか?

DOM操作と計算ロジックの混在

Misocaでは、新しくコードを書く際はVueやReactを使っていますが、まだまだjQueryで書かれたコードも残っています。今回の計算ロジックはそれが顕著で、100%jQueryで記述されていました。

参考としてこちらの図をご覧ください。

(画質は落としています)

f:id:mugi1:20180913131517p:plain:w100

これは、該当コードから一部を抜粋し、

  • ■緑 : DOMからの読み込み
  • ■黄 : 計算処理
  • ■赤 : DOMへの書き込み

でざっくりと色分けしたものです。カラフルで綺麗ですね!

さて、これはつまり、画面で見えている要素と計算処理が密接に絡み合ってる状態であることを示します。

今回の機能変更では、この中の 「■黄 : 計算処理」の変更が必要ですが、このまま挑んでも

  • 「計算処理を変えたつもりが、他の箇所でのDOMからの読み込みも変わっちゃった!」
  • 「DOM触ったら、全然違う場所のコードの計算処理も意図しない動きになっちゃった!」
  • 「つらいです」

となるのが容易に予想できます。

変更時の影響箇所が読めない

内部の複雑さだけではなく、該当コードはグローバルに定義されているため、あらゆるところから自由にコールされています。かつ、参考となる資料も特に存在していないため、変更時にどこまで影響が及ぶのかがわからない状態でした。

これによる最大の問題点は、コードを触るのが怖くなるという心理状態になることです。

修正をしても「関係のないところには影響がないです!」と誰も言うことができません。仮にPRを出したとしても、レビューする側は「ウッ...」となります。

まずはリファクタリングだ!

色々と大変なことはわかりましたが、嘆いてばかりでは何も改善しません。

もともとこのコードが作られた時期を考えると、jQuery全盛期であり、React/Vueといったものが世の中で活躍し始めるよりもずっと前の話ですので、むしろ今まで僕たちのプロダクトを支えてくれてありがとう、と言うべきなのかもしれません。

感謝の気持ちを込めて、リファクタリングを行うことにしました。

コードを知る

すぐにコードを書き直していきたくなるところですが、グッとこらえ、まずは誰が見ても分かる状態にコードを可視化することにしました。

というわけで、書いたのはこんな雰囲気の資料です。 draw.io で書きました。) f:id:mugi1:20180910163646p:plain

  • 緑色が読み込み専用のDOM
  • 赤色が書き込みも行うDOM
  • 線がデータの流れ

です。

資料書くとか無駄じゃない?という意見もあるかもしれませんが、

  • ある値が、一時的なものなのか、最終的な計算結果なのか
  • あるDOMを変えた場合、どこの書き込みに影響を及ぼすのか

を目に見える形で整理することで、コードを理解出来ると共に影響範囲が自分の中で整理できますし、リファクタリングする際にも様々な戦略を考えられるようになります。

また、レビューをしてもらう際にも、自信を持って「影響箇所はここです!」と言えるようになりますね。

リファクタリングの対象範囲を決める

一言にリファクタリングといっても、やみくもに始めると際限なく直してしまうので、 どこまでやるのか?も決めたほうがよいでしょう。

今回の目標は以下に設定しました

  1. 計算に必要なデータが、1箇所に集約できている
  2. DOMの変更を行う箇所が、1箇所に集約できている
  3. 計算処理が、DOM操作を伴わないJSの単一のfunctionになっている。

逆に、以下はやらないことにしました。

  • グローバル依存からの脱却
  • React/Vueといったフレームワークへの書き換え

「本来やりたい機能追加のためには、最低限ここまでやれば大丈夫だろう」というところまでを目標にしました。

怖い修正をする際には、小さく刻んでいくのも大事ですよね。

ちなみにこういった選択を出来たのは、最初にコードを可視化して整理したことで「どうやら小さくリファクタリングできそうだぞ?」ということが明確にわかったから、というのも大いにあります。

整理をしていなかったら、「全部Vueで書き換えるんじゃ〜〜、ウワァアア...」という未来が待っていたかもしれません。

テストコードを追加する

ここまでの整理をしても修正ミスをしてデグレを引き起こすのが人間です。

そんな時僕たちに自信をくれるのがテストコードです。Railsのfeature specによってある程度はカバーされていますが、いくつかの問題がありました。

  • 実行に時間がかかる(1分とか)
  • サービスのユーザ体験を担保しているものなので、網羅性は保証できない
  • リファクタリングした以外の箇所の問題とぶつかると永遠にハマる

特に実行時間がネックで、リファクタリング中は何十回・何百回と叩くことが予想されます。 そのたびに待たされていると作業ペースが落ちてしまうので、フロントエンドだけを対象としたテストコードを用意することにしました。

既存コードのInput/Outputのみにフォーカスしたテストを書く

さて、DOMにべったり依存しているコードですので、テストを書くと言っても一工夫必要です。

リファクタリングした結果、既存の挙動を壊していないことを担保したいので、

  • 該当のグローバル関数を実行する前のDOMをInput
  • 該当のグローバル関数を実行した後のDOMをOutput(期待結果)

として、ブラックボックステストを追加しました。

テストコードの例

影響のあるDOMのみを含む、最小限のテスト用テンプレートをpugで用意します。(先に資料化したものが役立ちました)

doctype html
html
  body
    //- Input
    input(
      name='quantity'
      value='1,000'
    )
    input(
      type='radio'
      name='tax_rate'
      checked
      value='8'
    )

    //- Output
    #total
    #sub-total
    #tax

...

テンプレートをロードして計算を行い、結果を確認します。

describe('計算処理', () => {
  beforeEach(() => {
    document.body.innerHTML = require('./test.pug')();
  });

  it('〜の計算結果が反映される', () => {
    window.run(); // リファクタリング対象のグローバル関数

    expect($('#total').text()).to.eq('10,800円');
    expect($('#sub-total').text()).to.eq('10,000円');
    expect($('#tax').text()).to.eq('税別 800円');
  });

...

最終的には、おおよそ200件ほどのexampleを書きました。

リファクタリング後に捨ててしまうことも視野に入れ、テストコードの綺麗さよりも、カバー範囲の広いテストを1件でも多く、時間をかけずに書くことに注力しました。

f:id:mugi1:20180911100127p:plain

テスト自体も3秒程度で終了します。いい感じですね!

小さく整理していく

ようやく準備が整いました。これで自信を持ってリファクタリングを始めることが出来ます。

リファクタリングする際は可能な範囲で小さい単位に区切りながら進めます。レビューする側の負担を軽減するという意味もありますし、そもそもリファクタリングの方向性が間違ってないか?というのを適宜確認できる効果もあります。

f:id:mugi1:20180912091111p:plain

ここまでやると、ある程度処理が分離された状態になってきます。

最後に、全体を通した整理を行い、ついでに不要な処理の削除やモジュール分割といったプラスαのリファクタリングを行いました。

f:id:mugi1:20180912092238p:plain

リファクタリングした結果どうなったか

リファクタリング前のコード同様に、 リファクタリング後のコードを抜粋してカラーリングしたものがこちらになります。

  • DOMからの取得処理

f:id:mugi1:20180913131930p:plain

  • DOMへの反映処理

f:id:mugi1:20180913131953p:plain

  • 計算処理

f:id:mugi1:20180913132012p:plain

  • グローバル関数本体

f:id:mugi1:20180913131837p:plain:w200

どこでなにをやってるかが明確で、綺麗になりましたね!

まとめ

今回はレガシーコードをリファクタリングしてみた話でした。

こういう作業には少なからず恐怖がつきまとうので、いかにしてそれを払拭しながら小さく進めていくかが重要だな〜と実感しました。

ただ、今回のリファクタリングである程度は綺麗になりましたが、正直なところ、まだまだ理想の状態には程遠いです。

と、いうわけで..

採用

Misocaでは、リファクタリングも楽しめるエンジニアを募集しています!

開発合宿の成果を新機能としてリリースしました!

こんにちは、@mugi_unoです。4歳の娘にトランプの神経衰弱で勝てません。

新機能をリリースしました 🎉

さて、先日Misocaに新しい機能がリリースされました。

www.misoca.jp

f:id:mugi1:20180828093504g:plain

国税庁のサイトで、法人の基本3情報(名称・所在地・法人番号)というものが公開されており*1、そのデータをもとに文書の送付先などを自動入力できるという機能です。

合宿成果からのリリース

この機能は、7月に行われた開発合宿*2での成果物がベースになっています。 今回は、合宿終了後からリリースまでどういった作業をMisoca内で行ったのかを中心にご紹介します。

合宿で作ったもの

Misocaでは以前から国税庁のデータを取得し保持していたものの、有効活用できていない状態になっていました。

そこで、私のいた合宿のチームでは「これ使ってなんかやってみよう!」というのをテーマに取り組みました。

(合宿時のチームメンバーです。Team 神)
f:id:mugi1:20180827110235j:plain

というわけで、以下を作ってみることにしました。

  • 請求書を作るときに、法人情報から検索して入力補完できるようにする。
  • 曖昧な入力でも検索結果がヒットするようにする。

3日間で概ね形になり、請求書だけではなく、見積書や納品書でも使えるようなプロトタイプが完成しました。

技術的には

  • 検索 / ElasticSearch
  • フロントエンド / Vue.js

を使っています。

リリース!...はまだ厳しい!

合宿最後の成果発表でもわりと評判がよかったので、このままプロダクトにリリースしよう!!

...と言いたいところですが、現実はそう甘くなく、ガッと作ったので色々と課題が残った状態でした。

さすがにこのまま使っていただくわけにはいかないので、プロジェクトとして、ちゃんとしたリリースに向けて動き出したくなりました。

リリースに向けてやったこと

ロードマップ会議で提案

Misocaでは週に一度、何を優先して着手していくかを整理するための、ロードマップ会議*3と言われる場があります。

これは誰でも参加でき、提案も自由にできます。

ということで、「合宿で作ったやつがいい感じなので、せっかくなのでブラッシュアップしてリリースしましょう!」と提案し、リリースに向けて動き出すことになりました。

(実際の提案時の内容)
f:id:mugi1:20180827151552p:plain

インセプションデッキをつくる&タスクの洗い出し

まずはメンバーの認識を揃えるため、インセプションデッキを書きます。

  • なんのためにやるのか?
  • どのぐらい期間をかけるのか?
  • リスクはなんだろう?

といったことをここで話し、必要となるタスクの洗い出しも行いました。

結果的には、ロードマップ会議で提案した時点では「数日程度でいけるでしょ〜」と思っていたのですが、実際にはやることがもう少し多く、1週間〜2週間程度は必要になりそうなことがわかりました。

UIの見直し

合宿では、とにかく機能が使えること自体を優先したため、UIには力を入れていませんでした。 改めて、複数人で「より使いやすくするにはどうしたらいいだろう?」という話をして、見た目の修正を行いました。

たとえば、以下のような変更を加えています。

検索導線

Before

  • 導線が常に見えていると、使わない人からするとノイズになる

f:id:mugi1:20180827145846p:plain

After

  • 使いたいときにのみ現れるようにする

f:id:mugi1:20180827153402p:plain

検索入力・検索結果の表示

Before

  • 「法人情報から検索」だと、データの出元がわからなくて使う時に不安になる
  • 会社名や都道府県など、何を使って検索できるのかがわからない

f:id:mugi1:20180827154234p:plain

After

  • タイトルの変更、補足メッセージやリンクを追加する

f:id:mugi1:20180827153506p:plain

検索結果から文書への反映

Before

  • 選択した法人情報が文書のどこに適用されるのかがわからない
  • 一部だけ編集する必要があることも多そう

After (新規に追加)

  • 文書へ適用する前にダイアログ上で確認を挟み、そこで編集もできるようにする

f:id:mugi1:20180827154739p:plain

バックエンド側の修正

UIだけではなく、バックエンド側も見直しました。

蓄積している法人情報はおおよそ500万件存在し、すでに利用されていないデータも混ざっている状態です。

色々整理すると、以下のような手直しが必要でした。

  • 不要なデータがElasticSearchにインデックスされないようにする
  • パフォーマンスが出るか確認し、適宜チューニングする
  • 都道府県名で柔軟に絞りこめるようにする (東京都 / 東京 などで絞り込む)
  • どういったフローでElasticSearchのIndexを最新化していくか考える

泥臭い作業も必要になりましたが、コツコツと1つずつ潰していきます。

加えて、今後のメンテナンスのために、書けていなかったspecも一通り書き足しました。

リリース 🎉

他にも細々した修正に加え、ヘルプなども最新化し、無事に新機能としてリリースされました。期間的には「やるぞ!」と決めてからはおおむね1週間強程度で大半の作業をやりました。なかなかのスピード感ですね。

まとめ

開発合宿の成果が実際にリリースされて嬉しい限りです。

これを繰り返していって合宿の価値を上げていって、最後はハワイでの開発バケーションを目指したいと思います!!


採用

Misocaではバリバリ新機能を作っていきたいエンジニアを募集しています!