Hatena::Groupbugrammer

蟲!虫!蟲!

Esehara Profile Site (by Heroku) / Github / bookable.jp (My Service)
過去の記事一覧はこちら

なにかあったら「えせはら あっと Gmail」まで送って頂ければ幸いです。
株式会社マリーチでは、Pythonやdjango、また自然言語処理を使ったお仕事を探しています

2013-06-24

[]nginx + Webalizerを使って、定量的なログ解析を行なう 02:51

 ここ一週間くらいは、Bookableというサービス改善を行なっていました。

 とはいえ、普通、「サービスを改善する」といった場合、その改良が「改善」というための指標が必要になります。単純に「機能を追加する」というだけでも、一つの「改善」なのかもしれませんが、それが自分のサービスへの「目標」に近づいているのか、という点からも検証される必要があります。

 以前に、このサービスを立ち上げるにあたって、知人から「なんらかのアクセス解析ツールを入れないの?」ということを言われたことがあって、そういえばそういうことに思い至らなかったな、ということで、さっそくアクセス解析ツールらしきものを探したところ、Webalizerというツールを発見しました。

 既にGoogle Analizerなどのサービスはありますが、まだ大規模な分析が必要なほど大きなサービスではないので、とりあえず、簡易なアクセス解析が出来ればいいかな、と思って入れました。

 元々はApacheのログを解析したりするものだったらしいのですが、自分はフロントとしてnginxをたてているため、ログの形式を揃える必要がありそうです。自分は、下の記事を参考にログ形式を揃えました。

nginx + webalizer でアクセス解析 - Folioscope

 一応、ログの形式を揃えることで、ログ解析はできるようになります。ただし、継続的に解析するとなると、設定のところの

Incremental yes

 にしておくと、継続的にログを貯めてくれるのでよいでしょう。これをnoにしておくと、単体のログ解析のみが残るので、ログがローテートしたときに、過去の解析が全部無くなってアウアウしてしまうことになります(というか自分はなりました)。

 で、解析をかますと、下のような静的なHTMLが生成されます。

f:id:nisemono_san:20130625022602p:image

 特に、ポイントになる部分としては、PageとVisitになるのかなと思います。Pageが、あるページにアクセスされた回数であり、Visitは、30分以内に同一のIPで接続していないときは記録するという形になります。

 つまり、ページを閲覧している回数はPageで見て、Visitで、実際に来てくれたユーザーを見ると言うことになります。

 で、このデータについて面白い見方Webalizerの見方|ahref.orgに書いてありました。

平均ページ閲覧数 = 総Pages /総Visits

 自分のページだと、autopagerizeで、自動的に次のページを更新するようにしているので、そのレスポンス数が、そのサイトに興味をもってくれている度合いになるのかな、というので、この指標を参考にしています。

 で、ただデータを取るだけではなく、下のような形で、Google Spread sheetにまとめています。

f:id:nisemono_san:20130625025020p:image

 Spread sheetに、さらに自分が改善した内容を含めて、それがどういう風に影響しているのか、というのを定期的にデータにしています。

 ただ、このデータを見る限りだと、Page/Visit比は、平均10Pageほど見ているので、それなりに閲覧して頂いていることはわかるのですが、問題はやはりVist自体の数が少なくなりつつあることがあり、その辺をどのように増やしていくかが、今後の課題になりそうです。

2013-06-23

[]幾つかの戦略フレームワークを使って自分のサービスの弱いところを分析する 01:48

 FXでの失敗ケース | Just another WordPress siteを一週間立ち上げてみました。発端の殆どは、自分の思いつきであるので、個人的な思い入れで拡張しています。しかし現実的な問題として一歩退いた目線で「このサービスはどうなんだろう?」という部分をあまり考えずにやっていると、自分が「これは絶対面白いだろう!」と思っていても、他人にとってはフックにならないことも多いのかな、という印象です。サービスを立ち上げている以上、ある程度使ってもらいたいし、広めたいという気持ちは単純に事実です。

 で、そこで「やはり戦略の部分とか考えないといけないよなー」と思って、そういう戦略分析的なフレームワークを、自分のサービスと当てはめて改善できるかどうかを考えていくのは重要かなと思って、いくつかの戦略分析フレームで、自分のサービスについて、今後どのように展開していくべきなのか、というところにスポットを当てて分析していったことを公開しようかと思います。

