シスアーキ in はてな

シスアーキ(自称)の技術ブログ

生まれ変わったJava !? 『Java SE 8 実践プログラミング』を読みました!!

みなさん!Javaで開発してますか〜!! 

2014年3月に正式リリースされたJava 8 ではラムダやストリーム、平行処理の機能強化に加えて、JavaFXやNashorn JavaScriptエンジンなど、様々な興味深い機能が追加されました。昔からJavaに携わってきた人間としては、本当に幅広く実用的な言語になったな~と思います。僕の書斎のJava関連本も大分増えました!

f:id:kozake:20141206143512p:plain

今後はJava 8 を用いた開発プロジェクトも増えてくるでしょう*1。そこで、Java 8 関連の技術を習得すべく、『Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング』を読みました!

Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング

Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング

 

本書の特徴としては、まえがきに書かれているとおり、既にJavaを習得している技術者が手短にJava 8 の機能を網羅的かつ簡潔に学習することを主眼としています。

この本では、すでにJavaをよく知っているプログラマーに対して、Java 8の多くの新機能を簡潔に説明します。(p.xi)

この本は「短気な(impatient)」スタイルで書かれています。...手短に要点を説明したかったのです。(p.xi)

必要なときにいつでもすばやく参照できるように、小さな単位で技術情報を解説しました。(p.xi)

その為、

  • 業務でJava 8 を使うことになったから、Java 8 の新機能を抑えたい
  • 今後の為に、とりあえず一通りJava 8 の機能に触れてみたい

といった方に最適な書籍だと思います。

また、コードサンプルも豊富に用意されており、各章の章末には豊富な練習問題も用意されていますので、

  • 開発時にリファレンスとして参照する
  • 読書会・勉強会などで活用する

などの使用方法もいいかと思います。

 

第1章ではラムダ式、第2章ではストリームAPI、第3章ではラムダ式を使ったプログラミング、そして第6章ではラムダ式と関連の深い並行処理の機能強化について記載されています。 まず、ラムダ式周りの機能を習得したい方は、第1〜3章と、第6章を読めばいいでしょう。

第5章では日付と時刻の新たなAPI、第8章ではその他のJava 8 機能について記載されています。Java 8 を用いた開発を行う場合は、こちらも読んでおいたほうがいいと思います。

第4章にはSwingに変わる新しいGUIとしてJavaFX、第7章はRhinoに代わる新しいJavaScriptエンジンのNashornについて記載されています。この章は興味に応じて読めばいいかと思います。

また、Java 7 で追加された機能の復習が、第9章に記載されています。Java 7 で機能拡張された内容を記載している書籍は少ないので嬉しいですね。

以下、 各章の内容を僕の感想交えて紹介します。

 

第1章 ラムダ式とは

第1章では、ラムダ式とインタフェースのデフォルト実装について記載されています。ラムダ式は、関数型インタフェース*2の無名実装の簡易構文(シンタックスシュガー)と考えると分かりやすいですが、実際のそれとは微妙に異なります。例えば、

ラムダ式の本体は、ネストしたブロックと同じスコープを持ちます。(p.17)

その為、ラムダ式とインタフェースの無名実装ではthisの扱いが異なります。また、Java 8 ではインタフェースにデフォルト実装を持つことが出来ます*3*4。これにより、

デフォルトメソッドは、CollectionとAbstractCollecction、あるいは、WindowsListenerとWindowsAdapterといった、インタフェースとそのインタフェースのほとんどすべてのメソッドを実装している抽象クラスを提供するという古典的なパターンに終止符を打つことになります。(p.19)

とあるように、既存の(慣れ親しんだ)API設計手法が変わります。古いJavaしか知らない方については、まずは第1章に目を通すだけでも、Javaに対する認識が大分変わってくるのではないかと思います。

 

第2章 ストリームAPIの使い方

第2章では、ストリームAPIの使い方が説明されています。

ストリームは、Java 8で導入された重要な抽象化概念です。(p.27)

とあるとおり、Java 8 を使いこなすには、ストリームの考え方をしっかり理解することが重要です。ストリームついては、p.29に記載されている、

  1. ストリームの作成
  2. 中間操作の指定
  3. 終端操作の適用

の3段階の操作でパイプラインを設定するという説明が分かり易かったです。

ストリームは最近の流行である、関数型プログラミングの概念を取り入れられて設計されています。本書では、

ストリーム以外のクラスにもflatMapメソッドがあるのを発見するかもしれません。それは、コンピュータサイエンスにおける一般的な概念です。...flatMapを使用して、最初にfを適用し、それからgを適用します。これは、モナド(monads)理論の重要な考えです。しかし、心配する必要はありません。モナドについて何も知らなくてもflatMapは使えますから。(p.33)

 とあるように、関数型プログラミングに対して深くは言及していません。

また、Optional型についてもこの章に記載されています。Optional型は値をnull安全に扱う為の重要なプログラミング技法です*5。今後のJavaフレームワークやライブラリでは、値がない可能性があるものは、nullではなくOptional型として取り扱われていくことになるでしょう。また、APIデザインを自分で設計する際には、そのように設計することが重要となります。

そもそもなぜOptional型がストリームAPIの章に記載されているかというと、Optiona型はストリームとして捉えることが出来るからです。

オプション値を大きさ0か1のストリームだと単純に想像してください。その結果は、大きさが0か1であり、1の場合に関数が適用されています。(p.38)

第2章を理解するだけで、Java 8 のストリームを十分使えるレベルになると思います。ただ、僕個人としては、関数型プログラミングは別途違う書籍で勉強したほうがいいと思います。というのも、最近の言語は関数型プログラミングのエッセンスを取り入れていますし、それを勉強することでストリームの理解がより深まると思うからです。

 

 第3章 ラムダ式を使ったプログラミング

 第3章ではラムダ式と関数型インタフェースを活用したプログラミング手法について記載されています。出てくる用語として、「遅延実行」「関数のパラメータ」「関数を返す」「合成」と、より関数型プログラミング色が強い章となっています。

 関数型プログラミング言語では、関数はファーストクラス・シティズン(first-class citizen)です。つまり、メソッドに数値を渡したり、数値を生成するメソッドを持つことができるように、引数や戻り値を関数にできるということです。これは、抽象的に聞こえますが、実際には非常に役立ちます。ある意味、Java関数型プログラミング言語ではありません。なぜなら、関数型インタフェースを使用するからです。しかし、原則は同じです。(p.65)

