Appresso Engineer Blog

アプレッソのエンジニアが書く技術ブログです。

IoT World 2016 参加レポート (後半)

こんにちは、開発の田中です。

IoT World 参加レポート後半です。
飛行機出発の時間までに書ききれず、帰国してからのアップになります。

前回の記事では、初日の基調講演と 2 日目の展示について書きました。

appresso.hatenablog.com

今回は最終日の展示についてとまとめを書きます。

最終日の展示では、前日の展示よりも少し焦点を絞って見聞きしてきました。

まずそもそもこの展示会は、ビジネス色が強く、ネットワーキングバーや各ブースで用意したテーブルでネットワーキングや商談を行っていました。
なのでそもそも展示というよりは、テーブルと椅子だけ持ってきて、商談するつもりしかないようなブースも散見されました。
というわけで技術的な露出はあまり多くありませんでした。

ミッションクリティカルについて

主に工場の生産システムや農業の最適化、スマートシティに対するソリューションを持っている企業に聞いてみました。

センサーといっても様々で、例えば工場内のロボットなどに取り付けるセンサーであれば、データのロスは絶対に起こしたくないので、非常に精度が高く、センサーの故障も少ないそうです。
逆に、コンシューマー寄りであったり、データが落ちても良い分野もあって、そういうところで使われるセンサーはそもそもセンサー自体の故障も多いそうです。
いずれにしろ、最近ではゲートウェイの役割が重要になってきており、センサデータはゲートウェイで粒度を揃えたり、ウインドウ集計を行うことが多いようです。
そこから最終的な IoT プラットフォームにデータを集めるようです。
ゲートウェイからアップロードされるデータはミッションクリティカルと言えるのではないでしょうか。

無線ネットワークについて

気になったところをメモっておきます。

アメリカでは鉱業が盛んな地域では、ネットワークインフラが全く存在しないこともあるそうです。
そのような地域で、例えばトラックの効率的な運用をナビゲーションするようなシステムを構築しようと思うと、自分たちでネットワークインフラを構築しないと行けないこともあるそうです。

また、無線の高速化や、カバーしている範囲を広げるために 5G の研究が進んでいるという話やマルチバンド LTE アンテナのブースもありました。
マルチバンド LTE アンテナだと、parsec という会社が目立っていました。

デバイスについて

IoT ゲートウェイに関してはほとんど見当たらなかったです。
エッジコンピューティングという言葉も数回聞いた程度でした。
近いところでは、ARTIK と Supermicro という会社が一番目立っていました。
ARTIK も、IoT ゲートウェイというよりは、さまざまな組み合わせが可能な組み込みデバイスと言った感じです。
ARTIK はスマートホームソリューションをブースで展示していました。

f:id:ktanaka89:20160516064733j:plain

ARTIK の組み合わせ可能なデバイス

デバイスマネジメントについて

私は IoT ゲートウェイの向こうにあるセンサーの状況まで管理できるツールや仕組みがないかなと探してみたのですが残念ながら見当たりませんでした。
デバイスマネジメント自体はそこそこ展示してあって、infiswift という会社はかなり広い範囲をカバーしているプラットフォームを持っていました。
とはいえ、デバイスマネジメントの仕組みは、私がわかりやすい印象で言えば、AWS IoT と同様で、自社サービスのバックエンドで稼働している MQTT Broker を使用していました。
infiswift でいうと、可視化ツール、あるいは、どのようなデータが来たら、どのような処理を行うか、などのルールエンジンも持っていました。

まとめ

私は DataSpider および HULFT IoT を開発しているという観点から、エンタプライズ向けのサービスやソリューションを中心に見てきましたが、日本の IoT 向けのサービスは非常に先進的であるという印象を受けました。
IoT World という展示会の性質上、あまり技術的な露出がなかったというのもあるので厳密には比較できませんが、プロトコルであったり、ネットワークあるいはデータ処理の負荷分散であったり、日本のサービスは様々な工夫をしていると思いました。
ただ、IoT World で展示されていた、工業・農業の最適化ソリューションの多くは R&D の段階で、これがどれだけ通用するか、受け入れられるかはまだまだこれからなところがあるので、また来年どうなっているかが非常に楽しみです。

以下、展示会の様子です。

f:id:ktanaka89:20160516065440j:plain

会場入ってすぐのビッグスポンサーのブース

一番わかり易い IoT のイメージは、よりたくさんのデバイスがクラウドに繋がるようになりました、というところだと私は思っているのですが、デバイスからクラウド、場合によってはネットワークまでカバーできると謳っているのは、ビッグスポンサーである、Hitach、Avnet、Analog Devices、などでしょうか。
デバイス自体の展示は、あまり多くなかったと思います。

f:id:ktanaka89:20160516070259j:plain

Hitach さんの R&D 展示

f:id:ktanaka89:20160516070322j:plain

展示していたソリューションでもでは、Lumada を活用している部分もあるらしいのですが、幅広く IoT に必要な機能を迅速に提供できることができるというメッセージ性が強いのかなという印象でした。

全体の印象としては、AWS IoT のようなバックエンド (MQTT Blocker やデバイスマネジメント、ルールエンジン) + リアルタイムな可視化が多かったと思います。

余談...

f:id:ktanaka89:20160516065152j:plain

展示会初日、こちらで活動しているセゾン情報の人と食べた肉

一人での旅はなかなか心細いものがありましたが、Uber で乗った車の運転手さんには何度も励ましてもらいました。
ありがとうございました。

IoT World 2016 参加レポート (前半)

こんにちは、開発の田中です。

日本では IT Week 開催中で非常に盛り上がっているようです。
弊社もクラウドと IoT で出展しています。

www.appresso.com