その前に、どんなフレームワークがあるの?

 とはいえ、戦略分析フレームワークでやろう、といったときにじゃあどんなフレームワークがあるのか、という問題があるので、その辺をざっと調べてみました。参考になりそうなリストとしては、下のようなものがありました。

リーンキャンバス

 この手の戦略フレームワークで一番有名なのはリーンキャンパスです。最近のスタートアップではリーンキャンパスという考え方が流行っていますが、それらと近い関係にあったりします。元々の考え方については、下の本を参照すると良いでしょう。

 今回のリーンキャンパスの画像については、下のブログから拝借しました。Thanks.

 で、さっそく描いてみた結果が下のようになります。

f:id:nisemono_san:20130624002120j:image

 これを見ている限りだと、「チャネル」であったり、「圧倒的な優位性」について弱いところが若干あるのかな、と思います。もちろん、そもそもの課題であったり、独自の価値提案そのものが、現段階においては「仮説」であり間違っている可能性もあるので、解析ツールで定期的に見直していく部分であるのかなとは思ったりします。

SWOT

 次はSWOTです。SWOTは、どうやらStrength/Weakness/Opportunity/Threatの頭文字を取り、強み/弱みと機会/脅威を分けて、それに対するアプローチを考えていく方法のようです。最初に参考したものが「競合」であるので、下に書いた図は競合になっています。

f:id:nisemono_san:20130624011649p:image

 書いてみた印象だと、やはりリーンキャンパスと似ている部分がある(強みなどを分析するあたり)とは思う一方で、それを組み合わせることによって、より「何をするべきなのか」というところが具体的になっている印象があります。

 つまり、一方でこういうリソースリスクを自分は抱えており、また外部状況として、このようなメリットをもたらしてくれたり、あるいは障害になりそうなものというのを組み合わせることによって、何をするべきなのか、ということを明確できるというのは、少し面白いかなとおもいました。

 ちなみに、SWOTに関しては、下の記事も参考になりました。

4C

 最後に、4Cによる分析を試したいと思います。4CはCustomer Value/Customer cost/Communication/Convenienceで分類します。それぞれ、「顧客価値」「顧客コスト」「コミニュケーション」「利便性」という四つによって分割します。例えば、自分のサービスであるならば、下のように書くことができるかもしれません。

顧客価値
漠然とした本に対する欲求を満たすことが出来る。また、普段だったら知ることのなかった本を知ることができる。また、たまに出てくる面白い商品を見つけ出すことが可能になる。
顧客コスト
ランダムで出てくるので、「欲しい」と思わせられる本に出合うかどうかはわからないので、何枚もページをめくる必要がでてくる。
コミュニケーション
ブログによって、どのようにサービスを開発しているか。特にはてなブックマーク技術者向けの話題が多いので、その話をする。その上で、サービスに興味をもってくれるように導線を貼る
利便性
ブラウザを通じていつでも閲覧できる。また、NexusやiPad程度の大きさのタブレットであるならば、それなりに快適に閲覧できるようになる。

 他の分析と4Cが違う部分は、恐らくは、今までの分析が自分たちのリソースとその関係を考えていくのに対して、4Cの場合は、顧客を中心として、その顧客に対してリソースをどのように与えればいいのか、というところの違いがあるように思われます。

 4Cについては、下のブログが参考になりました

まとめ

 というわけで、一般的によく使われるであろう3種類のフレームワークで、自分のサービスをどのように展開していくか、を分析してみました。

 ただ、この手のマーケティング分析で非常に感じることは、やはり「このような結果が出てきたとするならば、具体的なアクションはどのようになるのか」ということであったり、あるいは「果たしてこの分析の前提自体が正しいのか」という検証自体が必要になってくる部分があるのかな、という気がしています。

 とはいえ、自分が漠然とコンセプトとして考えていたことが明確になった、という意味ではやってみる価値はあるかもなーという気はしました。もし何かのときに、自分のサービスでも試してみるとどうでしょうか。

SamuelgluseSamuelgluse2017/04/02 18:16dalacin liniment pris
<a href= http://trinidadpi.bloggsite.se >zovirax cream genital herpes dosage</a>
<a href=http://project196270.tilda.ws>pergotime bivirkninger eller gravid</a>
dalacin 150 mg 24 capsulas
<a href= http://www.devote.se/grettaflam/ >flagyl 400 mg pris</a>
<a href=http://annettmarm.bloggnorge.com/exforge/>exforge novartis</a>
proscar finasteride biverkningar