ラムダ式を使ったプログラミングでは、差分プログラミングが主流となると思います。つまり従来の手続き型言語とは異なり、制御の反転(Inversion of Control)の中で、「どのように処理するか」ではなく「何がしたいか」の差分をラムダ式で記述する機会が多くなるでしょう。

関数型インタフェースとして操作を表現する場合には、呼び出し側は、処理の詳細を制御することをあきらめます。(p.70)  

また、本章では、ラムダ式を使った一通りのプログラミング手法に加え、

 について記載されています。

一般に、ラムダ式は、ジェネリック型と相性がよいです。(p.74)

 とあるように、ラムダ式を活用するとジェネリック型を意識することが多いです。特に関数は、入力と出力を扱うという特性上、型変位(引数型には反変、戻り値には共変)を意識する必要があります。ジェネリック型について知識が曖昧な方は、この機会に復習しておいたほうがいいでしょう*6

 

第4章 JavaFXによるGUIプログラミング

本章ではJavaFXによるGUIプログラミングを一通り説明しています。

JavaFXだけでおそらく1冊の本が出来てしまうので、本章で全てを学ぶのは難しいと思います。ただ、触りとしては十分な内容でしょう。特にバインディングはMVVMを用いた設計では重要な技術となりますので、知らない方はバインディングの楽しさに触れてみるのがいいかと思います。

また、JavaFXに関しては、開発ツールのScene Builderがとても優れているので、一度ダウンロードして試してみるといいかと思います*7

 

第5章 日付と時刻の新たなAPI

時刻は絶対基準のある値(ある特定の時間からどれくらい経過したか)でありながら、歴史、宗教、機械の制限、地球の揺れによる誤差やロケーションの違いなどから、正しく扱うのがとても難しいデータとなっています。

Java ではこれまで、Date、Calendarクラスで時刻を現していましたが、閏年サマータイムなどの問題を取り扱うことが出来ませんでした。そこで、Java 8では新たなAPIが用意されました。この章では、そのAPIの詳しい説明がされています。

  • ある時点を現すInstant
  • 二つの時間の差を現すDuration
  • タイムゾーン情報を持たないLocalDateTimeと持つZonedDateTime
  • SimpleDateFormatに代わる日付フォーマットクラスのDateTimeFormatter

などなど。

また、古いコードとの相互運用についても「5.7 古いコードとの相互運用」に記載されておりますので、リファレンスとして用いやすい章となってます。2000年問題に携わった人間としては、このようにAPIがあの時あればな〜と想いを馳せます。

 

第6章 並行処理の機能強化

Java 8 はラムダ式ばかり取り上げられることが多いように思いますが、そもそもラムダ式が導入された背景には、「マルチコアに対応して、効率よく平行プログラミングできるように」という目的があります*8。本章では、平行処理の機能強化について記載されています。

この章を読むには、スレッドや並行処理の基本が分かっていないと辛いでしょう。本章では、ラムダ式を用いたサーチ(search)や畳み込み(reduce)の話が出てきます。例えば、畳み込みでは順序に左右されない累積関数の重要性などが記載されています。

一般に、操作は、結合的(associative)であり、可換(commutative)です。すなわち、最終結果は、中間の値が組み合わされる順序に依存していないということです。(p.142) 

デフォルト値は、累積での中立要素*9でなければなりません。(p.149) 

つまり、累積関数funcは、

  • func( 中立要素, x ) の結果は、 x と等しい
  • func( x, 中立要素 ) の結果は、 x と等しい
  • func( func(x, y), z ) の結果は、 func( x, func(y, z) ) と等しい

ことを満たす必要があります*10。 

ストリームを並列化しても、それが正常な結果を返すかどうかはプログラマーの責任となります。僕は本章を読んだだけですが、どこかのタイミングで実際に大量データを用いた並行処理の実験をしてみたいと思いました。

また、完了可能フューチャーを用いた非同期操作やその合成方法についても記載されています。CPUを効率よく活用して、大量トランザクションを処理するには、フューチャーを用いたプログラミング技法もますます必要性を帯びていると思います。

 

第7章 Nashorn JavaScriptエンジンの活用

Java 8ではRhinoに代わりNashorn JavaScriptエンジンが提供されました。

知りませんでしたが、Java 8にはjjsと呼ばれるコマンドラインツールが含まれているらしいです。

$ jjs

jjs > 'Hello, World'

Hello, World 

Hello, World!'.length

13

 REPL環境として、便利ですね!JavaのREPLも早く提供して欲しいです。また、

jjs -scripting

として起動することで、バッククォート内にシェルコマンドを含めることでシェルコマンドを実行することが出来るらしいです。

`ls -la`

業務ではWindows Serverを扱うことが多く、Groovyでスクリプトを書く事が多かったのですが*11JavaScriptスクリプトを書く選択肢が出来たのは非常に嬉しいです。JavaScriptから、Javaオブジェクトを簡単に扱えるのもいいですね!

一通りのNashorn JavaScriptエンジンの使い方が記載されているので、フロントサイドでも活躍するJavaエンジニアには、本章はとても楽しい内容ではないかと思います。

 

 第8章 その他のJava 8 機能を理解する

本章では、微妙に嬉しいその他のJava 8 機能を紹介しています。純粋にString.join メソッドは嬉しいですね。その他にも微妙に役立つ変更が紹介されておりますので、一通り目を通すのがいいと思います。

 

第9章 Java 7 の機能を復習する

Java 7 は、Java 8 に比べるとかなり地味なバージョンアップですので、見落としがちな便利な機能がいくつかあります。本章では、そういった機能の為の復習が用意されており、Java 7 機能を理解したい場合は、本章だけを読むというのもありだと思います。

