はじめに
今回は、社内の若手エンジニアを育成する取り組みの一環で開催された、ハッカソン合宿で作成したサービスをご紹介します。
この合宿は毎年開催されていますが、今年からは非エンジニアも巻き込む新たな挑戦もしています。
詳しくは前回のエントリー[若手メンバーで2泊3日のハッカソン合宿@土善旅館に行ってきました!]をご覧ください。
メンバー紹介
イカれたメンバーを紹介するぜ!
- 山賀 美裕(WEBサービス開発部)
ときめくこと(を見てるの)が好きで、自分の趣味も兼ねて今回のサービスの元ネタを企画。
普段の業務は、不動産サービスの開発(主にAndroidアプリ)です。 - 佐藤 光(WEBサービス開発部)
日本酒が好きすぎて、お酒の趣味がおっさんと言われたことがある22歳エンジニア。
普段の業務は求人サービスのiOS/Androidアプリの開発をしています。 - 佐藤 葵(ポータルサービス部)
合コン行ったことないし、飲み会にも行かないし、 お酒飲まないし、コミュ障こじらせてるしでこのサービスとは一番遠い存在。 非エンジニアです。 - 清水 大輝(WEBサービス開発部)/サポート
合コンは一度だけ行ったことあるがなんやかんやで二度と行かないと固く誓った学生時代。
最近の業務ではawkとmysqlと戯れている事が多いけど一番好きなのはPHP。
制作物について
サービスの紹介
気になるあの子を誘うとき、何かきっかけがあると誘いやすいですよね・・・
例えば、お互い好きな食べ物が一致して盛り上がったとき、自然とお誘いできたことはありませんか・・・?
でも、気になるあの子のニーズに合わせた引き出しがないことはありませんか・・・?
そんなとき、イケテルあの人の引き出しを借りることができればと思うことありませんか・・・?
今回つくったサービスは、そんな「引き出し」をすばやく手に入れることができるサービスです!
企画段階では、下記のエレベーターピッチを作成しました!
このサービスは、2回目の食事にスムーズに誘いたい20代社会人男性向けの情報収集サービスです。
ユーザは、すばやく口コミを集めることができ、Google検索とは違い、エモーショナルさ(心が動く情報)が備わっていることが特徴です。
使い方
STEP1 | STEP2 | STEP3 |
気になるあの子の お酒をチェック |
いい頃合いでトイレへ | サイトにアクセスし、 お酒の種類+エリアで検索 |
STEP4 | STEP5 | |
表示されたお店と その魅力を暗記 |
暗記した内容で 気になるあの子をお誘い |
|
サービスの特徴
- 「お酒」から簡単に探せる
飲み会で気になるあの子のドリンクをチェックするだけで、好みに合わせたお店を探すことができます。 - 「3分」でピッタリのお店がみつかる
検索フォームに入力するのは、「お酒」と「場所」だけ!
「場所」は現在地がデフォルト入力されるので、省略することも可能!
この2つで検索をすると、グルメサイトの飲食店情報から人気のお店を3件チョイスして表示します。
簡単なアクションで、すぐにあの子にピッタリのお店が確認できます! - 「エモーショナル」な口コミが読める
行ったことのないお店を魅力的に説明するためには、メニューや場所のような「事実」だけではなく、どんな雰囲気でどんなおいしいお酒があるのかといった「心が動くような表現」が必要なはずです。
今回、そんなエモーショナルな口コミを確認するために、グルメサイトの魅力的な口コミを3件チョイスしました。
①TOP | ②検索結果画面 | ③検索履歴画面 |
技術のこと
今回のハッカソンで技術的に気をつけた、または技術に助けられたポイントは以下の3つでした。
フレームワーク
実はチームメンバー全員が業務でのWEBサービスの開発経験が少ないと言う背景があります。
開発経験が少ないジャンル/言語での開発で一番最初にぶち当たる壁と言えば・・・「環境構築」ですよね?
今回、開発で使用したPHPフレームワークのLaravelに助けられた事例を2つご紹介します。
良くぶち当たる壁① 外部パッケージのインストール
composer.jsonにパッケージの記述を追加
1 2 3 4 5 6 7 8 |
・・・ "require": { "php": ">=5.6.4", "laravel/framework": "5.4.*", "laravel/tinker": "~1.0", "package_name": "version" // こんな感じ }, ・・・ |
terminalで
1 |
$ composer install |
これだけ。
良くぶち当たる壁② サーバ設定、DB設定の共有
terminalで
1 2 3 4 5 |
// table作成、カラム定義追加 $ php artisan migrate // マスターデータを挿入 $ php artisan db:seed |
これだけ。
tableを作成するためのmigrationファイルや、マスターデータを作るためのseeder元データは、誰かが1回は作らなければいけませんが、他のメンバーはコマンドをたたくだけです。
新たに開発メンバーが増えても(今回は増えませんが)、スムーズに開発にJoinできるようになります。
これら2つがあるだけで3時間くらい時間削減できたのではないかと思います。フレームワークに圧倒的感謝!!!!
レスポンシブデザイン
このサービスを使うタイミングは「トイレで席を外してから戻るまでの3分」で想定しているため、スマホでの利用を意識したレスポンシブデザイン(※)にしています。
(※)パソコンやスマートフォンなど各デバイスごとにページのレイアウトを最適化して表示する技術のこと
今回、レスポンシブデザインを実現するために「Material Design Lite」というフレームワークを使用しました。(以下MDL)
レスポンシブデザインといえば、「Bootstrap」も有名ですが、両方使ってみて感じたそれぞれのメリットデメリットは以下です。
メリット | デメリット | |
---|---|---|
Material Design Lite | デザインの方向性が決まっている 元から洗練されているので、時間をかけずに”いい感じ”にできる ※具体例は後述 |
使えるコンポーネントが少ない →例えばBootstrapにはある画像のスライドショーがこちらにはない |
Bootstrap | 使えるコンポーネントが多い 記事が多く問題を解決しやすい |
デザインにこだわる時間がほしい |
MDLは今回のようにあまりデザインに時間を掛けられないハッカソンやモック作成に向いていると言えます。
また、MDLは、フラットデザインを踏襲したシンプルさを持ちながらも、要素の重なり・陰影などの立体感によりユーザビリティの向上を図っている点が特徴です。
例えばボタン。
どちらがより直感的に「押せるもの」だと分かりますか?
左がMDLのボタン表現ですが、要素にメリハリがあって”押せる感”があります。
以下は、Bootstrapのボタンとの比較です。
ボタン1つとっても、MDLとBootstrapで印象が大きく異なります。
MDLの方が洗練されている・今風といった印象を受けます。
とはいってもデザイントレンドは流行り廃りありますので、時代に合ったデザインを取り入れていくことが大事だと思います。
「エモーショナルな口コミ」を得る
今回、2回目のデートに誘えるような「エモーショナル」な情報は、実装時間が限られているためグルメサイトの口コミから取得しています。
「エモーショナル」な情報は「いいお店」の「いい口コミ」の中にあると仮定し、グルメサイトを使ったユーザが良いと判断しているお店/口コミをピックアップして情報を取得しています。
店舗情報
「いいお店」の判断基準としては、お店につけられる評価の上位3店舗を取得しています。
当初は上位1件のみを取得していましたが、お酒で検索しているのにカフェのお店が表示されてしまうことがあったため3件表示しています。
※本当はデータを取得する時点でカフェなどを弾くようにできれば良かったですが、時間が・・・。
口コミ
「いい口コミ」に関しても「いいお店」の判断基準と同様に、口コミにつけられる評価の上位3件を取得しています。
表示される口コミ内に検索したお酒の名前が入っていた場合は、その文字がハイライトされるため、より彼女の心を動かすことができる口コミが見つけやすくなっています!
以下簡単な実装内容
口コミの取得は、PHPのスクレイピングツールであるGoutteを利用しました。
こちらの記事を参考に:http://qiita.com/kumechang/items/5f7bed354109a91f0abc
・環境構築
composer.jsonに以下を追加
1 2 3 4 5 6 7 8 |
・・・ "require": { "php": ">=5.6.4", "laravel/framework": "5.4.*", "laravel/tinker": "~1.0", "fabpot/goutte": "2.0.*" // これです }, ・・・ |
1 |
$ composer update |
・評価上位3店舗分の口コミ情報取得(一部省略版)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<?php namespace App; use Goutte\Client; class GetReviewInfo { private static $instance; // その他定数など public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new GetReviewInfo(); } return self::$instance; } public function getReview($area, $drink) { // 引数なければ終了 if (is_null($area) || is_null($drink)) { return; } // エリア名、ドリンク名からIDを取得 // hogehoge // Goutte Object $client = new Client(); // 店舗一覧ページへ遷移 $request_url = 'http://hogehoge/'; $crawler = $client->request('GET', $request_url); sleep(0.5); // 最終的に返却する結果を格納する配列 $result = array(); $wanna_go_count_array = array(); $crawler->filter('div.class_name')->each(function ($node) use (&$wanna_go_count_array) { $wanna_go_count = (int)$node->filter('div.class_name')->text(); $shop_info = hogehoge; // 省略 $shop_url = hogehoge; // 省略 $shop_name = hogehoge; // 省略 array_push($wanna_go_count_array, array('wanna_go_count' => $wanna_go_count, 'shop_url' => $shop_url, 'shop_name' => $shop_name)); }); // 上位3店舗分の案件情報取得 // 以下省略 return $result; } } ?> |
合宿で学んだこと
2泊3日とあっという間の開発合宿でしたが、とても貴重な経験をすることができました。
学びはたくさんありましたが、その中でも特に印象に残ったことを紹介します。
同じ立場で相談できる人がいるよさ
普段の業務では、1人で1つのプロダクトを開発することが多く、細かいところまで十分に相談できないこともあります。
しかし今回の合宿では、チームで目的や仕様の共通認識ができていたので、細かいところまで気軽に相談することができました。
その結果、よりきれいなコードを書くことや、提供したい価値の認識を合わせて実装することができました。
ゴールを明確にする重要さ
合宿初日、どうすれば仕様が実現できるかわからず、それぞれが調査・開発をする形で作業を開始しました。
その状態がずるずると続いてしまい、次第に「どこまで仕様が実現できればいいんだっけ?」という悩みや「すでにチームメンバーが調査済みだった・・・」といった無駄な時間がうまれてしまいました。
この状況に危機感を覚え、2日目からは定期的にメンバーで集まり、それぞれの作業内容とゴールを明確にする時間をつくりました。
(このあたりは入社1年目の新人研修で学んだアジャイル手法がかなり役立ちました!)
それにより、無駄な迷いや作業を減らすことができ、合宿期間内に最低限の価値を提供できるサービスをつくることができました。
(非エンジニアの)開発業務の理解
これまで企画サイドでは、やりたいことがあっても、エンジニアにやりたいことを伝えきれないというもどかしい思いをすることが多々ありました。
しかし今回、開発に関する基礎的な知識に触れて以降、開発担当者との会話がスムーズにできるようになったように感じています。
まとめ
つらつらと書きましたが、開発合宿はとっても楽しかったです!!!
エンジニア・非エンジニアにかかわらず、チームで協力してアイディアを形にすることはとてもやりがいがあり、普段の業務では気付けないことに気付け貴重な経験でした。
今後は、
・周りへの状況の発信や他のプロダクトへの当事者意識を持つことで、「同じ立場で相談できる人のいる環境づくり」を強化すること
・ゴールを明確にして無駄な時間を減らすこと
・エンジニアと非エンジニアの共通言語を増やし、それぞれの垣根を越えた密接な連携をすること
を今まで以上に強化し、よりよいサービスづくりをおこないたいと思います。