WilliamStofeWilliamStofe2017/04/04 16:07nexium iv dosage
<a href= http://jorgemanwa.jimdo.com >diclofenaco potássico garganta</a>
<a href=http://www.imxprs.com/free/tarenchern/tarenchern>excedrin migraña nombre generico</a>
ciprofloxacino comprimido para que serve
<a href= http://kaleighdzi.myfreesites.net >augmentin bula</a>
<a href=http://www.breannawei-60.webself.net>pilula qlaira engorda</a>
augmentin mide bulantısı

MichaelMammaMichaelMamma2017/04/07 12:38amoxicilline posologie grippe
<a href= http://elwoodeast.soup.io >nolvadex pct</a>
<a href=http://leroypusey.startspot.nl>tolexine gé acné</a>
priligy pharmacie maroc
<a href= http://audreategn.over-blog.com/2017/04/doxyval.html >doxyval 100 posologie</a>
<a href=http://markettaro.startbewijs.nl>priligy 60 mg review</a>
amoxicilline sandoz 500 mg/5 ml

MatthewCitMatthewCit2017/04/07 16:29nolvadex pct for sale
<a href= http://jolenemale.onlc.be >nolvadex prix belgique</a>
<a href=http://salomemahe.page4.me>finasteride prix algerie</a>
efficacité finastéride cheveux
<a href= http://sydneyvoll.webblogg.se >tolexine 100 soleil</a>
<a href=http://jolenemale.onlc.be>nolvadex dosage</a>
amoxicilline sandoz 750

JamestopJamestop2017/04/10 16:19etoricoxib 60 mg 28 comprimidos
<a href= http://kirkagrest.myfreesites.net >etoricoxib cane</a>
<a href=http://www.luciocapsh-87.webself.net>teva celecoxib launch</a>
zovirax pomata effetti collaterali
<a href= http://kirkagrest.myfreesites.net >etoricoxib per cane</a>
<a href=http://www.luciocapsh-87.webself.net>celecoxib pfizer</a>
levetiracetam fiale torrinomedica

veveoguzetveveoguzet2017/05/30 04:54http://100mgcheapest-price-viagra.com/ - 100mgcheapest-price-viagra.com.ankor <a href="http://tadalafil-buy-5mg.com/">tadalafil-buy-5mg.com.ankor</a> http://20mgprednisone-order.com/

eufonoyuwoeufonoyuwo2017/05/30 04:59http://100mgcheapest-price-viagra.com/ - 100mgcheapest-price-viagra.com.ankor <a href="http://tadalafil-buy-5mg.com/">tadalafil-buy-5mg.com.ankor</a> http://20mgprednisone-order.com/

xiuwooleyxiuwooley2017/05/30 05:06http://100mgcheapest-price-viagra.com/ - 100mgcheapest-price-viagra.com.ankor <a href="http://tadalafil-buy-5mg.com/">tadalafil-buy-5mg.com.ankor</a> http://20mgprednisone-order.com/

awzaajajimoawzaajajimo2017/05/30 05:07http://100mgcheapest-price-viagra.com/ - 100mgcheapest-price-viagra.com.ankor <a href="http://tadalafil-buy-5mg.com/">tadalafil-buy-5mg.com.ankor</a> http://20mgprednisone-order.com/

axelujoveaxelujove2017/05/30 05:13http://100mgcheapest-price-viagra.com/ - 100mgcheapest-price-viagra.com.ankor <a href="http://tadalafil-buy-5mg.com/">tadalafil-buy-5mg.com.ankor</a> http://20mgprednisone-order.com/

eserojoveserojov2017/05/31 19:50http://100mgcheapest-price-viagra.com/ - 100mgcheapest-price-viagra.com.ankor <a href="http://tadalafil-buy-5mg.com/">tadalafil-buy-5mg.com.ankor</a> http://20mgprednisone-order.com/

ircorefuqircorefuq2017/05/31 20:04http://100mgcheapest-price-viagra.com/ - 100mgcheapest-price-viagra.com.ankor <a href="http://tadalafil-buy-5mg.com/">tadalafil-buy-5mg.com.ankor</a> http://20mgprednisone-order.com/