僕が一番嬉しい機能としては、Java 7 ではFileを簡単に扱う方法が提供されました!

JavaではGroovyのようなスクリプト言語と比べて、ファイルを扱うにはとても増長な記述が必要な言語でした。Java 7 では、以下のように簡潔に書く事が可能なようになります。

for (String s : Files.readAllLines(Paths.get("/tmp", "hello.txt"))) {
    System.out.println(s);
}

 まあ、Groovyならもっと直感的に書けますが、、

println(new File("/tmp/hello.txt").text)

書籍『APIデザインの極意』にもありましたが、簡単な事を簡単に扱えるAPIを提供することは重要です。そういう機能が提供されただけでも喜ばしいです*12

また、 try-with-resources 文などは地味に便利な機能なので、知らない方はしっかり押さえておくのがいいと思います。

 

まとめ

 Javaは、Java 8 で生まれ変わりました。ラムダ式を筆頭に、Coolな拡張がされています。ラムダ式ばかりが取りざたされている印象がありますが、細部にわたって良い改善がされています。

Java 8 のバージョンアップを通じて、Javaはこれからも変わっていく、変わりつづけていけるとのメッセージを受け取ったように感じました。古いJava で知識が止まっている方、いまだJava 1.4 で消耗している方は、一度この本の1章だけでも目を通して見ればいいのではないでしょうか!

*1:Java 7は2015年4月に公式アップデートが終了されますし。

*2:単一の抽象メソッドをもつインタフェース

*3:インタフェースにデフォルト実装をもたせた理由は、既存資産への後方互換性をサポートするためです。書籍『APIデザインの極意』の6.6に発展の視点から既存のインタフェースへのメソッド追加は困難である旨が記載されています。それに対する解決策として、Javaにデフォルト実装という機能が追加されました。

*4:p.21に記載されていますが、スーパークラスメソッドとインタフェースのデフォルメソッドが衝突した際、「クラスが優先」となります。これはJava 7 とのソース互換・機能互換維持のためです。ここからも、Java後方互換を如何に大事にしているのが分かりますね。

*5:NullPointerExceptionはJavaで一番有名な例外ですからね!

*6:僕も反変と共変の知識が怪しかったので、『Java 2 Standard Edition 5.0 Tiger―拡張された言語仕様について』で復習しました。

*7:僕はInteliJ IDEAとのScene Builderの組み合わせで使ってみましたが、とてもいい感じです。

*8:訳者まえがきの最後に「マルチコア時代へ向けた新たな道具を獲得することに、この翻訳本を役立てていただければ」という記載もありますしね。

*9:数値なら0、文字列なら空文字、リストから0サイズのリストなど。

*10:はい、モノイドですね。

*11:DOSバッチを書きたくないので。。

*12:個人的にはPathやFilesの追加は好きではありません。Fileに加えてPathという新たな概念が誕生し、操作がFilesに分かれているからです。後方互換の関係上、仕方ないことだとは思いますが。

『しょぼちむにおごって僕が金欠になるかどうか』をプログラミングしてみた!

<< 4日目  6日目>>

この記事は しょぼちむ Advent Calendar 2014 5 日目の記事です。


しょぼちむ Advent Calendar 2014 - Adventar

 昨日は なかけん さんの しょぼちむを使ったお手軽WebGL体験|猫まっしぐら でした!

 

しょぼちむとは確か2回ほど会ったことがあります!可憐でかわいい女の子でしたよ^^しょぼちむとは年末の忘年会でも会う予定だから、今から楽しみだ!

普段から「かわいい女の子には奢っちゃうぞ///」宣言しているから、この状況でおねだりされるとおじさん、金欠がデッドラインになっちゃうな~ww。

 

・・・

あいつ本物か?

というのも、実はネカマのおっさんで僕が会ったのはバイトの女子大生という噂も絶えません。ツイッターを見てても、可憐な女子の発言とはとうてい思えない!

お、おっさんには絶対に奢らないからな!!

やばい、結局金欠になるのか、ならんのか分からなくなってきた。

 

ということで、『しょぼちむにおごって僕が金欠になるかどうか』をプログラミングして求めたいと思います。

 

まずは可能性をあらわすクラスを用意します。世の中は選択肢で溢れています。 選択肢の型はジェネリック型にして、様々な選択型を扱えるようにします。また、選択には確率がありますので、確率を小数点*1で現します。

しょぼちむ Advent Calendar 2014 のソース(可能性)

 

 次にしょぼちむの正体とその可能性を考えます。

僕が会っていたしょぼちむはバイトの女子大生の可能性が高いです。ということは、今度の忘年会にもその子が来る可能性が高いでしょう。ってことで、確率を60%として0.6で現します。もしかすると忘年会ということで、ネカマのおっさんがくるかもしれません!ようおっさん!はたまた、実は本当は普通の二年目女子SEかもしれません。全く知らん人かも、、おまえ誰だ?

まじレッドキングだったらどうしよう。。

しょぼちむの正体の可能性をStreamで現すことにします。Streamとは遅延評価可能な値の集まり、つまりリストです。そしてリストとは非決定性を持った値の集合、つまり可能性ある値の集合なのです。

しょぼちむ Advent Calendar 2014 のソース(しょぼちむ)

 

次に支払いの可能性を考えます。支払いは「おごり」と「ごち」と「割り勘」が考えられます。バイトの子がきたらおじさん奢っちゃうかも///。おっさんがきたら、謝罪と賠償を求めます。レッドキングだったら、まじどうしよう。。

それぞれの確率にしょぼちむの正体の確率をかけることで、入力の確率に対しての割合を加味して返します。

しょぼちむ Advent Calendar 2014 のソース(支払い)

 

最後に、支払いの結果、おこづかいのダメージ具合を考えます。奢ったからといって、即金欠になるかどうかは分からないからな! (その逆もしかり)

しょぼちむ Advent Calendar 2014 のソース(おこづかい)

 

 可能性の条件は揃いました!

flatMapで処理を連結してcollectで確率を求めます。flatMapを用いることで、「ある値に対して考えうる可能性を返す関数」を連結出来るんです!*2

