2016-01-11

2015年の振り返り

少し時間が経ってしまったが、以前自分が書いた振り返りブログを見返すと当時のことを鮮明に思い出せて「ああ、こんなこともあったなぁ。こんな感想持っていたのかー。」という感じになっておもしろかったので、2015年分の振り返りも書くことにした。

時系列に沿いつつ、特に印象に残ったテーマ単位で振り返る。

古くなり手を付けられなくなったレガシーコードの大幅リファクタリング

開発から年数が経ち、日に日に複雑化してレガシーコードと化してしまった検索系APIの大幅なリファクタリング(のための準備)を行った。

  • グローバル変数が何個も使われている
  • 1メソッドが肥大化して400行を超えている
  • 1つの変数が参照渡しで様々なメソッドに渡され、処理を追い切れない
  • テストが無い

というような状態で、手を付けられる状態ではなくなっていた。開発者も何が影響してバグを生み出すかわからないから手を出したくない。 しかしこのAPI、サービスにとってかなり重要な機能を提供していたため、企画さんや営業さんから絶え間なく機能追加要望が来ているという状況だった。

これは良くないということで、チームメンバーで相談し合い、多少時間がかかっても良いからリファクタリングをすることに決めた。それが将来的に見てプラスになると判断した。

自分が担当したのは、最初にこのAPIの仕様を正確に把握してテストに落とすことだった。 APIなのでviewまわりの処理を気にする必要は無かったが、受け取るパラメータが80個(!)くらいあって「ウッ..」っとなった記憶がある。

あまりテストを書いた経験が無かったので、正しいかどうかはわからないが、次のような方針でやっていくことにした。

  1. 外側から見たAPIの仕様だけをテストにする。つまり、内部的な実装のテストではなく、API利用者の視点のテストを書いていく。
  2. テストはリクエストパラメータ単位で書く

1 は1つのメソッドが長すぎてテストに落とすのは難度が高かったのと、これから大幅にリファクタリングされることもあって単体レベルのテストを書くのは無意味だと思ったので、機能面でのテストだけを書くことにした。例えば次のようなテストである。

1. パラメータ「price_from」に100を渡すと、100円以上の結果のみが返ってくる
2. パラメータ「price_from」に100を渡し、「price_to」に1000を渡すと100円以上1000円以下の結果のみが返ってくる

2 についてはそのままの意味で、受け取り可能なパラメータごとに仕様を整理してテストに落とすということ。何でも良かったのだが、何かしらグループ化できると進行状況がわかるし、開発も進めやすいと思ったのでこのルールを作った。

リファクタリングが完了する前に自分は別の部署に異動してしまったので、最終的にこのリファクタリング作業がどうなったかは実は知らないのだが、上の方針でテストを書いてみていくつか感想をまとめたい。

機能テストは効果が高い

機能面でのテストは、関数など単体レベルのテストよりずっと効果が高いと思った。 現実での使われ方と同じ形でテストをするので(APIの場合、HTTPリクエストをするという形をとるので)、信頼性が高く感じた。 また、内部的な実装はどんどん変わっていくが、API自体の仕様は頻繁には変わらないので保守性の面でも良いと思う。

本番の検索エンジンのデータをテストに使えたのは良かった

本番の検索エンジンとつながったAPIに対してテストをできたのは良かった。 日々更新される実際の検索インデックスに対して毎日テストをかけていると、「たまに落ちる」というテストが見つかるので、それを修正していくことでテストの品質も少しずつ上がっていったし、本番のデータでテストが通ると「本当に大丈夫そうだ」という安心感があった。

テストパターンを十分にカバーしきれなかった

パラメータ単位でテストを書いていったので、あるパラメータとまた別のパラメータでの組み合わせによって発生する機能の仕様を追いきれなかった。 また、HTTPリクエストをしてその結果を確認する形式のテストなので、レスポンスに直接出ないパラメータの機能をテストすることができなかった。

最後の最後までやりきれず、チームメンバーに迷惑をかけてしまったのが申し訳ない限りだが、テストやリファクタリングについて真面目に考える機会ができたのは良い経験になった。

※ この時買って参考にした書籍
[isbn:4798116831:detail]

Vim::Factory開発

2015年のはじめ頃からid:mosuke5とvim::factoryの開発を始めた。

http://vimfactory.com/

2016-01-11-01.png
2016-01-11-01.png

はじめは、お互いインフラ・サーバ寄り技術に興味があったので、Software Designなどに掲載されていたHAProxyとかDockerとかnginx等を実際に触って遊んでいた。しかし、インフラ系技術はやはり実際に動くアプリケーションがあって使わないと面白くないし、知識も浅いままになってしまうだろうということで何らかアプリケーションを作ることにした。

目的はインフラ系技術を学ぶ上で題材になるアプリケーションを作ることだったので、自己満アプリでも何でも良いはずなのだが、やはり自分たちが作りたい・使ってみたいアプリにしたいという気持ちもある。そんな風に欲張っていたから何を作るか決めるのに時間がかかった。

ある日、id:mosuke5がさくらVPSのバーチャルコンソール(?)から着想を得て、vim::factoryを開発することに決まった。何度かブレストをした中に、vimrcを簡単につくって試せるアプリはどうか、というようなネタはあったものの実現方法が全く思い浮かばず却下されていたのだが、実際に似たようなイメージで動くモノを見つけたので、そこから調べてプロトタイプを作ってみたらちゃんといい感じに動いたのでこれに決めた。