ekjumnijuruekjumnijuru2017/07/12 03:11http://100mg-viagracanada.com/ - 100mg-viagracanada.com.ankor <a href="http://sertralinezoloftonline.com/">sertralinezoloftonline.com.ankor</a> http://20mg-tadalafil-lowest-price.com/

oqepolucoqepoluc2017/07/12 03:24http://100mg-viagracanada.com/ - 100mg-viagracanada.com.ankor <a href="http://sertralinezoloftonline.com/">sertralinezoloftonline.com.ankor</a> http://20mg-tadalafil-lowest-price.com/

imasamujulahuimasamujulahu2017/07/12 03:26http://100mg-viagracanada.com/ - 100mg-viagracanada.com.ankor <a href="http://sertralinezoloftonline.com/">sertralinezoloftonline.com.ankor</a> http://20mg-tadalafil-lowest-price.com/

wacokidailizowacokidailizo2017/07/12 03:36http://100mg-viagracanada.com/ - 100mg-viagracanada.com.ankor <a href="http://sertralinezoloftonline.com/">sertralinezoloftonline.com.ankor</a> http://20mg-tadalafil-lowest-price.com/

anowisozobonaanowisozobona2017/07/12 03:39http://100mg-viagracanada.com/ - 100mg-viagracanada.com.ankor <a href="http://sertralinezoloftonline.com/">sertralinezoloftonline.com.ankor</a> http://20mg-tadalafil-lowest-price.com/

akinorotaecaakinorotaeca2017/07/12 03:50http://100mg-viagracanada.com/ - 100mg-viagracanada.com.ankor <a href="http://sertralinezoloftonline.com/">sertralinezoloftonline.com.ankor</a> http://20mg-tadalafil-lowest-price.com/

2013-06-19

[]土日でサービスを作っていて考えていたこと 00:01

f:id:nisemono_san:20130618210147p:image

 ふと、Bookableのコミットのパンチカードを見ていたら、本当に土日に偏っていたので、俺は嘘をついていなかった!

 ……という冗談は置いておくとして、この記事は、前回の続きとなります。今回は、じゃあ実際にはどういう風にやっていったか、という話を書こうと思います。

何を作るのか

 何を作るのか、といったときに、いろいろな考え方があるかと思われます。自分が思い付く限りでは下のようになるかなーと思います。

  1. 自分が作りたい、欲しいものを作る
  2. 人が欲しがっているものを作る
  3. 技術として試してみたいものを作る
  4. お金が欲しいので、お金になりそうなものを作る

 ここで重要なのは、たぶん何らかの形で、作ることがモチベーションになるものだと思います。

 例えば、自分がTornadoで作ったNotVJSというものがあります。このモチベーションは、Tornadoと呼ばれる、Pythonで作られた非同期ライブラリを使いたかった、どうせならPythonWebsocketを使いたかった、というのがあったので、「もしブラウザ間で同期したら面白いものはなんだろう」と考えたときに、知人が、HTML数枚で画像をjQueryで加工してVJみたいなことをやっていたことを思い出したので、「そうだ、そういうのをつくればいいじゃん」と思って作ったものでした。

 上記の場合はそうですし、例えば今回のBookableについては、下の本に憧れて作ったものだったりします。

f:id:nisemono_san:20130618234908j:image

 上の本は工作舎と呼ばれる出版社(松岡正剛がいたところ、というとわかりやすい?)が作ったもので、他の人はともかく、自分はとても感銘を受けたので、こういうものを作ろう、と思ったのが初期のきっかけでした。

 最初のころのコンセプトとしては、下のように整理されるでしょう。

  1. 本をキーワードでぶったぎって配置する
  2. そこから有名な本とあんまり有名ではない本を配置する
    1. 「有名」の定義は、ブックマークのユーザー数として定義する
  3. 有名な本をフックにして、知らない本に辿り着ける

 このようなものとして、最初Bookableは考えられていました(ついでにアフィリエイトで金がGETできるんじゃないか、という淡い期待もありました)。