しょぼちむ Advent Calendar 2014 のソース(Main)

 

そして実行結果

{金欠だ~ヽ(;▽;)ノ=70.0, 金ならあるんだ!!(((o(*゚▽゚*)o)))=29.0}

 

 やばい、70%の確率で金欠やで~~。。

 

人生は選択の連続であり、選択の結果が人生です。若いというのは可能性の宝庫です。これから様々な選択をしていくことになると思います。慎重にかつアグレッシブな選択をしていき、自分が楽しいと思える人生を選択していってくださいね^^

 

若いっていいな~ *・゜゚・*:.。..。.:*・'(*゚▽゚*)'・*:.。. .。.:*・゜゚・*

 

ではこの辺で!バイナリ〜( ´ ▽ ` )ノ

 

明日は mike_neck さんの syobochim/gistにプルリクを送った結果wwwwwwwwwwwww です!

 

 

*1:金額の計算をBigDecimalで![http://togetter.com/li/738592]

*2:え、リストモナド?なにそれ、怖い、うけるww

関西Kotlin勉強会に参加したよ

関西Kotlin勉強会に参加してきました!!


関西Kotlin勉強会 on Zusaar

 

様子はここら辺をみれば分かります!


関西Kotlin勉強会やった #kotlin — 裏紙

 

関西Kotlin勉強会で発表してきたよ〜 - 算譜王におれはなる!!!!

 

KotlinでJAX-RS + おまけ

http://backpaper0.github.io/ghosts/kotlin-jaxrs.html#/

 うらがみさんの発表はKotlinでJAX-RSをやるってお話でした。

テーマを決めてその技術を検証するってのは、本当にその言語の「出来る/出来ない」がはっきりしてきていいな〜と思いました。あとうらがみさん、Kotlin詳しすぎで凄い!!

一日前にKotlin初めて触って、資料作る所だけ学んだ僕とは姿勢から違いました。。

見習いたいと思います!

JAX-RSの話が一通り終わると、Kotlinが出力するバイトコードの検証からモナドをKotlinで実装する話と、一気に参加者を置いてきぼりモードに。。うらがみさん、怖い。

別件ですが、JAX-RSのブログの更改してくれるみたいです。期待しています!!(俺得なので)

Nullなのはいけないと思います!

Nullなのはいけないと思います!

 

僕の発表です。この勉強会の前にScalaMatsuriでたろうさんと初めてお会いして、そこでLTやる宣言したので作りました。Kotlin知らないのにw

Kotlinに関しては、Nullを安全に扱える仕組みがある言語ってのは知っていて、そこが言語機能としてすごく好きだったので、そこに絞って資料作りました。

ただ、もう少しきちんと整理してお話出来るようになりたいですね。

勉強がNullなのはいけないと思います!

たろうさんの発表

たろうさんの発表。今までの資料からKotlinの面白い所の話をたくさんしてくれました!

僕は既存オブジェクトを拡張できる拡張メソッドが好きでしたね^^

また、AndroidをKotlinで実装するライブコーディングも見させて貰えましたし、大満足です。Kotlinはモダンな言語機能を備えてて、とてもいい言語だと思いました。

あと、自分のコードみて悩んでいるたろうさん、かわいかったです、本当。

懇親会

神戸で飲んで、大阪で飲んでとかなりの時間飲んでましたww

本当に楽しい時間でした!ありがとうございました!!

 

Scala Matsuri 2014に参加しました!

Scala Matsuri 2014に参加しました!

Enjoy.scala ! 日本最大級の Scala のカンファレンス - ScalaMatsuri

 

ちょっと忙しくてブログ書くのが遅れました。楽しかったです^^

今回の参加は勉強目的ではなく、Scala界隈のトップレベルの人達が集まるイベントに参加したかった、その空気を感じたかったという完全に個人的な趣向です。去年、参加出来なかったのが悔やまれたので、今年は参加出来て本当によかったです。

 Scala Matsuriの内容はニコ生で中継されていましたし、資料も公開されています。ScalaMatsuri で検索すれば、色々な記事が出てくると思うので、僕は感想だけ。この記事読んでも得るものありませんよ!!

1日目

S-1 、S-2、B-1、B-2、A-3、B-4、B-5、B-6、B-7、B-8あたりに顔を出しました。

個人的には、B-1のGitBucketとA-3のPlay vs Node.js の話が一番印象に残っています。

普段、ツイッターで絡んでいる東京勢の方とお会い出来て嬉しかったです。

GitBucketはちょっと使いたいな〜と思っていたので、ローカル環境で立ち上げてちょこちょこ触っているから余計に印象に残ったのでしょうね。また、竹添さんの話し方がとても面白かったのと、GitBucketで使っている技術とかが興味深くてよかったです。

Play vs Node.jsについては、LinkedInの中の人が色々なフレームワークを検討しているって話が面白かったです。その中でもPlayはいいフレームワークってことなのでしょう。

懇親会ではOdersky先生にサイン貰えて、写真までご一緒させて頂きました!!

とても嬉しいです。

 また、梅澤さんにPlayステッカー貰えたのが嬉しかったです!

ScalaMatsuriでは色んなステッカー貰えましたが、当分はこのステッカーのみでいこうかと思います^^

2日目

アンカンファレンスではぶらぶらしていました。

 

Skinny Frameworkのハンズオンでは、そもそも「skinny new」 が失敗して動かないw

結局は、nodeのバージョン0.11が入っていたことが悪さをしていたみたい。0.10にしたら動きました。う〜ん、なんでこんなん入ってたんだろう。

あとは、Playの翻訳作業を眺めたり、GitBucket 会議にでたり。

まとめ

ま〜、ひどい内容のブログですが、本当に今回はお祭り気分の参加でした。勉強に燃えてって訳でもなく、そもそもScala力もそんなにありませんからね。本当に勉強したいなら、家でコップ本と逆引きを読んでいたでしょうし。

雰囲気を感じたかったのですが、色々と言語化できない刺激を受けました。

とりあえず来年があるなら、もっと有意義な参加になるようScalaの勉強と英語頑張ろうと思いましたw

今回のイベントは値段を考えても信じられないくらい豪勢なイベントでした!

スタッフの皆さんは本当に大変だったと思います!

ありがとうございました!!

 

関西WildFly 8(旧JBoss AS)勉強会に参加してきました。

関西WildFly 8(旧JBoss AS)勉強会に参加してきました。

nekop さんの発表

詳細はこちら

関西WildFly 8(旧JBoss AS)勉強会でしゃべってきた - nekop's blog

 

nekopさんとは初めてお会いしたが、噂通りの背の高いイケメンな方。しゃべりも上手で天は二物を与えてずるいのである。ちょっと仕事の関係でOSSまわりのWeb Application Serverを選定中だったのだが、スライドの中でJBossの市場シェアの話などが出てきてとても参考になった。Tomcat、Jetty、WildFlyGlassFishあたりが選定対象にあがると思うが、最近のJava界隈のOSS事情を考えると、ある程度企業サポートのあるOSS製品が今後も生き残ると考えている。組織として選択結果は技術投資になるので、投資が無駄にならない製品を選びたい。ちょっとGlassFishの立ち位置がいまいちなので、そうなるとWildFlyかな〜と考えていた。当日にWildFlyを使ったデモも拝見させて頂いたが、未だ重量級なイメージのあるJavaEEサーバーとは思えないほど軽くて良さげ。また、Web Application Serverはクラスローダーまわりで毎回ハマるのだが、WildFlyではモジュールクラスローディングを採用しているので心配ないとのこと。ちょっとモジュールクラスローディングについては推移的依存関係のバージョン違いのバッティングの解決方法など、そこら辺が詳しく分からなかったが、面白そうである。文献をあさって調べていきたい。 

 backpaper0 さんの発表

詳細はこちら

関西WildFly勉強会をやった #wildflykansai — 裏紙

 

Arquilian を使ったテストの話。僕も仕事まわりでJAX-RSを検討しているので参考になった。テストに関してはどうしても後回しになってしまうが、保守・運用フェーズになるとテストがないと困ることが非常に多い。今回の開発ではそこらへんの反省を踏まえて、テスト設計もしっかりしていきたいと思う。Arquilian は使えるかもしれない。

 

おだ さんの発表

詳細はこちら

関西WildFly 8(旧JBoss AS)勉強会 でお話しさせてもらいました - お だ のスペース

 

GlassFishからWildFly8に乗り換えたお話。大変参考になる。また、実際に使ってみてほとんど問題がないというのも心強い話である。ところで、帰りに@haljik さんとも話したのだが、おださんはどういうシステムを開発しているのだろうか?WASを変更したり、バージョンUPを気軽にするとか、なかなかSI案件では難しいのだが。。謎である。

その後

勉強会に参加出来て本当によかった。みなさん、ありがとうございます!当日は家庭の事情で懇親会に参加出来なかったのが本当に残念だった。

WildFlyについては、その後も色々といじっている。WebLogicで動いている社内プロダクトをWildFlyで動かしてみたり、Jenkinsのせてみたり。特に問題は発生していない。GradleのCargo Pluginを使ってビルド&起動してうま〜ってのも出来たいので、どっかで公開したい。本当、今のところ全く問題なく使えているので、このまま問題なければWildFlyで行きたいと思う。

 

進め、現場のチーム開発 〜チーム開発実践入門〜 (DevLOVE関西Ver) に参加してきました

進め、現場のチーム開発 〜チーム開発実践入門〜 (DevLOVE関西Ver) - DevLOVE関西 | Doorkeeper

に参加してきました。

 

当日はKYな台風到来で、予定していたスケジュールを短縮しての開催となりましたが、色々と気づきや学びのある勉強会でした。参加出来てとてもよかったと思います。 

「チーム開発をスムーズにするために何ができるか、してきたか」

チーム開発実践入門の著者である池田尚史(@ikeike443)さんの発表でした。池田さんは勉強会に参加することはあまりないそうですが(懇親会の席で伺いました。ちょっと意外)、わざわざ遠方からお越し下さいました。僕は縁あって、以前にもPlay Framework勉強会*1*2で一度お会いしたことがあり、久しぶりの再会でした。あの時はPlayのすごい人のイメージだったのですが、今ではチーム開発実践の大先生です。*3

 

発表内容はチーム開発でよくある課題とそれにどう対処するかという話から始まり、チーム開発実践入門2章のケーススタディーのような、実経験に基づいたチーム改善の事例紹介でした。とても実践に富んだ内容でした。

 

発表内容の一部を紹介すると、

チーム開発にベストプラクティスはない。ケースバイケース。その時々の状況にあわせることが重要。  

チーム開発の課題としては、

  •  プロジェクトの目標があいまい
  • プロジェクトの成功や価値が不明確
  • リスク管理が出来ていない
  • チームがうまく機能していない(パフォーマンスが発揮されていない)

 という状況が多く、これに対処していく。

言い換えると、

  •   ゴールはどこか?
  • 決めるのは誰か?
  • 利益は出るのか?
  • リスクは見えているのか?
  • チーム開発はうまくいっているのか?

  といったことを念頭におき、

  • 方法論はどんなものを使うか?
  • コミュニケーションプランをどうするか?
  • 成果をどう測るか?
  • チームビルディングはどうするか?
  • 開発ツールはどう使うか? 

をチーム開発を始めるにあたって考えるとのこと。 特に「チームビルディングはどうするか?」で話されていた、

「キャラも大事。全員モヒカンばかりではチームがうまく回らない。プロジェクトのマネージャーも必要だし、やさしい人も厳しい人も必要。また人どおしの相性も重要」 

 という話は僕も同感です。技術ばかり優秀なメンバを集めてもチーム開発はうまく行きません。様々な能力を持つメンバーが自分の得意を活かして、一人では成し遂げれないことをするのがチームであり、組織に所属する利点だと思います。

 

また、「ツールを組み合わせればチーム開発の課題が解決するのか?実際上手くいくのは、実践し続けている人のみ」という話がありました。その後の事例紹介の中でも、ツールは導入されていたが上手く使いこなせていないという話があり、あくまでツールは人をサポートするものであり、大事なのは個々人のスキルとコミュニケーションなんだと実感しました。

 

事例紹介ではチーム開発実践入門には述べられていない、「某ソシャゲー会社」の事例紹介があって面白かったですww。どこまで話していいのかが分からないのでここでは触れませんが、色々と考えさせられました。

 

まとめの中であった、

  •  管理しない。「管理する」の発想だと管理者のレベルを超えたものは産まれない。シナジーを重視する。
  • 「やれ」と言われたことをやるよりも、自ら「やろう」と考えたことのほうがパフォーマンスが高い。

 という言葉は、心に響きました。

 

最後に、チーム改善をダイエットに例えて、

  •  ダイエットが続かない理由はダイエットを始めるから!
  • 「課題があるから解決しよう」ではなく「課題がなくなるような習慣をつくろう」というアプローチが成功の鍵なのでは?

 という問いかけは面白かったです。チーム改善は良い習慣が大事で、それを続けるのが難しい(ダイエットと同じですね!)ということがすんなりと理解できました。上手いメタファですね! 

チーム開発よろず相談部屋

その後、チーム開発よろず相談部屋にて、「情報共有」について話し合いました。話し合いで得た内容としては、

  • 情報は蓄積より検索が重要でそれをうまくやるのが難しい
  • タバコ部屋のような気軽な情報交換できる場を用意する
  • 不特定多数への情報発信ができる場を用意する
  • 定期的にミーティングを開く

という話を得ました。また、情報共有に使うツールとしては、JIRAやBacklog、GithubIRCというキーワードが挙っていました。

顧客との情報共有に関しては、顧客側から情報共有してほしいという要望があり、Backlogの導入がすんなり実現したという話も聞けました。社内からこのような働きかけをするのは難しいですが、外部圧力なら簡単に話が進むな〜と関心しました。

 

また、席を移動して「人材育成」について周りに伺いましたが、どこの現場も育成に関しては苦労しているみたいでした。

というキーワードが挙げられていましたが、それぞれの育成効果は異なるので、ここら辺を組み合わせることが重要だと感じました。あと、経理やサポート、営業の人たちに初歩的な技術の勉強会を開くという話があり、それは面白い!と感じました。 

懇親会

勉強会の楽しみのひとつは懇親会ですw。もちろん酒が飲めるいうのがありますが、懇親会では勉強会で聞けない裏話が聞けたり、突っ込んだ技術討論が出来たりと、実は勉強会よりも得るものが多かったりします。ちょっと禁酒していたので、飲み過ぎてしまいましたww。皆さん、お付き合い頂きありがとうございました!!

おまけ

実は今回はLTをする予定だったのですが、台風でお流れになりましたw。ってことで、幻の資料をここに上げておきます^^

この資料の内容は、実践出来ていることもあれば、出来ていないことも多いです。今自分が問題だと思ってて、今後このような改善が現場で必要だという内容を書きました。

 

 
ここで得た内容を少しでも実践出来ればいいな〜と思います。
皆さんありがとうございました!!! 
チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

 

 

アジャイルAPI設計時代の到来!?APIデザインの極意を読みました。

プログラミング言語Java」「Effective Java」などの翻訳で有名な、柴田芳樹さんの新たな訳書である「APIデザインの極意」を読みました。

APIデザインの極意 Java/NetBeansアーキテクト探究ノート

APIデザインの極意 Java/NetBeansアーキテクト探究ノート

 

 「APIデザインの極意」は、NetBeansの生みの親で、初期のアーキテクトであるJaroslav Tulach(ヤロスラフ・ツゥラッハ)が著者で、NetBeansの開発で得た経験や教訓を纏めたノートが元になって書かれた書籍です。

従来のデザインパターンでは解決できない、後方互換性を維持しながらライブラリを発展させる設計手法について書かれています。

読んだ感想としては、GoFデザインパターン本のような体系だった内容というよりは、後方互換性を意識した設計手法が必要となる背景や理由、API設計者としての思想や態度に重点がおかれているように感じました。

本書の難易度はかなり高めだと思います。読み解くにはJavaをある程度習得している必要があります。「Effective Java」の内容を理解でき、デザインパターンの知識が身に付いた中級者が次に読む本だと思います。

なお、1章は哲学的な話が続くので、読みにくく感じるかも知れませんが、2章以降はシステムよりの話になるので技術者にとっては読みにくさはなくなるかと思います。

なぜ新たなデザイン本が必要なのか

序章でも述べられていますが、様々なデザイン本が出ている中、なぜ新たなデザイン本が必要なのでしょうか?
その答えは、本書の中にある、

今日のシステムは、巨大なビルディングブロックで構成されています。

 にあると思います。

僕は最近のシステム開発はまるで、「レゴブロックの組み立て、もしくはパズルのピース合わせのようだ」と感じています。様々なフレームワークやライブラリが提供する一部のAPIを組み合わせ、または拡張し、それらをブラックボックスとして使用します。
以前、ソートのアルゴリズム名を知らないプログラマに驚いたことがありますが、幾多のライブラリを導入し、ブラックボックスとして使用する僕とそのプログラマの違いは何だろうと疑問を感じたことがあります。そして、このような開発手法にも若干の違和感を抱いておりました。

本書ではこの状況を以下のように述べています。

21世紀の最初の10年間に構築される平均的なシステムは、その裏側にはなんの優雅さがない、あってもわずかしかない巨大なゴミの山のようなものです。そのようなシステムを構築する主な動機は、常に最小限の努力で成し遂げることです。そのために、エンジニアリングチームは、既存のソフトウェアフレームワークが必要以上であっても再利用しようとします。

 自分の知識や経験を踏まえて今後のシステム開発のあり方を考えた場合、このような開発手法は今後もますます拡がっていくと想定しています。

僕らは「何をしたいか」に注力し、大きなビルディングブロック上で自分がしたい”わずかな”拡張を実装することでそれを実現することになるでしょう。これを実現する為には、ユーザーがソートを実現したい時にそれを実現する方法を簡単に発見出来て、(具体的なアルゴリズムを知らなくても)それを呼び出すだけで最適なアルゴリズムによりソートした結果が得られるAPIが必要となります(本書では、そうした状況を選択的無知と呼称しています)。そして、APIを提供する設計者は、ユーザーの投資を無駄にせずに発展できるような設計、つまり後方互換を維持できるAPI設計が重要となります。

今までのデザイン本ではこのような手法については述べられていませんでした。
それが著者が本書を書いた動機であり、今後の開発者が本書から学ぶべき内容だと思います。

本書は400パージ程度の一般的なボリュームの技術本ですが、1ページあたりの内容が濃く、全てを端的に纏めることは不可能です(むしろ、著者が纏めた結果が本書のページ数です)。ですので、ここでは本書の概要と、中でも僕が感銘を受けたいくつかの内容について紹介したいと思います。

本書の概要

序章で述べられていますが、

が本書のテーマです。

  • 純粋に芸術的な設計よりは多少エンジニアリング的設計を好むすべてのAPIアーキテクト

が本書の想定読者層となっています。

第1部では、本書で述べる語彙が定義されています。
第2部では、具体的なAPIの設計手法
第3部では、API設計者としてうまくやっていくための助言が述べられています。

本書は精読が必要な部類の本であり、第1部から順に理解しながら読んでいくことをお勧めします。

本書の内容の抜粋と感想

1章、2章では、この本の重要なテーマである「選択的無知」について説明されています。

「無知」という言葉は一般的に侮蔑や軽蔑を含むイメージがありますが、本書ではこのような「攻撃的な意味」では使われていません。

車や携帯電話については仕組みを全く気にしないで使っています。

車を運転するために車の設計を理解したいと思わないでしょう。歯を綺麗にするために科学を理解する必要はありません。

何を深く知り、何を深く知る必要がないかを積極的に選択することを意味しています。

目標は、開発者がすべてを知らなくてもよいコーディング方法を見つけることです。すなわち、開発者が必要な知識を選択することです。私は、それを選択的無知と呼びます。

と本中で述べられているように、優れたAPIは無知であることを選択できます。

また、

無知モデルは、世界中のソフトウェアプロジェクトから集められた大きなビルディングブロッグを使用することに基づいています。

 と本中で述べられていますが、今日のシステムはより大きく、そしてより複雑になっています。昔のように、限定された単一環境上で画面入力をファイルに読み書きするだけのシステム開発はほとんどなく、複数の異なるベンダーが提供するOS、データベース、アプリケーションサーバーを利用し、様々なフレームワークやライブラリを組み合わせ、各所に分散されたシステムと協調して機能を実現するのが今日の一般的なシステムの姿です。そして、そのようなシステムでは、様々なAPIが他のAPIに依存し、ツタのように絡み合い、複数APIが異なるバージョンの同一APIを使用するというややこしい状況が普遍的に発生します。

このような状況下において、これらのAPIを組み合わせて効率よくシステムを設計・開発し、更にはエンハンスしながら健全に保つには、

  • 無知な状態を選択出来ること
  • 無知な状態で居られること

に気を使うことが、今後ますます重要になると思います。
それを実現するには、無知な状態でAPIを導入・使用でき、そしてAPI後方互換性を保ちながら健全に発展出来る設計手法を学ぶことが重要になってきます。

 3章、4章では、APIに焦点をあてた内容が説明されています。

について述べられています。

API」は、それ以上に広範囲な意味を持つ用語であり、他の多くの種類のインタフェースを含んでいます。

と本中にあるように、一般的なプログラマが想像する以上のものがAPIに含まれます。
それは一般的に想像する「メソッドとフィールドのシグネチャ」のみではなく、環境変数や標準出力やログ、振る舞いといった広範囲なものがAPIに含まれます。標準出力までもがAPIとして扱われることには驚きましたが、Unixのコマンドの使い方を考えると、すごく納得できました。*1
ある変更がユーザーを「びっくりさせる」のであれば、それはAPIとして含まれるということになります。

 APIの品質検査方法については、API設計者はもちろん、APIユーザの視点でも学んでおくことが重要だと思います。

ビルディングブロックの上で効率よくシステムを開発する為には、APIを設計する以上に、より良いAPIを探し出し、評価し、使用することが重要なスキルになります*2

API導入の善し悪しがシステム開発から保守・エンハンスまで、システムのライフサイクル全体の品質に影響します。APIを一度導入すると、そのAPIはアプリケーションの一部となり、今後の保守対象となります。導入するAPIの習得コスト、発展性を評価し、「投資の保全」が保てるよう、APIの品質検査方法を押さえておく必要があります。

余談 ①

以前、とある勉強会で「Jenkinsがすごい後方互換の維持を頑張っている。その為に、Javaバイトコードにパッチをあてるなど、黒魔法的なことをしている。」という話を聞きました。NetBeans開発でも同様の手法がとられていたことが本書でも記載されており、なんというかSunの後方互換に対する遺伝子のようなものを感じました。またJenkinsはユーザーの「投資」に真摯に向き合っているのだな〜と感動しました。 

API後方互換のレベルとしては、

  • ソース互換性
  • バイナリ互換性
  • 機能互換性

が挙げられています。
特に、機能互換性については考慮が漏れがちです。

のような理由で機能互換性を失う改修をすることがありますが、そのような改修はAPIの提供範囲によっては大きな影響をもたらします。

APIの提供範囲により、「どこまで」後方互換を保つかのレベルは変わると思いますが、後方互換のレベルを知り、それを保つ為の設計手法であったり、保ったまま発展させる方法を知識として押さえておくことは重要だと思います。

余談②

すこしうる覚えですが、以前、とあるORMapperの設計者がTwitterで「nullをパラメータに渡されたときに、"is null"を指定されたように設計変更しようかどうか」を悩んでいたのを見かけたことがあります。結局、その設計変更は他のフォロアーの「そのような変更はオプション指定で行えるようにしてほしい」という意見で見送られたみたいですが、大変興味深い内容でした。この会話内容には、本書の後方互換性の改修に対する最適解が含まれています。

 

第2部では、具体的なAPIの設計手法が述べられています。

  • 御託はいいから具体的な設計手法を知りたい
  • とりあえずコードを読みたい

といった開発者にとっては、第2部からが楽しい内容になると思います。

5章、6章では、API後方互換性を維持しながら健全に発展できる為の具体的な手法がJava言語に特化して述べられています。特に僕が感銘を受けた内容*3は、

  • メソッドを安全に追加できる型としてfinalクラスを使用する
  • 不変型を指定するためにJavaインタフェースを使用する

の2点です。

「不変型を指定するためにJavaインタフェースを使用する」については、Java8でインタフェースにデフォルトメソッドが導入される経緯となった理由を理解する上でも面白い内容だと思います(更に言えば、Java8以降についてはこのデザインパターンもデフォルトメソッドの出現で再考が必要となります)。

メソッドを安全に追加できる型としてfinalクラスを使用する」については、オブジェクト指向の代名詞と言われる継承に対する否定でもあり、とても面白い内容です。継承は「無知」をサポートするには難しい言語機能であり、ユーザの拡張方法が多岐に渡るので、後方互換の維持も難しくします。また、容易にソースをスパゲティ化することも出来ます。JavaではCompositeパターンが言語レベルでサポートされておらず、それを実現するには「もっさり」したコードを記述する必要がありますが、それでも本書を読んで、APIとして継承のサポートは出来るだけしないほうがいいように感じました。

8章ではJavaのWriterを例として、Decoratorパターンの発展問題と、それに対処する方法が述べられています。Decoratorパターンは僕が好むデザインパターンの1つであり、美しさを感じていたのですが、APIの発展性を考えた場合には大きな問題点があることに驚きました。APIは使用者向けと提供者(サービスプロバイダー)向けに分けて提供することの重要性、そして、コアな部分とサポートの部分に分けて提供することの重要性が理解出来ました。

9章では、テストについて述べられています。テストについては本書の中で心に響く文章があったので紹介しておきます。

テストは病みつきになるという私の主張にみなさんが同意しないかもしれない唯一の理由は、みなさんが試してみたことがないということです。

仕様書は時代遅れで、少なくともそのように思えます。...実際、テストは非公式な仕様書の一部となり、公式な仕様書がないことに対する埋め合わせとしての役割を果たします。

 また、テストをサポートするテストAPIを提供することの重要性や、テスト互換性キット(TCKを提供することの重要性が述べられています。

10章では他のAPIとの協調においての注意事項が述べられています。他のライブラリのAPIをほとんどそのままのシグネチャーで公開する、再エクスポート(re-export)を行った場合の発展性への影響などが述べられています。

11章では、API実行時の側面について、スレッドを意識した話が多く挙げられています。特にスレッド周りのテストではいつも苦労するのですが、本書ではログを使用したクールなテスト手法が紹介されており、とても興味深い内容でした。

12章では、宣言型プログラミングについて述べられています。特に、「オブジェクトを不変にする」の節で述べられている、

宣言型プログラミングの力は、高いレベルの概念を定義し、低いレベルで何が起きるかの詳細を正確に指定させるのではなく、高いレベルで指定させることができるのです。

関数型言語の時代が来たら、コーディングは突然、さらに美しくなり、はるかに優雅になり、常に安定していて真実は永久に変わらない幾何学のようでしょう。それまでは、私たちのAPIの一部を少なくとも不変にすることで、来るべきその時代を感じることができます。

については、選択的無知や後方互換性の観点からも、今後APIはより関数型プログラミングに向いて進化することを彷彿させました。

 

第3部では、API設計者としてうまくやっていくための助言が述べられています。
特に、13章の有害で極端な助言については、API設計者は一度目を通しておいたほうがいいでしょう。

僕の場合で言えば、「APIは、正しくなければならない」の節で述べられている、

Javaでディスクからファイルを読み込む方法が異常に「面倒」と思っているのが、私だけではないと確信しています。

の一文がAPIを正しく設計するだけでは良い設計といえないということを実感をもって理解できて面白かったです。

余談③

Java7ではFileを簡易的な扱うjava.nio.file.Filesが提供されておりますが、本来はFileの追加メソッドとして提供されたほうがより利便性が良かったと思います。
そうならなかったのは、広く使われているだろうFileクラスがfinalでなかったことが原因だったのではないかと推測しています。

個人的には、3部では17章のAPI設計フェストが一番面白かったです。
本書を読む方は17章で設計フェストに挑戦し、本書の内容が身に付いているかを実感して欲しいと思います!*4

まとめ

先に述べたとおり、本書は内容が濃く、全てを端的に纏めることは不可能なほど示唆に富んだ内容が豊富に述べられています。
ライブラリを開発して世に広めようとしている意識の高い技術者、ライブラリを導入して"上手く"システムを開発しようとする技術者のいずれにとっても本書の内容は有効なものになるでしょう。
世の中のライブラリが「選択的無知」を活用し、"下手な"APIがより多くの死者を生み出さない為にも、是非本書をより多くの優秀な技術者の方が読み解き、そしてその設計手法を広めていって欲しいと思います。

 

APIデザインの極意 Java/NetBeansアーキテクト探究ノート

APIデザインの極意 Java/NetBeansアーキテクト探究ノート

 

 

プログラミング言語 Java 第4版

プログラミング言語 Java 第4版

 

 

EFFECTIVE JAVA 第2版 (The Java Series)

EFFECTIVE JAVA 第2版 (The Java Series)

 

 

*1:Unixではコマンドをパイプやリダイレクトで組み合わせて「やりたいこと」を実現しますが、標準出力の内容がコマンドのバージョンによって変わると、おそらく混乱を招き使い物にならないでしょう。

*2:そのような情報を求めて雑誌を購読したり、勉強会に参加したりもします。

*3:ほとんど感銘を受けているのですが、全て述べるとキリがないので。

*4:ちなみに僕はボコボコにされましたがww