私は現在 HULFT IoT を開発しているのですが、この開発チームで展示会に向けてかなり手の込んだ準備をしてきました。
レゴで工場を再現して、HULFT IoT + HULFT + DataSpider で工場をモニタリングしています。
私達の持っている製品や、ぷらっとホームさんの IoT ゲートウェイなどフル活用しています。
ぜひお立ち寄りください。

私はといえば、サンタクララで開催中の IoT World 2016 に参加しております。

iotworldevent.com

今回は re:Invent の時のように出展してくるわけではなく、基調講演やシンポジウムを聴いたり、展示を見に来ています。

月曜日に成田から一日一本出ている ANA のサンノゼ直行便に乗り、現地の午前中に到着しました。
イベントは今日 (5/10) からなので、到着してからすぐにホテルにチェックインし、サンノゼダウンタウンや、イベントが開催されるサンタクララコンベンションセンターの近くを散策していました。

初日

さて、初日 (5/9) の IoT World は展示はなく、基調講演のみでした。

Internet of Things World » Day 1

基調講演なので、IoT の包括的な話がメインで、ビジネスモデルがどうとか、どんな可能性があるだとか、そんな話でした。
ものすごくざっくりまとめると以下のようになります。

  • IoT というのは特定の特化した分野を指すのではなく複合的な分野である。
  • 可能性の実現のために、大小さまざまな会社や組織を巻き込んでいく。
  • そして我々はどことパートナーと組んでいて、どんなエコシステムを構築しているか。
  • あるいは我々だけでどこまでトータルでカバーできるか。

IoT の適用分野としては、工業・農業の最適化、ヘルスケア、スマートホーム、スマートシティ、あとはスタジアムや鉄道などでどのように人の安全を守るか、などが挙げられていました。

スマートシティについては、サンフランシスコ市の Chief Information Officer (CIO) が基調講演に登壇していました。
スマートシティが語られるときは大抵、都市機構の最適化か、その前提にあるフリーなネットワーク環境の拡充のいずれかですが、今回はフリーなアクセスポイントの拡充についてでした。
誰もがどこでもネットにアクセすることで、今まで機会に恵まれなかった人たちもネットに繋がり、勉強あるいは開発ができるようになる、などの話が印象的でした。

またキーワードとしては、「IoT プラットフォーム」、「IoT エコシステム」といった言葉を頻繁に聞きました。

「IoT エコシステム」というのはつまり、われわれはどういうコンセプトでどことパートナーシップを組んでいるのだとか、どこまでトータルでカバーできます、という文脈で語られることが多かったと思います。

「IoT プラットフォーム」という言葉が使われるコンテキストとしては、IoT と言うのは様々なシステムやサービス、ハードウェアを繋げる必要があり、複合的で複雑なので、どれだけシンプルに IoT に必要な部品を提供できるか、という文脈で語られていたと思います。

2 日目

さて、2 日目の展示からが本番といった様子で、人の数も段違いでした。

展示は 2 日間あるので、初日はざっくりとどういう出展があるのかを見てきました。

ざっくりとした感想としては以下の通りです。

  • とにかくリアルタイム
    • リアルタイムにグラフ表示
    • リアルタイムにフィードバック
  • エコシステム・プラットフォーム・あるいは多種多様な組み合わせを実現できることをアピール

私の英語力の問題で、突っ込んだ質問ができていないというのもありますが、気になっている点としては以下の通りです。

  • 採用しているプロトコル
  • エコシステム、プラットフォームごととの違い
  • デバイスマネジメント
  • ミッションクリティカル領域に対するアプローチ

採用しているプロトコルについては Device -> Cloud に関しては聞いて回ったところ、MQTT か HTTP しかありませんでしたが、日本では SORACOM Beam が注目されているのもあって、もうちょっと深掘りしたいなと思っています。
この点について 2 日目は聞いてまわろうと思っています。

以下、会場内の様子です。

f:id:ktanaka89:20160513005439j:plain

会場内のスペースでエコシステムのセッション

f:id:ktanaka89:20160513005451j:plain

同じく会場内で、主に Eclipse Foundation による OPEN SOUCE SUMMIT 。
気になるプロジェクトがあったので後でチェックします。

f:id:ktanaka89:20160513005512j:plain

IoT World ではスマートシティを再現していました。
温度湿度以外にも、駐車場の空き状況とかもモニタリングしています。
テーブルの下の段に、多種多様なセンサーや Arduino/Rasberry Pi らしきものが見えます。

会場では、IoT World 以外にも apps world North America や、Future Connected Cars USA が同時開催されています。

f:id:ktanaka89:20160513005322j:plain

巨大なドロイド君 (正式には Bugdroid というらしい)

その他では、SONY さんの FUTURE LAB ウェアラブルデバイスが気になりました。

f:id:ktanaka89:20160513005213j:plain

しっくりくる装着感のウェアラブルデバイス

今までタブレットでできていた、例えば天気を聞いたり、おすすめの店を探したりを音声だけでできるようになるだけでなく、SDK が用意されているので、さまざまなサービスと連携できそうです。
発売はまだだそうですが、非常に期待が持てました。

www.futurelab.sony.net

余談

サンノゼ・サンタクララはタクシーを拾うのにも結構苦労します。完全に車社会です。
そこで旅行者にとってありがたいサービスが、Uber (ウーバー) です。
アプリで乗車位置をと目的地を入力すると数分でピックアップしに来てくれます。
車に乗った後は、自動的に始まる英会話レッスンをこなしながら、到着を待つだけ!
非常に便利です。

そして歩き疲れておなかが減ると食べたくなるのがラーメンですね。

f:id:ktanaka89:20160513005250j:plain

ジャパンタウンでいただいた味噌ラーメン

ちょっと辛かったですが、普通においしい味噌ラーメンでした。
ごちそうさまでした。

というわけで、 IoT World 最終日もがんばってきます。

まだまだ整理しきれていないところや、書ききれていないところがありますが、そこは乞うご期待でお願いします!