知人に話をしてみる

 で、ある程度作りたいと思うものの確証が出来たら、とにかく人に自分のアイデアを説明してみました。そうすると、案外好印象だったので、「結構面白がってくれる人がいるのであるならば、これはもしかしたら面白いものになるのではないか」と思ったので、実際に作ってみることにしました。

 知人にアイデアを惜しみなく話してみる、というのは、そのサービスに対しての反応がダイレクトに伝わってくるし、また人に説明することで、自分の中で、どういうサービスにするのかというのが明確になってくる。そういう意味では、知人に自分のアイデアを言ってみるというのは、最初の反応を見るのには、とてもいいんじゃないかと思います。

とりあえず必要になりそうなところから作り始める

 じゃあ何処から作り始めたのか、というと、実は書籍データをどのように集めてくるのかというところからスタートしました。というのは、画面を作るのは、たぶん簡単だろうと思ったからでした。

 ただ、今から考えると、当たり前といえば当たり前なんですが、あまりにも書籍データが集まってしまったので(だいたい四万冊とかその辺)、「あー、これは整理するのが難しいなあ」と思ったので、とりあえず自然言語処理で、名詞部分を取り出して連結できないかなーと考えたりして、実はその辺の実装は未だにやっていたりしています。

 で、必要になりそうなところといえば、本を表示する部分だなあ、と思ったので、テンプレートをさくっと書いて、ランダムで本を表示してみたところ、配置の妙というべきなのか、そこそこ面白い結果が出てきたので、「とりあえずこれでサービスを認知させて、その後のことを考えるか」みたいな感じでリリースしたのでした。

知人と協力してモノを作ってみる

 当然の事ながら、全部の事を一人でやるのもいいんですけれど、当然のことながら、得意な分野と苦手な分野があります。自分の場合だと、実装やコーディングについては、特に苦にはならないわけですが、圧倒的にデザインというか見栄えを作るのが弱いところがありました。で、ちょうど知人であるところの、豊井さんに頼みました。

 で、そのときに意識したのは、自分は基本的に全くデザインはわからない、ということでオペレーターに徹したということです。普段から一緒にすごすことが多いので、お互いの気質が解っていたというのもあるのですが、そのあたりの役割分担を上手くやったので、スムーズに楽しくできました。たぶん、このあたりは信頼関係だと思います。あと、単純に自分のスキルをお互いに補完し合う経験というのは、普通に楽しかったというのもありました。

普段から試してみたい技術をストックしておく

 これは技術者よりの話になるのかもしれませんが、日々最新の技術が生まれていきますし、「これはヤバい」と喧伝されていますが、いきなり自社のプロダクトにぶち込むのは、さすがに問題があります。なので、こういう場所で自分で試してみる機会になることがあります。例えば、自分の場合だったりすると、compassやsusyは始めて使ったものではあったのですが、それを試せたのは何よりも収穫だったと思います。

 たぶん、そういうものを試していく場所というのは、自分にとっては楽しい場所であるので、とてもよかったと思います。また、そういう「自分を楽にしてくれそうなオープンソース」の情報を集めておくことで、開発が便利になる側面もあるように感じます。

一度必要な画面・構成を洗い出してみる

 今回は、必要な画面が一つしかなかったので、シンプルな作りになったのですが、画面数がおおくなればなるほど、やはりある程度実装量は多くなります。自分は、もう少し若い頃に「超大作システムのRPGを作ろう!」と思って挫折した経験がなんどかあります。実装量が多いということは、それだけ保つべきモチベーションの量も必要になってきます(モチベーションも大切に運用するべきリソースだと思います)。

 どれくらい大きくなりそうなのかというのは、画面数を洗い流してみるとある程度わかったりします。もちろん、クライアント側のJavaScriptが増えれば、また問題は変わってくるのですが、今回の場合は、一画面だったので、実装が割と楽だったというのがあるとは思います。

反省するべきところ

 とはいえ、反省するべきところも無いわけではありません。

作成中に、実際に使ってみてユーザーの反応を見る作業が必要だった

 あとでリリースしてみてわかったのですが、シンプルにすることに拘りすぎてしまったために、実際に自分たち以外のユーザーからどう見えているのか、という調査を怠っていたのが少し問題だったかなと。普通なら、リリース前に、ユーザーの反応というか、使い方を見て、それをフィードバックして必要な機能を追加するという作業をするのですが、今回それをしなかったのは、イケてなかったかなと。「実はこういうのを作ってみたんですよ」という話をすることはあって、そのときに「あー綺麗だね」の一言で終わって、そのあとすぐに閉じる感じだったのに気がつけなかったのはダメだったなと。

 要するに「フック」という部分と、「このサービスがどういうものであるのか」というのを説明する必要はあったなあというのは率直な印象だったりします。実際に、「このサービス、ふと見るとどういうサービスなのかわかりずらい」ということを言われました。そこに鈍感だったのはよくない、というのは反省するべきところです。というのは、そのサービスの「はじめの使い方」をよく知っているのは開発者であって、それはユーザーにとってはわからない。その辺の視点が抜けていたのはよくなかったなと。