平均週1のペースで開発をしつつ、インフラ・運用まわりの仕組みはこだわりたかったのでAnsibleとかDockerとかMackerel等の面白そうな技術をどんどん取り入れた。そのため、リリースできるモノができたのは4,5ヶ月後の7月になった。

その時に報告書としてid:mosuke5が書いたブログ(誰に向けた報告書かは謎w)がいい感じにバズったのはなんとなく少し自信になったし、嬉しかった。
http://mosuke5.hateblo.jp/entry/2015/07/19/135844

なお、vim::factoryは2016年になっても細々と機能追加やバックエンドの改善をしている。本日、pluginを試せる機能を導入した。

引っ越し

2015年の7月頃に引っ越しをした。 当初は交通の便が良く街の雰囲気も良いなと思っていた住みたいエリアがあったのだが、家賃や間取りで納得行く物件が見つからず、少しアクセスが悪い場所に引っ越すことにした。今思うともう少し慎重に選ぶべきだったなという感じ。

わりと大きめのイベントだが、特に書くことが思い浮かばないので箇条書きで感想とかを適当に書く。

  • 2階の足音が気になる。次住むとしたら最上階にしたい。
  • お金が貯まらなくなる。つらい。
  • 家事(掃除、洗濯、料理、アイロン等)は結構余裕。余裕。
  • 両親のありがたみは結構感じる。
  • モノは少ない方が色々良いと思った。と言いつつ便利道具が最近揃ってきた。
  • 独立して1人でやっていけてるのは少しだけ自信になる。

Railsアプリケーション開発

2015年の10月から部署が変わった。そこで最初に担当したのは、担当サービスのversion2開発だった(現在も進行中)。 この仕事はうまくいかないことが多く、かなり苦戦した(している)。

設計面での考慮漏れ

システム全体が様々なコンポーネントが組み合わさってできていることもあって、開発を進める中で考慮漏れ部分が何度も見つかった。 考慮漏れが発覚するたびに手直しをする、直したと思ったらやっぱり元の状態が正しかった、というようなことがあって、進捗がなかなか出なかった。

元々そのシステムをメインで担当していた人物は、自分が異動してくるとほぼ同時に退職してしまったので、そのシステムを詳しく知っている人物はいなかったのが少し痛かった。。とはいえ、もう少し詳細に設計を考えるべきだったという反省もある....。

どうやっていくのが良かったのか、未だに良い対策や方法は思い浮かんでいない。

Rails開発

Rails wayに乗りたいけど、うまく乗れないというパターンが多かった。 また、Rails wayに乗ろうとするあまりか、「Railsではこういう時どう書けばよいか」というのを調べる時間が多かった。

わかるまでひたすらググっていて、なんかダメな開発スタイルになっていた気がする。 アプリケーションの仕様そのものがRails wayにそぐわない要件だった部分もあるような気がするが、Rails自体をもっと知る必要があると痛感。

また、RailsというかActiveRecordなのだが、あまり深く考えずに基礎的な知識だけでコードを書いていると、意図通りに動作するもののパフォーマンスが出ない実装になっていることがある。

直せるところは直したが、リリースも近く未着手の部分も残っている。非常に怖い。

micro services

自分が担当したシステムは、最近よく耳にする「micro services」を参考にして、メイン部分とはは完全に独立した形態のシステムになっている(と前任者に聞いた)。

しかし、おそらくだが分離の方法があまり良くなかったのではないかと思う。 なぜかというと、このシステムはメイン部分と確実に整合性を持たせなければならないデータを扱っていて、そのために複雑な分散トランザクション処理が必要になっていたからである。

この部分はかなり苦労したが、APIが1リクエストで多くの処理をこなせるようにすることでトランザクション処理を実装しやすくすることで対応した。ただ、これが正解なのかどうかはまだわからない...。

システムを分割しWebAPIを使って連携するようなシステム構成は、トランザクション面とパフォーマンス面で気にかけることが多くなるので慎重に設計した方が良いのではないか、という学びはあった。

なお、 この辺の苦悩については次のエントリでも書いている(愚痴っている)。

勉強や学習の方向性について考え始める

エンジニア視点で、次のようなことを考えるようになった。

  • 何か1つ、得意分野を持ちたい
  • 基礎や仕組みといったすぐには廃れない、応用の効く知識を蓄えたい。「○○の使い方」等を身につけたところで、長期的にはあまり役に立たない。

この辺りに関して、過去に少しまとめたのがこの記事。
http://qiita.com/mogulla3/items/0f06ce1d9b3ba56ce075

こうは思いつつも、仕事をしているとやっぱりハウツー系の知識が必要とされる場面が多く、実現はできていない。 たまに暗号化技術とかTCP/IPとか長く活きて多方面で役立ちそうな技術の勉強をしてみるものの、緊急で調べたいことが出てくるとそこで終わったり...。

しかし、新卒1, 2年目はインフラからフロントまで何でもできる、いわゆるフルスタックエンジニアになりたいとか言っていた気がするので、すごい変化である。

まとめ

随分長い記事になってしまった。

また数年後の自分が見ておもしろいと感じられると良いと思う。 来年は英語(特に英会話)を頑張りたい気持ちあるけど、避けられない事情があるわけでもないので、モチベーションが続くかどうかが不安です。