サンタクララから以上です。

そして、ペアプログラミングをもう一度

開発部の野口です。

ここ数日、毎日 2 ~ 3 時間ずつペアプログラミングをしてみています。

アプレッソには昔からペアプログラミングをする文化があり、これまでにも要所要所でペアプログラミングをしたことはありました。
たとえば、

  • 実装が難しいコードについて相談がてらペアプログラミング
  • コミットレビュー*1の修正がてらペアプログラミング
  • 社内勉強会の準備でペアコードリーディング(これも一種のペアプログラミング)

などです。
しかし、毎日決まった時間、必ずペアプログラミングをするというのは、私にとって初めての試みです。

始めてからまだ一週間程度ですが、色々とわかったことがあります。

すごくつかれる

ペアプログラミングは、疲れます。

仮説 : 疲れなければペアプログラミングではない

初日のペアプログラミング終了時に、まず感じたことがこれでした。
むしろ、疲れなければそれはペアプログラミングではないのでは、という感さえあります。

ペアプログラミングでは、たえず同僚の視線にさらされながらプログラミングを行います。

Twitter をチェックする時間は 0.1 秒もないし、いつもならついボーッとしてしまうビルド待ちの時間にも、相手にちょっとした説明をしたり、雑談したりします。
しようとしていることをナビゲーター*2にわかってもらわないと意味がないので、ドライバー*3は常にナビゲーターの理解を確かめ、必要に応じて説明しながらコードを書く必要があります。

見られて恥ずかしくないコードを書く

実は、社外から来ていただいている凄腕エンジニアと組んでやっています。
ドライバーの立場では、見られて恥ずかしくないコードを書かなくては、ナビゲーターの立場では、少しでも鋭い指摘や提案をしなくては、という意識がずっと働いていて、すごく集中します

現在はペア担当者とお互いのタスクを相互に見るようなかたちで進めていて、だいたい 1 時間でタスクを切り替えています。
その 1 時間のなかに休憩をはさむ場合もあれば、1 時間続ける場合もありますが、タスクの切り替えのあいだには 10 分くらいの休憩を取ります。

その 1 時間が終わったときにはヘロヘロになりますし、両方終わったときにはほとんど放心状態になります。

すごくはかどる

さて、そんなに疲れるペアプログラミングは……ご推察の通り、はかどります。

データ : 工数は 15% 増加する

ペアプログラミング』(ピアソン・エデュケーション、2003)の著者らの調査によると、ペアプログラミングでは開発にかかる工数(人時)が 15% 程度増加した、というデータがあります。

つまり、一人でやって 20 時間かかるタスクなら、

  • 二人でやった場合の工数が、20 * 1.15 = 23 時間(人時)
  • 一人あたりにすると 11.5 時間
  • 経過時間(工期)も 11.5 時間

ということになります。

私は現在のタスクをきちんと測定しているわけではないですが、感覚としてこれはおおむね正しい数字だと思います。
一人で作業するときよりは、明らかに速いペースで開発が進んでいますし、かといって 2 倍の速度かというとさすがにそれはないかな、という気がします。

全体としての工数は、増えています。
データでは 15% の増加で、20 時間の作業に対して 3 時間 の増加です。

工期は縮む

しかし、工期は縮んでいます。
始めてから最短で 20 時間後にしか仕上がらなかったはずの作業が、11.5 時間後には仕上がる計算、実に 8.5 時間もの短縮です。

情報共有と品質の向上が圧倒的にはかどる

よってペアプログラミングはいざというときの工期短縮に役立ちます、と言いたいわけではないです。
もちろん、役立つとは思いますが。

むしろ、(一週間やり続けてみた現時点で感じている)ペアプログラミングの真髄は、情報共有品質の向上です。
15% 程度の工数増加で、ものすごい帯域幅で圧倒的にお互いが持つ知識の共有が進み、また、一人でやっていたらきっとここまで丁寧じゃない、というクオリティで成果物が生まれていきます。

私にとっては毎日が発見の連続であり、またペア担当者も熟練者ながらに、色々と新しいものを見つけてくれているようです。
私たちが開発している DataSpider Servista の開発者としてはまだそれほどの経験がない、ということも大きいのかもしれません。

クオリティについては、一人でやっていても最終的にはそのレベルまで上げるのですが、開発の後半で品質を上げることには大きな労力(とつらさ)を伴います。
ペアプログラミングをしていると、作業中の成果物の品質が常に高いレベルに保たれて、早期に品質を作りこんでいる状態になるので、後顧の憂いなく、ずんずん進んでいけます。

すごくたのしい

そんなわけで、ペアプログラミングは何よりも、たのしいです。

自信を持って作業を進めることはたのしい

ペアプログラミングはたのしいんです!

大事なことなので二回言いました。

おそらく多くのプログラマはそうだと思うのですが、私は、役に立って、高品質なソフトウェアを、すばやく開発したいと思っています。
そして、簡単に言うと、ペアプログラミングによってそれが実現されます。(少なくとも、大きく推進されます)

いいものを作りたい、と思います。
しかし、一人でプログラミングをしていると、コードを書く、仕様上・設計上の判断をするその瞬間瞬間に、ほんとうにいいことをしているかどうかチェックできるのも、気づくことができるのも、軌道修正できるのも、ただ一人、自分だけです。

ペアで作業をしていると、常にもう一人の開発者がほんとうにいいことをしているかチェックしてくれます。していなければ、違う、と言ってくれます。
これは大きな喜びです。そして、自信を持って作業を進めることができます。プログラミングに限らず、後顧の憂いがない、ということは人間の喜びにとって重要な要素ではないでしょうか。

そして、ペアプログラミングをもう一度

少し熱くなりすぎました。

ペアプログラミングが終わる日