まとめ

 いろいろと書き連ねましたが、現在のところ、Bookableについては、自分がハードユーザーであることは間違いではないです。ソフトウェア業界には「ドックフード(=自分が作ったもの)を食べる」という表現がありますが、だいたい自分のつくったものというのは、どことなく愛着が湧いてくるものです。HTML5Canvasにキャラクターを描いて動かしているだけでもニヤニヤできてしまうところは自分にはあって、たぶんそういうものだと思います。

 今後の課題としては、恐らく「自分が一番楽しんで、愛着を持って使っている」というところから、「他の人にも、暇つぶしとして楽しんでもらえる」というところに持っていくというところだと思います。そういう意味で、もし貴方がBookableを使って楽しんでくれるなら、それは自分としても作ってよかったと思える部分だと思います。

 それでは、改めて、Bookableをよろしくお願いします。

 FXでの失敗ケース | Just another WordPress site

2013-03-12

[][]僕がペアプログラミングをするために必要ないくつか 17:26

 現状についてと、その改善案についてメモ。

 現状として、自分が仕事をやっている周りにおいて、ペアプログラミングという習慣がついていない。アジャイル開発、あるいはエクストリームプログラミングに関して、この手法が提唱されている。ただ、この手法については、タイミングが取れなかったり、例えば「テストファースト」よりも、明確な効果(しかし長期的な効果は必ずある)が無いというのがあって、現状としてどういても実践できていないし、その実践に対する提唱が出来なかったりしている。

 ペアプログラミングは、「一つの実装を二人で行なう」ということを行なうため、どうしても工数の問題を考えるとするなら、「一人のことを一人にやらせたほうがいいのではないか」という疑問があって、その辺りの疑問に関しては既に「いや、ペアプログラミングしたほうが作業量が多くなる、生産的になる」といわれたりしていて、その辺は、先達のアジャイルサムライたちが口を酸っぱくして言っている。

 とはいえ、ペアプログラミングは、素晴らしい実践方法であっても、あくまでも「実践方法」でしかなく、たぶん無理していれなくてもいいのかもね、とは思う。ただ、自分が置かれている現状を省みて、ある程度時間を裂いてでもペアプログラミングはするべきなんじゃないんだろうか、という意見にシフトしつつある。

ペアプログラミングをしない幾つかの理由

 で、ペアプログラミング効用自体は酸っぱく言われているからいいのだけれども、かといって、なかなか「じゃあペアプログラミングしよう」という形にならなかったりする。それは一体どうしてだろうなーということを、とりあえず現状の職場と照らし合わせて反省的に考えてみることにする。

タスクの役割分担が邪魔をする

 実際に開発をしていく場合、何らかの単位でタスクを振り分けることになると思う。そういった場合、どうしても「あのタスクはあの人の担当だから」ということになりがちになってしまう。そうすると、露骨にそういうことは言わないけれども、「そのタスクはその人がやるべきことであって、自分が関係することではない」といったような、悪い意味で、分担されてしまうことになる。そういう場合、ペアプログラミングをする機会というのは、たいてい「そのタスクが遅れている原因を探るため」といったような形で導入されることになる。

 確かに、そのような「タスクが遅れているから、助言をするためにペアプログラミングする」という方法は一つの方法であるとは思うのだが、これだけだと、一つ欠点があって、「そのタスクが順調に見えているうちには、実装に問題があったとしてもそれに気がつくことが無い」ということになってしまいがちになる。また、これにはもう一つの欠点があって、「その実装を行なうにさいして、もっと良い方法があるのにも関わらず、そのときのスキルで実装し続けることになる」ということもある。

 たぶん、ペアプログラミング効用というのは、そのような短期的な「悩んでいる部分に対して問題解決をする」ということではなく、「もっと良いやりかたがあるのにも関わらず、それが共有できていない」という状態を、できるだけなだらかにすることができるという部分という効用もあるはずだ。と考えると、意外にも「タスクの役割によってわけてノータッチ」という方法は、それほどよくない可能性がある。