実は、このエントリは以下のエントリをもとに書き始めました。

アプレッソで、およそ 9 年前にも、ペアプログラミングを集中的に行ったことがあった、ということの記録です。
ペアプログラミングを絶賛する論調ですが、はっきり言って、今の私は、これらの記述に深くうなずきます。その通りだ、と思います。*4

しかし、事実として、現在のアプレッソではペアプログラミングをほとんど行っていません。
最初に書いたように補助的には行っていて、平均して勤務時間の 5% くらいはペアプログラミングしている気がしますが、9 年前のエントリの論調から考えると、いかにも隔たりを感じます。

私が今行っているペアプログラミングはとてもうまくいっていますが、続けていくと、色々と課題が噴出するものなのかもしれません。
前出の『ペアプログラミング』にも、「すべての人がペアプログラミングに向いているわけではない」とはっきりと、また、繰り返し書かれています。

おそらく、今のアプレッソにも、ペアプログラミングを好まない人や、ペアプログラミングをうまくできない人というのはいるのだろうと思います。
それは、悪いことではありません。

そして、ペアプログラミングをもう一度

それでも、やはり、ペアプログラミングがたのしく、開発をぐんぐん進捗させるものであることは事実です。
少なくとも、事実となる場合があります。

「すべての人がペアプログラミングに向いているわけではない」ということも念頭に置き、ペアプログラミングをしない人の居心地が悪くならないように気をつけつつ、9 年ぶり(?)に再開したペアプログラミングを続けて、アプレッソをよりたのしく、効率的に開発できる組織にしていけたら、と思っています。

関連エントリ

それから 1 年後の記事です。

appresso.hatenablog.com

*1:アプレッソでは 1 年くらい前までコミット時に必ず対面でのレビューを行っていました。現在は Github:Enterprise 上での Pull Request に置き換えられています

*2:ペアプログラミング用語で、キーボードを持つ人をドライバー、見て意見を出す人をナビゲーターといいます

*3:前注を参照

*4:なお突っ込まれないように予め言っておくと、「すべての勤務時間をペアプログラミングする」というのはさすがになかなか大変そうだ、とも思います。前出の通り、疲れるので。

Java 8 勉強会・再び 第1回 ~デフォルトメソッド~

こんにちは、アプレッソ開発部の陳です。

秋が終わり、本格的に冬に入って、今年も残り僅かとなりました。

春(3月)から始まった Java 8 勉強会ですが、すでに予定したテーマを半分以上消化したにもかかわらず、内容は全然共有できていない状況です…(汗)

ここでアプレッソ Advent Calendar 2015とさくさにまぎれて勢いに乗って、Java 8 勉強会の内容共有を再開することにしました。 せっかくの再開なので、勉強会の内容をできるだけ細かく説明していきたいと思います。

今回はデフォルトメソッドについてお話ししたいと思います。

デフォルトメソッドのおさらい

Java 8 で導入された デフォルトメソッド は名前の通り、インタフェースで定義されたメソッドのデフォルト実装を提供する仕組みです。

基本的な使い方として二通りがあって、処理の一般形として提供するケース

// java.util.List (OpenJDK8)
default void sort(Comparator<? super E> c) {
    Collections.sort(this, c);
}

と、仕様の契約として提供するケースがあります。

// java.util.Iterator
default void remove() {
    throws new UnsupportedOperationException(”remove”);
}

デフォルトメソッドを導入しする主な意図は、API拡張時の既存実装とのソース互換性を維持するためです。 上記の例にあったように、実際 Java 8 では新しいフィーチャーの互換性を維持するため、デフォルトメソッドを多用しています。

デフォルトメソッドの使用場面

シンプルそうに見えるデフォルトメソッドですが、実は地味にいろんな場面で役に立っています。

API拡張時の互換性維持

Java 7 以前、java.util.Iterator の定義は以下のようになっています。

// Java 7
public interface Iterator<E>() {
    boolean hasNext();
    E next();
    void remove();
}

Java 8 になって、イテレーションの残り要素に順次処理を適用するメソッド forEachRemaining(Consumer<? super E>) が追加されました。 この処理は他のメソッドの組み合わせで実現可能なので、デフォルトメソッドをインタフェースに追加することで、すべての実装クラスの互換性が維持されます。

// Java 8
public interface Iterator<E>() {
    boolean hasNext();
    E next();
    default void remove() {...}
    default void forEachRemaining(Consumer<? super E> c) {...}
}

実装が必須でないメソッド

前節の java.util.Iterator をもう一回見ましょう。

Java 7 以前、remove() メソッドを提供しない実装クラスでも、例外を投げるメソッドを用意する必要があります。 プログラマにとって、このようなメソッドは関心の対象ではないので、ある意味ただのノイズになります。

// Java 7
class NonRemovableIterator implements Iterator<Object> {
    public boolean hasNext() {...}
    public Object next() {...}
    public void remove() {
        throws new UnsupportedOperationException(”remove”);
    }
}

Java 8 では remove() のデフォルトメソッドが追加されたため、この場合では remove() の実装が不要となりました。 結果として、コードが簡潔になって、関心の対象にも集中しやすくなります。

// Java 8
class NonRemovableIterator implements Iterator<Object> {
    public boolean hasNext() {...}
    public Object next() {...}
}

振る舞いの多重継承と再利用

類似するインタフェースがいくつか存在している場合、デフォルトメソッドを使うとそれらの一般的な振る舞いを再利用*1できます。

少し抽象な例になりますが、生き物とその運動能力の関係を以下のように表して、生き物をクラス、運動能力をインタフェースと見立てます。

f:id:chyiro:20151214170047p:plain

このように、ペンギンが「泳ぐ」と「歩く」、ピューマが「歩く」と「走る」、ペガサスは「飛ぶ」「歩く」「走る」、くも子*2は「泳ぐ」「飛ぶ」「歩く」「走る」ことができます。

運動能力を表すインタフェースにはそれに対応する動きをデフォルトメソッドとして定義すると、生き物たちのクラスは対応するインタフェースを実装するだけで振る舞いを再利用できます。

ただし、このような振る舞いの多重継承は一見便利ですが、前提としてインタフェースのメソッド定義は適切な直交化が必要になります。そうでないと、かえってソースコードの可読性とメンテナンス性を害するオチになります…

メソッド参照の解決ルール

前述したように、デフォルトメソッド導入によって、振る舞いの多重継承が可能になりました。

メソッド実装の参照先が複数存在する状況を解決するため、いくつかの解決ルールが追加されました。自動的にメソッド実装を解決するルールは以下の優先度順になります。

  1. クラスのメソッド実装
  2. 最も特定的なインタフェース*3のデフォルトメソッド

最も特定的なインタフェースが複数存在する場合、上記ルールでは自動的解決できないので、コンパイルエラーになります。この場合は明示的に参照先インタフェースを指定する必要があります。

スーパークラスのメソッド実装が存在する場合、自動解決より明示的に指定した参照先が優先されます。

文章での説明は分かりづらいかもしれないので、簡単な例を見てみましょう。

ルール1: クラスのメソッド実装を使用

クラス C がクラス A を継承し、インタフェース B を実装しています。A と B はそれぞれ hello() の実装とデフォルトメソッドがあります。

class A {
    public void hello() { System.out.println("A"); }
}
interface B {
    default void hello() { System.out.println("B"); }
}
class C extends A implements B {
    // A のデフォルトメソッドを使用
}

この場合、ルール1は適用されて、C の hello() は A の実装を使用することになります。

f:id:chyiro:20151214132905p:plain

ルール2: 最も特定的なインタフェースのデフォルトメソッドを使用

クラス C がインタフェース A とインタフェース B を実装していて、B が A を継承しています。A と B は両方共 hello() のデフォルトメソッドがあります。

interface A {
    default void hello() { System.out.println("A"); }
}
interface B extends A {
    default void hello() { System.out.println("B"); }
}
class C implements A, B {
    // B のデフォルトメソッドを使用
}

この場合、ルール2は適用されて、C の hello() は B の実装を使用することになります。

f:id:chyiro:20151214132912p:plain

番外: 自動解決できない場合

インタフェース A とインタフェース B は両方共 hello() のデフォルトメソッドを持つが、お互い関係ありません。 クラス C が A と B を両方実装していて、インタフェース D が A と B を両方継承しています。

interface A {
    default void hello() { System.out.println("A"); }
}
interface B {
    default void hello() { System.out.println("B"); }
}
class C implements A, B {
    // 実装参照先を自動解決できないので、コンパイルエラーになる
}
interface D extends A, B {
    // 実装参照先を自動解決できないので、コンパイルエラーになる
}

この場合、C と D の hello() の実装参照先を明示的に指定する必要があります。

class C implements A, B {
    public void hello() {
        A.super.hello();  // A のデフォルトメソッドを使用
    }
}
interface D extends A, B {
    public void hello() {
        B.super.hello();  // B のデフォルトメソッドを使用
    }
}

(おまけ)ダイアモンドにまつわる話

多重継承といえば、やはりダイアモンド*4ですね。

Java 7 以前、多重継承できるのは実装を持たないインタフェースだけなので、メソッド実装参照先にあいまい性がありません。したがって、ダイアモンドがあっても、問題は発生しません。

Java 8 にデフォルトメソッドが導入されて、インタフェースにも実装を持つことができるようになりました。ダイアモンド問題は存在しているが、前述した実装参照先の解決ルールを採用することで、解決されました。

f:id:chyiro:20151214142559p:plain

余談ですが、去年(2014)東京での Java Day Tech Night: Ask the Experts では、クラス多重継承またはそれに準じるフィーチャーが追加される可能性があるかという質問が上がったが、エキスパートの方にきっぱりと否定されました。*5

まとめ

デフォルトメソッドは Java 8 のほかの新しいフィーチャーと比べて、あまりファンシーさがなくて影も薄いですが、その存在がほかの新フィーチャーの支えとなっていて、既存コードへのインパクトと導入時コストを抑える役割を見事に果たしています。

今回は主にその性質や使い方に着目して記事にまとめましたが、どのように実現したかは触れていないので、機会があればまたその部分を深く掘り下げたいと思います。

*1:ほかの OOP 言語での mixin の役割と同様です。

*2:雲の上に住んでいるクモの妖精です。

*3:継承関係において最も下位にあるインタフェースを指します。

*4:炭素の結晶体ではなく、かの有名な菱形継承問題のことです。

*5:まあ、Java の設計思想から考えると、その方向はまずありえないでしょう…

テスターとして心がける5つのこと

こんにちは、株式会社メディアフォースの山田と申します。
本記事は アプレッソ Advent Calendar 2015 の 21 日目の記事です。

qiita.com

はじめに

アプレッソでは、DataSpider Servista という様々なデータベースやクラウドサービスなどと簡単にデータ連携*1を行う製品を開発しています。 EAI製品はその製品の特性上、データを確実に、かつ簡単に連携することが求められます。
そのため、アプレッソにはQAグループという品質保証を専門に行うグループが存在し、DataSpider Servista の品質を支えています。

2014年から現在に至るまで2年間、QAグループの業務に携わった経験からテスターがテストを行うときに心がけるべき5つのことについてご紹介します。

テスターとして心がける5つのこと

  1. ユーザーを意識せよ
  2. 正直であるべき
  3. 情報を共有せよ
  4. つらいテストは見直すべし
  5. 手動テストをやるべき

1.ユーザーを意識せよ