なんでペアプログラミングが重要だと感じるのか

 で、上記理由があったとして、「それでなんでペアプログラミングなの?」という話になる。

 一つの理由として、「中期的・長期的にスキルのばらつきを解消する」という方法がありうるように思う。要するに全体の底上げ。実際に、ある人が実装したコードにバグが見つかって修正しようとしたときに、余りにもコードがおかしすぎて頭を抱え込むことがあったりする。あるいは、頭を抱え込ませていることがあると思う。そういうスキルによるすれ違いというものに関しては、できるだけ少ない方が、お互いストレスを抱え込まなくて済むし、ストレスが無くて良い。

 あともう一つとして、例えばHTMLの組み込みの場合でもそうなんだけど、「これって常識だよね」って思っていることって、意外と常識的ではなかったりするし、自分ですら「普通ならばこういう風に設計するよね」という知識がなかったりすることがある。そういうことは、「これって常識だよね」と思っているがゆえに、スキルとして共有されなかったりする。例えば、自分の場合は福岡出身だったりするんだけど、「なおす(博多弁では「修正する」)」という言葉が方言にあたるということを知らなかったりしていた。そういうのは往々にしてある。

 つまり、ペアプログラミングは、単に「その実装が上手くいっているかどうか」をチェックする、という部分に焦点をあてすぎると、不味いわけで、むしろ「その実装に対してどのようなアプローチを取っているのか」、あるいは「その実装をとりまくその人の背景がどうなっているのか」という部分も重要なわけで、その辺までカバーできたらいいなあとは思う。

 そんな感じで、今の状態が落ち着いたら、定期的にペアプロができるような環境作りと実践をしたいですね。

2013-03-09

[][]ちょっとしたユニットテストアンチパターンについて 23:44

 最近の置かれている状態について考える。

前提: ユニットテストは書かれるべきか

 まず一つに、ユニットテストがテストの全てではないし、それで全てが解決できる銀の弾丸でもないけれども、自分みたいな凡人(あるいは以下の)プログラマーにとっては、テストを意識して実装するということは、コードを綺麗にするという意味でも、実装された内容を保証するという意味でも重要な行為だと思う。しかし、最初は意識高くテストファーストを実行していたとしても、早急な対応であったり、納期であったりの問題で飛ばされ、テストが壮大に破壊されるという場合があると思う。

 その辺は、納期などの問題で「仕方ないよね、今は機能を実装することが優先されるべきなのだ!」という形になったとしても、テストを書く行程が削られたために、「より早く」何かしらの機能が実装できるという場合ならいい。しかし現実問題としては、テストを書く行程が削られたことによって、その機能が本当に実装されているのか、他の機能との同一処理を確保できているのか、といった部分や、手でテストを行なうよりも確認が早く済む(し、実装も早い)という場合があって、結局ユニットテストを守ればよかったじゃないか、ということになって辛い思いをしてしまう場合もある。

 難しいのは、意識を高くしていても、その意識の高さというのはそのような意識の反物質、つまり「ユニットテストを書かせまい」という魔物によって削られる。それはたびたび「アンチパターン」と呼ばれるもので、そのような悪魔は何処にでも潜んでいる。そして、俺は今回その悪魔たちに負けてしまったのだが、しかし悪魔の種類については、幾ばくか理解したので、ここにメモしておく。ベテランのプログラマーの人は「なんでそんなこともしていなかったの」と冷笑して頂ければ幸い。

 ちなみに解決に関しては、「自分だったらこうするね」という例です。

アンチパターン: ユニットテストは、実装が終わったときに逐一実行すればよい

問題

ユニットテストを自動的に動かすスクリプトを書くのは面倒くさいし、そもそもテストなんて、一発で実行できるような何かしらの方法が用意されている。実装中にテストを走らせて赤いのは当たり前のことだ。そんな無駄なことをするくらいだったら、実装が終わったあとに、テストを手で起動したほうがよい。