QAグループであるので品質のことを考えるのは当然です。
しかし、期限が近くなると目の前のテスト項目を消化させることを優先しがちになります。
消化を優先してしまうと、テスターが使い勝手が悪いと思っている機能でも合格すればよしとしてしまいそうになります。
もしかすると、その機能がユーザー環境ではとても大切な要素であるかもしれません。
我々QAの仕事は与えられたテスト項目を消化することではありません。ソフトウェアの品質を保証することです

ユーザーにとっては開発チームの内情や実装上の都合など関係ありません。
そして、テスターはユーザーの前に製品を触るファーストユーザーです。
どんなときでも実際に製品を使用するユーザーのことを考えテストをしなければいけません。

2.正直であるべき

正直であることは当たり前に聞こえますがとても大切なことです。 たとえば、実施環境が「Windows7」なのに「Windows8」と偽ってテスト結果に記載した場合、テストの実施結果自体に疑惑が生まれます。
また、その実施結果に疑惑が生まれるとその他のテスト結果にも疑惑が生まれ、それがまた疑惑を生む疑惑の連鎖となります。
テスターたるもの常に正直でいなければなりません。

3.情報を共有せよ

テストを実施していると「あれ何かこの動作おかしいな」と思うことがあります。
しかし、それを「まぁ伝えなくていいかな」と放置するのはあまりよくありません。
ちょっとした違和感などから大きな問題が発覚することがありますし、それが実は不具合であることもあります。
また、仲間にそれを相談することで新たな発見があるかもしれません。
実施者たるもの情報を仲間と共有するべきなのです。

しかし、現場によってはテスターがリーダーに気軽に情報を伝えにくい場合も存在します。
そのようなときはテスターもリーダーに勇気を出して一言その旨を伝えてみましょう。
その一言がチーム全体を良い方向に導くかもしれません。

4.つらいテストは見直すべし

アプレッソQAには「実施がつらいテストは見直すべし」というルールがあります。

実施のつらさはテスターに依存しますが、以下のようなパターンが存在します。

  • 試験項目量が多い
  • 事前設定や試験中の設定が複雑
  • 試験手順が設定を兼ねている

実施がつらいテストというのは、過度に時間がかかってしまったり、テスト結果そのものの精度やテスターのメンタルにも悪影響を及ぼします。
テストを見直すことでそれが改善するのであれば試験は見直すべきでしょう。
その結果が次回以降にも活かされ、製品品質の向上に寄与します。

5.手動テストをやるべき

現在、アプレッソQAではテストの自動化が進んでいます。
しかし、自動化では検知できない問題も存在します。
例えば、以下のようなユーザビリティなどが代表的です。

  • よく使うボタンが小さく押しづらい
  • 使用頻度の高い機能に数ステップの手順を要する

自動化テストは正確で高速です。
しかし、利用するのは人であり機械ではありません。
そこに人がテストを行う意義があります。
自動化と手動テストのメリットデメリットを見極め、自動化できることは積極的に自動化し、手動テストを行う時間を多くしましょう

最後に

今回の記事で記載した内容は当たり前のことかもしれませんが、とても大切なことです。
テスト作業はときには大変なこともあるかもしれません。
しかし、テスターひとりひとりが製品の品質を支えているという気概を持って作業を行うことが、製品品質の向上に繋がっていくでしょう。

*1:いわゆるEAI

スクリプト開発時に気をつけるべき3つのポイント

株式会社メディアフォース*1の齊藤です。

本記事は アプレッソ Advent Calendar 2015 の 16 日目の記事です。

qiita.com

本日は EAI 製品導入ベンダとしての経験から、DataSpider Servistaを使ったスクリプト開発のコツをでお話しします*2

はじめに

DataSpider Servista はとても優れた製品です。 データベースやWebサービスに少し理解のある方ならばプログラミング技術がなくとも、短期間で連携処理が構築できます。 これは、開発 - 試験 - リリースを短期間で反復するアジャイル開発にとても向いています*3。 また、アイコンベースで開発するため、エラーの発生箇所が特定しやすく、修正も比較的容易です。

一方で、1つのスクリプト内にアイコンが多くなり、フローが辿りにくくなったり、処理を追加するにもどこを直したら良いかわからなくなった経験のある方は多いのではないでしょうか。  

何がなんだかわからなくなりつつある例

f:id:mf_sol_eai:20151211180341p:plain

こうなってしまうとメンテナンスが非常に大変で、引き継ぐのも一苦労になります。 例えば、エラーメールのメッセージを変更したいと思ったらメール送信アイコン全てを直さなければならず、とても面倒ですね。

DataSpider Servista では、経験上 一度試しに作ってみたスクリプトをそのまま拡張する ところから、スクリプトが無尽蔵に大きくなる傾向にあります。

スッキリさっぱりしたスクリプト例

f:id:mf_sol_eai:20151211180337p:plain

だいぶ見やすくなったと思います。スッキリしたスクリプトにはメリットが多々あります。

例えば

  • 一箇所修正すればすべてに適用される。
  • 追加開発時には連携部だけ開発できる。
  • 見やすいのでメンテナンスしやすい

などなど。 是非とも、スッキリさっぱりスクリプティングを目指していきましょう!

★★★以下、開発手法的な内容になりますので、以下に該当する方は 当社 までご連絡を★★★

  • 今現在ごちゃごちゃしておりスッキリさせたい
  • これからスッキリと DataSpider Servista を導入したい
  • 細かい開発手法はいいからとりあえずスッキリしたい
  • 欲しいものはあるけど作り方がわからない

どうやって開発すればいいの?

スッキリさっぱりスクリプティングのポイントはザックリと3つです。

  1. 重複する処理は作らない
  2. 限定的な役割をもたせる
  3. 個別処理はパッケージ分離する

重複する処理は作らない

先ほどの例では、メール送信アイコンがいくつも置いてありましたね。 メール送信アイコンを1つにすることでだいぶスッキリします。 また、メッセージを変えたい場合も一度の修正で全て直って楽になりますね。

限定的な役割をもたせる

先ほどの例では、1つのスクリプトに以下のような役割がありました。

  • 開始時にメッセージを出すなど初期処理
  • パラメータによって実行内容を変えるコントロール処理
  • 実際にシステムと連携を行う個別連携処理
  • エラー発生時にメールを送信するなどの異常処理
  • 例にはありませんが、実際には終了ログを出すなどの終了処理もあるかも知れません。

コントロールと個別連携処理、個別連携処理内での異常処理など様々な役割を持っていました。 スクリプトの役割を限定させ、分離することで、さっぱりしました。

個別処理はパッケージ分離する

スッキリさっぱりしたスクリプト例では、「private*4」というフォルダがあります。 DataSpider Servista では、スクリプトに対してのアクセス修飾子*5をつけることは出来ませんが、開発規約*6などでアクセス可能領域を明言しておくことでスクリプトの呼び出しを制限しておくと良いです。

最後に

設計 - 開発 - 試験 - リリースを順に行う従来型ウォーターフォール手法の設計方法は計画的設計、 アジャイル開発などで用いられるエクストリーム・プログラミングの設計方法は進化的設計と呼ばれることもあります。

計画的設計、進化的設計双方を効果的に用いることで、DataSpider Servista にマッチした堅牢性と柔軟性を合わせ持った設計が出来ます。

保守性を考慮した設計をすることで DataSpider Servista はより一層、使いやすい製品となります。

次回、運用編!乞うご期待

*1:当社はSI事業を主としていますが、その中でも当事業部は DataSpider 製品を主軸としたEAI、EDIのSIを展開しています。

*2:続きはWebで

*3:機能そのものは既に担保されてるのも良いですよね

*4:今回の場合、同じプロジェクト内からしか呼び出せないという意味で利用しています。

*5:privateなどをアクセス修飾子と呼びます。

*6:コーディング規約、命名規約は非常に重要です!

プロダクト開発を支えるサステイニングチームのはなし

本記事は、「アプレッソ Advent Calendar 2015」8 日目の記事です。

qiita.com

プロダクトが成長していくためには組織の成長がかかせません。私自身、アプレッソでプロダクト開発に携わって 10 年以上になりますが、そこで得た経験や知識をもとに私になりに考えるプロダクトの成長を支える開発組織、特に私が所属しているサステイニングチームについて説明したいと思います。

開発、保守、テストの 3 つの業務

この記事の中では、プロダクト開発に関わる業務を「開発」、「保守」、「テスト」の 3 つに分けてます。それぞれの業務内容は以下のとおりとします。

  • 開発・・・バージョンアップに向けた「新機能の開発」や「バグフィックス」
  • 保守・・・カスタマーサポートの中で、「ソースコードを見ないと対応が困難なインシデントの調査」や「リリース済みプロダクトのバグフィックス(パッチ作成)」
  • テスト・・・コードレベルの「単体テスト」やプロダクトの品質を担保する「ソフトウェアテスト」

開発、保守、テストを一人で行う

プロダクトの機能ごとに開発、保守、テストを 1 人の開発者がすべて行うことは、プロダクトが成熟しきっていないスピード重視の立ち上げ時期にはよくある光景です。大抵の場合、チームは少人数で構成されており、開発、保守、テストの各業務を分担するよりも、1 人の開発者がすべてを行うほうが効率的です。また、前提として、少ないコミュニケーションコストでメンバー間の意思疎通ができることが挙げられるでしょう。

プロダクトが成長していくと 1 人で対応することが難しくなっていく

ただし、顧客が増加してプロダクトが成長していくと、1 人ですべてを行うことが難しくなってきます。プロダクトのリリーススケジュールは引かれている中で新機能の開発をしつつ、サポートからはフロントで捌くことが困難な問い合わせが緊急で入ってきて当日回答を求められる、さらに、プリセールスからは「この機能があると受注できる」という話が舞い込んで、予定していなかった機能追加に追われる、結果、プロダクトのリリーススケジュールに影響が出て延期せざるを得ない状況に……。これはもう精神と時の部屋に入らないと対応できないレベルです。

「タスクの優先度が正しく設定できていればこんなことにはならない」、「あれもこれも手を出し過ぎじゃない?」みたいな声が聞こえてきそうですが、1 人で開発、保守、テストのすべてを行うことは、プロダクトをある程度以上に成長させるうえでボトルネックになり得ると考えます。

「ソフトウェアテスト」を行うQAチームの立ち上げ

プロダクトが成熟してきて、1 人で開発、保守、テストを行うことが困難になってきた場合、テスト専任の「QAチーム」の立ち上げというのが考えられます。テスト専任というと単なるテスターのような印象を受けるかもしれませんが、そうではなくプロダクトが定めた品質を保証するチームになります。QA チームについての説明はここでは省略しますが、アプレッソの QA チームについては、アプレッソ東が昨年の Advent Calendar で執筆した「QAチームって何ぞや?」に書かれています。

QA チームの立ち上げによって、プロダクトの品質を担保する「ソフトウェアテスト」は QA チームが行うことになるので、開発者はコードレベルの「単体テスト」に注力できる効果が期待できます。しかしながら、開発と保守は依然として 1 人で行うことになるので、さらなる変革が必要です。

保守を行うサステイニングチームの立ち上げ

ようやくこの記事の本題に入ってきました。

ここでいう保守とは、カスタマーサポートのうち、特に「ソースコードを見ないと対応が困難なインシデントの対応」やリリース済みプロダクトの「バグフィックス(パッチ作成)」のことで、その業務を専任で行うのがサステイニングチームです。