解決

 このアンチパターンの問題は、「手で動かすことは、動かすのを忘れるし、またその存在を忘れてしまう」ということだと思う。実装できてしまったから、つい嬉しくてユニットテストを忘れてしまって、隣接のユニットテストを破壊してしまっていたということはありうる。それらを防止するためのJenkinsではあるものの、できるならそういう破壊については素早く掴めていたほうが、対応が早くなるし、少なくとも自分にとってはいい。

 一番理想的なタイミングは、恐らく「ファイルが変更されたときに、即座にテストを実行すること」だと思う。それが実行できるスクリプトを実行する。時間がかかる場合は、自分の環境で、できる範囲のテストを定期的に動くようにcronなり叩くといいかもしれない。そして、テストもう一つのソリューションとしては、常用しているエディタから一発でテストできるようなものを仕込んでおく(IDEだったら既にあるかもしれない)。無理矢理テストが実行されてしまう環境が望ましいが、コードを書いている最中にテストを実行できる環境も候補としてある。

アンチパターン: ユニットテストを書いて、実装する。その後はテストコードを読まない。だってそれは実装とは関係ないから

問題

 往々にして、テストコードは、負債になったり、足かせになったりする。何かの変更があった場合に、その変更が波及して、テストが壊れる。もちろん、そのテストを直していけばいい問題なのだが、しかしその変更が多岐に渡り、面倒くさい単純作業になると、とても辛いことになる。その結果として、メンテナンスが遅れてしまったり、余計な工数がかかったり、状況によってはそのメンテナンスのコストをかけるよりも、メンテしないという方向を取る可能性がある(それが悪い結果をもたらす可能性があるかもしれないとわかっていても)。

解決

 実装されたコードのリファクタリングも必要だし、そもそもテストファーストとなると、「テスト→実装→リファクタリング」なわけで、「リファクタリングを怠るとは、このナマケモノめ!」と罵らせてもしかたないし、それはもう頭を下げるしかない。

 なにはともあれ、ユニットテストはちゃんとリファクタリングすること。それも定期的に。

 できることなら変更に対して容易に対応しやすいコードにまとめあげていくこと。変更に対して容易に対応しやすくする方法の一つとしては、同じようなテストを行なっているとするならば、それ専用の関数を用意してあげて、共通にチェックできるようにする。またユニットテスト同士で、同一のデータが使われることが、できることなら望ましい。またそのデータが変更される可能性がある場合なら、定数を予め用意してあげて、使いまわすことができないかどうかを考えると良かったかもしれない。

アンチパターン: そもそもテストが壊れてしまっているし、そのテストもメンテナンスされなくて久しい

問題

 既にプロジェクトに破綻が来しており、納期優先のためにテストが破壊されたまま進行している。確かに、機能を実装することのほうが優先されるべきなのは確かであるものの、しかしさらに困ったことに、テストコードを書いていたときよりも、手動テストのほうが時間がかかってしまうにも関わらず、テストコードが書かれなくなっている。Jenkinsは怒り続けているか、誰も気にしない。こんな状態でテストコードを書いてもしかたないのではないか。

解決

 どのようなテストフレームワークを使っているかどうかはわからないけれども、それなりに良く考えられたテスト・フレームワークであるならば、クラス単位であったり、あるいは、あるテストケースだけを実行できるような方法があるんじゃないかと。

 決してユニットテストを書いていく、あるいはテストファーストで行なうということは、その機能全体を保証するだけではなく、個別のコードについての実装の目安(テスタブルで、適切にメソッド関数として機能を切り分けることができる)が明確になると言うメリットを享受できるわけで、プロジェクト全体はともかくとして、自分が担当しているコードだけは、機能を保証したり、ちゃんとテスタブルなものにしよう、という意味で自分の担当する部分だけでもグリーンとして進めていくという方法はあったと思う。

 このように、とりあえず、自分が実装している部分に関してだけに、ユニットテストを書くというのは、「元々ユニットテストを書く文化ではないのですが」という場合にも有効だろうと思う。

まとめ

 どのアジャイル本でも取り敢えず「テストは書け、テストファーストをやれ」ということは言われるけれども、しかし実際にプロダクトに投入してみると、むしろデメリットというか、コストがかかってしまう部分に関して、どのように対処していくのか、というところの共有はあんまりされていないのかなという部分がわからなくて、さらにこの辺は定期的に愚痴を言う/いわれる分野なので、「あー、テストにしたってこういう風にすればよかったーーー!」ということを共有していただくと、自分としても勉強になるし、今後の資産になるのかな、という感じです。