アプレッソでもサステイニングチームが存在していて、このチームのメンバーはDataSpider Servistaをはじめ、PIMSYNC、DataSpider BPM、Thunderbusなど、アプレッソのすべてのプロダクトを横断的に対応しています。したがって、特定のプロダクト、機能に依存しない広い視野と知識、スキルを求められますが、ときには他部署や協力会社、顧客とコミュニケーションを取ることもあり、技術のみにフォーカスしているだけでは回らない業務も担当します。

サステイニングチーム立ち上げの背景

サステイニングチームを立ち上げることになった背景として、カスタマーサポートからの問い合わせの対応や他部署との調整などのコストが増加し、プロダクトのリリースに影響して延期したことが起因しています。

開発タスク以外の対応がスケジュールを遅延させていく

カスタマーサポートへ問い合わせが来るタイミングは当然予測できるものではなく、フロントで捌くことが困難な問い合わせが入ってきた場合、開発者は現時点の開発タスクを一旦止めて、カスタマーサポートから来た問い合わせを対応します。開発者から見て比較的軽いものであれば対応に費やした時間はその後の調整や頑張りでキャッチアップ可能ですが、重たいものは確実にスケジュールに影響していきます。また、軽いものでも数が多いと、都度開発タスクを中断しなければならず、対応後に開発タスクの作業を復帰しても同じパフォーマンスを出すまでに時間がかかってしまい、生産性の低下は避けられません。

さらに、プリセールスや他社との協業の話で技術的課題が発生し、営業側では対応が難しいケースがあります。この場合、技術的な観点でプロダクトに造詣が深い人間の支援が必要になるわけですが、サステイニングチーム立ち上げ前は、開発チームが対応していました。そうなると、開発タスクの中断を余儀なくされることになります。

開発チームの疲弊とリリーススケジュールの延期

開発タスクの中断が頻発すると、開発チームでは、本来やりたいこと、やるべきことに対して「割り込み」が発生したと捉えられ、負のオーラが蔓延していきます。また、担当する開発メンバーによっては、そういった外部からの情報は、開発には役に立たない情報、いわゆる「ノイズ」として受け止めて、精神的にも時間的にも余裕のない状況に追い込まれていきます。

これら複数の要因が積み重なり、過去にプロダクトのリリースを延期せざるを得ない状況になった経緯があります。

開発チームを守る「壁」

この状況を改善するべく、プロダクトのリリースに向けた開発タスクを担当する開発チームを守る「」の役割としてサステイニングチームが立ち上がりました。 現在は、カスタマーサポートのフロントで捌くことが困難な問い合わせの対応や、営業側との相談ごとの窓口や技術支援などもサステイニングチームのメンバーで対応しています。結果として、開発チームの気を逸らすような情報はサステイニングチームで遮断され、プロダクトのリリースに向けた開発タスクに注力することができるようになりました。

外部の情報を正しく聞いて正しく伝える

上記ではサステイニングチームの役割として開発チームを守る壁と記述しましたが、壁となって頑なに外部からの情報を遮断してしまっては、「開発チームに役立つ情報が伝わってない」、「伝わったけど誤認識されてしまう」というケースが考えられます。外部からの情報としては、社内外でさまざまなものがありますが、特にプロダクトに対する顧客の声はこのようなケースに陥らないように注意しなければなりません。

顧客からのエンハンス要望の聞き方、伝え方

プロダクトに対する顧客の声としては、例えばエンハンス要望があります。カスタマーサポートでエンハンス要望を受けると、サステイニングチームで対応の可否を判断したうえで、可能な場合は開発チームで対応を検討してもらうように依頼します。その際、エンハンス要望を正しく聞けていない、または聞いたことを開発チームに正しく伝えられていないと、要望したものとは異なる機能がプロダクトに入る可能性があります。

このような不幸な出来事を防ぐためには、エンハンス要望を「正しく聞く」ことが重要です。正しく聞くというのは、文章としての正しさではなく、「なぜその機能を要望しているのか」という背景を汲み取る本質的な正しさになります。サステイニングチームは、顧客目線で要望の背景を聞いて対応を検討し、十分納得できるものであれば、開発チームにその情報を正しく伝えます。

また、ここでいう「正しく伝える」ということは、顧客からのエンハンス要望をそのまま伝えることではありません。サステイニングチームで検討した結果、要望された機能がなぜプロダクトとして必要なのか、開発チームに理解してもらえるような用語に「翻訳」することも重要です。

この一連のコミュニケーションにおいては、「正しく聞く」と「正しく伝える」が達成できれば、手段は問いません。メールやインシデントの文字だけでは理解が難しいと感じれば、顧客を担当している社内の営業に聞いてみることや、ときには顧客から直接ヒアリングしてみることもアリだと思います。また、開発チームに正しく伝えるにも、バグトラッキングシステムに書いたからそれで終わりではなく、サステイニングチームからコードレベルで修正案を提示することも有効な手段だと思います。

最後に

サステイニングチームは開発組織の中では縁の下の力持ち的な存在で、プロダクトを成長させていくためには重要なロールだと考えます。しかしながら、サステイニングチームのタスクは、他部署との調整やカスタマーサポートから入る突発的事態の対応など、開発チームの多くのメンバーがやりたがらない、または苦手なタスクがほとんどです。

そのような業務を行うサステイニングチームに対して、開発チームから見た場合、外部から自分達を守ってくれる壁として、また、ときには開発に役立つ情報を効率良く流してくれる頼もしい存在として映ることもあるでしょう。ただし、ここで注意したいのは「サステイニングチームを過度に賞賛しないこと」です。サステイニングチームは、あくまでも後方支援の立場で開発チームを支える裏方であり、プロダクトを前進させる花形は開発チームだと考えます。この陰と陽の 2 つのチームが同じ目的に向かって自分達の役割を全うすることができれば、より良い方向にプロダクトを成長させていけるのではないかと思います。