Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

【こっそり始める】Javaプログラマコーディングマイグレーション

13,563 views

Published on

JJUG CCC Fall 2015 #jjug_ccc #ccc_ab6の資料です。
(カットしたスライド含めた完全版)
Java SE 8に関してEOLが延長されたようなのでその補足訂正も追加しました。

Published in: Engineering
  • Be the first to comment

【こっそり始める】Javaプログラマコーディングマイグレーション

  1. 1. JJUG CCC 2015 fall @yy_yank #ccc_ab6 【こっそり始める】 Javaプログラマコーディング マイグレーション
  2. 2. #ccc_ab6 #jjug_ccc でつぶやいてください ハッシュタグ
  3. 3. 自己紹介 ヤンク(@yy_yank)         こいつです         ・JJUG、JKUGに出没         ・vi好き         ・でもサクラエディタicon         ・ゆるふわSIer         ・JavaとKotlinが好き
  4. 4. よーし、 JJUG CfP応募やで www
  5. 5. 数日後・・・
  6. 6. あ、メールきたで
  7. 7. まぁ、 「残念ながら…」的 なやつやろ
  8. 8. ?????
  9. 9. それはさておき
  10. 10. 現場のコード どうですか?
  11. 11. 2015年の Javaですか?
  12. 12. 多くは Old Java もしくは カオスJava
  13. 13. マイグレーション チャーンス!! ゴゴゴゴゴゴゴゴゴゴ・・・・・・
  14. 14. しかし 人は争うもの なんで変えないと ダメなの??? …デスヨネー よくわからん エラい人
  15. 15. 平和にこっそりやりたい
  16. 16. JJUG CCC 2015 fall @yy_yank #ccc_ab6 【こっそり始める】 Javaプログラマコーディング マイグレーション
  17. 17. ・移動、移行という意味(Wikipediaより) 今回は2つのマイグレーション(移動、移行) 1.新しいJavaのコーディングスタイルへの移行 2.プログラマ自身の知識、意識の移行 マイグレーションとは
  18. 18. ・移動、移行という意味(Wikipediaより) 今回は2つのマイグレーション(移動、移行) 1.新しいJavaのコーディングスタイルへの移行 2.プログラマ自身の知識、意識の移行 マイグレーションとは これを「こっそり」や る!!
  19. 19. ・Javaの初級~中級PGとかSEとか ・プロジェクトを変えていきたいなぁって人 ・Javaのスゴくない人 想定聴講者
  20. 20. ・Java自体のversion up (例えば、Java SE 6 -> Java SE 8など) は完了しているものとする ・またはプロジェクトでversion upの同意 がとれているものとする 前提
  21. 21. ・Java自体のversion up (例えば、Java SE 6 -> Java SE 8など) は完了しているものとする ・またはプロジェクトでversion upの同意 がとれているものとする そこが大変なんですけどね 前提
  22. 22. Java SE 6 likeなもの Java SE 7 likeなもの Java SE 8 likeなもの Javaマイグレーションマイルストーン
  23. 23. Java SE 6 likeなもの Java SE 7 likeなもの Java SE 8 likeなもの 今回ここまでです Javaマイグレーションマイルストーン
  24. 24. Java SE 8 likeなもの Java SE 9 likeなもの ここまで見据えていればすばらしい Java SE 9は来年らしいですね Javaマイグレーションマイルストーン
  25. 25. うちのプロジェクト J2SE 1.4(Java SE 4) なんだけど…
  26. 26. http://builder.japan.zdnet.com/sp_oracle/weblogic/35059108/より引用 対象Javaバージョン
  27. 27. http://builder.japan.zdnet.com/sp_oracle/weblogic/35059108/より引用 対象Javaバージョン 2017年9月?に延長されたらしい!! http://www.oracle. com/technetwork/jp/java/eol-135779.html
  28. 28. Java SE 8以外終わってますね 対象Javaバージョン 2017年9月?に延長されたらしい!! http://www.oracle. com/technetwork/jp/java/eol-135779.html
  29. 29. ・ソース互換、バイナリ互換性を保ちなが らバージョンアップしている ・非互換については公式ドキュメント確認 の上、回帰テストしつつバージョンあげて 行けばいいんだけどなぁ (個人の感想です) Javaは強い後方互換性を持っている
  30. 30. ・むしろサポート切れのもの使ってる方が 危ない気がするんだけどなぁ ・有償サポートとかどうしてますか?ええ、 なにそれ?ってなったら素直にバージョン アップした方が良い気が (個人の感想です) Javaは強い後方互換性を持っている
  31. 31. とはいっても、 色々事情があるのは 分かります
  32. 32. ・互換性故にオールドタイプなコーディング が許容される ・言語の進歩に技術者がついていってな いことがあったりする ・昔の書き方はもう出来ません! という言語ではない Javaの強い後方互換性ゆえに
  33. 33. ・互換性故にオールドタイプなコーディング が許容される ・言語の進歩に技術者がついていってな いことがあったりする ・昔の書き方はもう出来ません! という言語ではない Javaの強い後方互換性ゆえに これをなんとかしたい! という発表です
  34. 34. 1.現場コードを診る 2.チームメンバーのコードを診る 3.人を選ぶ 4.口コミ的に伝える 5.JUnitで示す 6.実践 アジェンダ
  35. 35. 1.現場コードを診る->事前準備 2.チームメンバーのコードを診る->事前準備 3.人を選ぶ->マイグレーション戦略 4.口コミ的に伝える->ハウツー的なもの 5.JUnitで示す->デモ 6.実践->1〜5をやってみる アジェンダ
  36. 36. 1.現場コードを診る 2.チームメンバーのコードを診る 3.人を選ぶ 4.口コミ的に伝える 5.JUnitで示す 6.実践 アジェンダ
  37. 37. 注目すべきところ ・依存ライブラリ ・アーキテクチャ ・コミットコメント ・ソース中のコメント 1.現場のコードを診る
  38. 38. 注目すべきところ ・依存ライブラリ ・アーキテクチャ ・コミットコメント ・ソース中のコメント 1.現場のコードを診る
  39. 39. 依存ライブラリを調べれば、大体やろうと している事が分かる Mavenならpom.xml Gradleならbuild.gradle をみて全体を俯瞰 IDE依存ならそれを見て… 1.現場のコードを診る 〜依存ライブラリ〜
  40. 40. pom.xmlに関してはdependencies見るだ けで大体OK 1.現場のコードを診る 〜依存ライブラリ〜
  41. 41. 1.現場のコードを診る 〜依存ライブラリ〜 <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
  42. 42. build.gradleに関してもdependencies見 るだけで大体OK 1.現場のコードを診る 〜依存ライブラリ〜
  43. 43. dependencies { compile 'org.apache.commons:commons-lang3: 3.3.2' testCompile('junit:junit:4.11') { transitive = false } 1.現場のコードを診る 〜依存ライブラリ〜
  44. 44. 依存ライブラリに存在するのに 直接利用する機会が無い =共通処理などで吸収している(内部で利 用している)と推測出来る 1.現場のコードを診る 〜依存ライブラリ〜
  45. 45. 注目すべきところ ・依存ライブラリ ・アーキテクチャ ・コミットコメント ・ソース中のコメント 1.現場のコードを診る
  46. 46. 1.現場のコードを診る 〜アーキテクチャ〜 全体を眺める上で ・ドキュメントの確認 ・エントリポイントの探索 ・ライフサイクル ・使用されているフレームワーク の確認は重要
  47. 47. 1.現場のコードを診る 〜アーキテクチャ〜 全体を眺める上で ・ドキュメントの確認 ・エントリポイントの探索 ・ライフサイクル ・使用されているフレームワーク の確認は重要 逆に言うと、 アーキテクトはこ こを用意してい てほしい
  48. 48. ・原始的にpublic static void mainを探す ・スタックトレースを出してみる 1.現場のコードを診る 〜アーキテクチャ〜 エントリポイントの探索
  49. 49. ・原始的にpublic static void mainを探す ・スタックトレースを出してみる new Exception().printstacktrace(); ※あくまでデバッグ用 1.現場のコードを診る 〜アーキテクチャ〜 エントリポイントの探索
  50. 50. 1.現場のコードを診る 〜アーキテクチャ〜 使用されているフレームワーク Java EEなら ・EJB、JSF、CDI その他 Spring系(Spring MVC、Spring Web etc..) など
  51. 51. 1.現場のコードを診る 〜アーキテクチャ〜 使用されているフレームワーク Java EEなら ・EJB、JSF、CDI その他 Spring系(Spring AOP、Spring Web etc..) など 知っていなくても、 アノテーションかクラス名で 検索すればなんとなくは分か るはず。 事前知識としてある程度知っ ておきたい
  52. 52. 1.現場のコードを診る 〜アーキテクチャ〜 大体どこのプロジェクトにもあるもの ・ベースとなるフレームワーク ・ベースをラッピングしたフレームワーク ・ORM(0/Rマッパー) ・推奨されるデザインパターン
  53. 53. ベースとなるフレームワーク public class ActionServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { process(request, response); } ・・・(略)・・・ }
  54. 54. ベースをラッピングしたフレームワーク public class SyanaiFrameworkServlet extends ActionServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { super.doGet(request, response); syanaiLogic.execute(); } ・・・(略)・・・
  55. 55. SyanaiFrameWorkServlet SyanaiFrameWorkAction SyanaiFrameWorkActionForm SyanaiFrameWorkRequestProcessor SyanaiFrameWorkBeanUtils ベースをラッピングしたフレームワーク
  56. 56. ベースをラッピングしたフレームワーク SyanaiFrameWorkServlet SyanaiFrameWorkAction SyanaiFrameWorkActionForm SyanaiFrameWorkRequestProcessor SyanaiFrameWorkBeanUtils ※まれによくある
  57. 57. ベースをラッピングしたフレームワーク SyanaiFrameWorkServlet SyanaiFrameWorkAction SyanaiFrameWorkActionForm SyanaiFrameWorkRequestProcessor SyanaiFrameWorkBeanUtils ※ここらへんのマイグレーションは ある程度妥協、出来てプルリク。
  58. 58. ベースをラッピングしたフレームワーク ・社内技術の蓄積とオレオレフレームワークは表裏一 体。良くもあり、悪くもある ・オレオレフレームワークは神聖不可侵みたいな扱い をされている事が多い ・アーキテクチャに従えという支配的な傾向が強かった りする
  59. 59. ベースをラッピングしたフレームワーク ・社内技術の蓄積とオレオレフレームワークは表裏一 体。良くもあり、悪くもある ・オレオレフレームワークは神聖不可侵みたいな扱い をされている事が多い ・アーキテクチャに従えという支配的な傾向が強かった りする だからこそ、ここを改善していくのは 難易度が高い
  60. 60. 注目すべきところ ・依存ライブラリ ・アーキテクチャ ・コミットコメント ・ソース中のコメント 1.現場のコードを診る
  61. 61. 1.現場のコードを診る〜コミットコメント〜 ・コメントというより、ヒストリー ・眺めて行くと思想や文化、修正・改修の 背景が見えてくる ・実装に関してのステークホルダーとかも 分かる
  62. 62. 注目すべきところ ・依存ライブラリ ・アーキテクチャ ・コミットコメント ・ソース中のコメント 1.現場のコードを診る
  63. 63. 1.現場のコードを診る 〜ソースコメント〜 ・TODOコメント ・FIXMEコメント ・その他ソース中のコメント このあたりを見ると潜在的に抱えている問 題が分かる
  64. 64. 1.現場のコードを診る 〜ソースコメント〜 // TODO 文言変更 String message = “不正なエラー”; // FIXME 不具合があるため一旦コメントアウト // HogeUtil.executeSomething();
  65. 65. 1.現場のコードを診る 〜ソースコメント〜 switch(hoge) { case A: a(); break; case B: b(); break; default: // ここに来るはずは無い break;
  66. 66. 1.現場のコードを診る 〜ソースコメント〜 ・社内フレームワークに相当する部分、 その他既存業務コードなどは真似される事が多い ・結果的に同じようなソースコメントが増える ・他人指向型のやり方を見抜くヒントになる
  67. 67. 1.現場のコードを診る 〜なぜ診るか〜 ・なぜ、わざわざ「現場のコードを診る」の? ・色んな人に質問して回答してもらったり、ソース コードの改善を提案すれば良いんじゃないです か? Question!!
  68. 68. Answer
  69. 69. なにかしら障壁があるから
  70. 70. なんかエラい上司 ・・・・ うーん・・
  71. 71. なんかエラい上司 それやって 工数削減出来る の?
  72. 72. なんかエラい上司 ソースを綺麗にす るよりも A画面の実装の方 が優先だよね
  73. 73. キェェェェェェェェェ ェwww
  74. 74. ・こういう展開はよくあるので、 水面下でこっそり始める ・「診る」は時間がかかるように思えるが 対人コストは低い ・交渉をする必要が無い方法である ・ただし、やはりスケジュール感は あるので、時間との戦い 1.現場のコードを診る 〜なぜ診るか〜
  75. 75. 1.現場コードを診る 2.チームメンバーのコードを診る 3.人を選ぶ 4.口コミ的に伝える 5.JUnitで示す 6.実践 アジェンダ
  76. 76. ・基本的なJavaコーディングセオリー ・どのver.のJavaコーディングか ・どういう性格か ・メソッドや変数命名のクセ ・DRY、SOLID 2.チームメンバーのコードを診る
  77. 77. ・基本的なJavaコーディングセオリー ・どのver.のJavaコーディングか ・どういう性格か ・メソッドや変数命名のクセ ・DRY、SOLID 2.チームメンバーのコードを診る
  78. 78. ・基本的なJavaコーディングセオリー ・どのver.のJavaコーディングか ・どういう性格か ・メソッドや変数命名のクセ ・DRY、SOLID 2.チームメンバーのコードを診る 勝手に作ったセオリー (出典なし)
  79. 79. ・変数とメソッドはキャメルケース ・クラスはパスカルケース ・for(int i = 0; i < hoge.length; i++) ・拡張for文 ・変数は呼び出す直前で定義 ・Java Beans 2.チームメンバーのコードを診る 〜Javaコーディングセオリー〜入門レベル(必須)
  80. 80. public class hogeHoge { String user_id; String UserId; public void GetHoge() public void get_hoge() } 2.チームメンバーのコードを診る 〜Javaコーディングセオリー〜
  81. 81. boolean deleteFlag = false; ・・・・長い処理・・・ for(...){ ・・・・長い処理・・・ if(...) { if(...) { else if(...){ } ・・・・長い処理・・・ deleteFlag = true; } } 2.チームメンバーのコードを診る 〜Javaコーディングセオリー〜
  82. 82. 2.チームメンバーのコードを診る 〜Javaコーディングセオリー〜 ・methodスコープの意識 ・文字連結にはStringBuilder ・大きい桁数のデータ、小数演算にはBigDecimal ・ジェネリクスの適切利用(型安全) ・hashCodeとequals かけだしレベル (意識しててほしいやつ)
  83. 83. ・たまに入門レベルを満たしてないプログ ラマがいる ・そういう場合はマイグレーション以前に Java教えるところから ※レベルの内容は勝手に 僕が思いつきで書いただけです 2.チームメンバーのコードを診る 〜Javaコーディングセオリー〜
  84. 84. ・基本的なJavaコーディングセオリー ・どのver.のJavaコーディングか ・どういう性格か ・メソッドや変数命名のクセ ・DRY、SOLID 2.チームメンバーのコードを診る
  85. 85. ・try、catch、finallyを見れば大体分かる ・例外処理は一番コーディングスキルが測 れると言っても過言ではない 主には後述するtry-with-resources マルチキャッチなど 2.チームメンバーのコードを診る 〜どのverのJavaコーディングか〜
  86. 86. ・Java SE 8知ってたらStream API使い たがると思うのでそこも見分けるのは簡単 2.チームメンバーのコードを診る 〜どのverのJavaコーディングか〜
  87. 87. Java SE 6の時代が 長過ぎた (2006〜2011年)
  88. 88. 2.チームメンバーのコードを診る ・基本的なJavaコーディングセオリー ・どのver.のJavaコーディングか ・どういう性格か ・メソッドや変数命名のクセ ・DRY、SOLID
  89. 89. ・やたらフラグ使いたがる人 →自分の世界にいる(唯我独尊) ・やたらJavaBeansのコンバートが多い人→ オレオレ実装が好き(やりたがり) ・コメントを多く残す人 →几帳面か保守的 2.チームメンバーのコードを診る 〜どういう性格か〜
  90. 90. ・1メソッドがやたら長い人 →設計書のその通りに作るタイプ アバウトな例ですがこんな感じ。 コードと普段の会話でなんとなく 見えてくるものが…? 2.チームメンバーのコードを診る 〜どういう性格か〜
  91. 91. ・コードは正直 ・直接的に伝え合う情報も重要だが 普段気づくにくいところに本質的な部分が ある気がする 2.チームメンバーのコードを診る 〜どういう性格か〜
  92. 92. ・コードは正直 ・直接的に伝え合う情報も重要だが 普段気づくにくいところに本質的な部分が ある気がする コード性格占い結構当たる 2.チームメンバーのコードを診る 〜どういう性格か〜
  93. 93. 2.チームメンバーのコードを診る ・基本的なJavaコーディングセオリー ・どのver.のJavaコーディングか ・どういう性格か ・メソッドや変数命名のクセ ・DRY、SOLID
  94. 94. 制約の無い部分(実装者に一任されてい る部分)の命名は個人のクセが出やす い。 その人の言語経験(Cから始めて今は Javaとか、VBから始めて今はJavaとか) が見えてくるはず…? 2.チームメンバーのコードを診る 〜メソッド名や変数命名のクセ〜
  95. 95. 2.チームメンバーのコードを診る ・基本的なJavaコーディングセオリー ・どのver.のJavaコーディングか ・どういう性格か ・メソッドや変数命名のクセ ・DRY、SOLID
  96. 96. ・DRY(Don’t Repeat Yourself) 呪文のように反芻するべきと思う言葉 ・繰り返しを無意識にやっている人は多い →マイグレーション以前で 改善しておきたい部分 2.チームメンバーのコードを診る 〜DRY, SOLID〜
  97. 97. ・SOLID State Dependency Principle Open-Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle 2.チームメンバーのコードを診る 〜DRY, SOLID〜
  98. 98. ・オブジェクト指向の設計原則 クラスの責任は1つだけ 拡張しやすく、修正で影響出ない 継承先でクラスの意味変わっちゃだめ 必要ないところまで意識させない 親も子も独立しているべき 2.チームメンバーのコードを診る 〜DRY, SOLID〜
  99. 99. ・SOLIDを意識した実装は理想的 ・アンチパターンを見抜く手だてになる(原 則に反するか、という指標値) ・原則は絶対厳守のものではないが 背景知識として持っていて損は無い 2.チームメンバーのコードを診る 〜DRY, SOLID〜
  100. 100. 1.現場コードを診る 2.チームメンバーのコードを診る 3.人を選ぶ 4.口コミ的に伝える 5.JUnitで示す 6.実践 アジェンダ
  101. 101. ・人選びは大事。変化を起こすとき ☆提案を受け入れてくれる人 ☆半信半疑だが着いてきてくれる人 ☆何が何でも反対する人があらわれる。 受け入れてくれる人 + 半信半疑の人に 協力してもらえるように努力する (ピープルウェアの受け売り) 3.人を選ぶ
  102. 102. ・現場のコード、メンバーのコードを踏まえ て マイグレーションを推進していく 3.人を選ぶ
  103. 103. ・指摘を受け入れる人か ・こだわりが強いか 3.人を選ぶ
  104. 104. ・指摘を受け入れる人か ->丁寧にアドバイスしていく ・こだわりが強いか ->こだわりを受け入れつつ、アイデアを提 示する、提案する。 3.人を選ぶ
  105. 105. ・処理スピードを重視するか 3.人を選ぶ
  106. 106. ・処理スピードを重視するか -> ベンチマークを示す。 「こちらの方が速いから」 みたいなやりとりするよりも 実際の数値見て会話する方が生産的 3.人を選ぶ
  107. 107. ・怠惰か 3.人を選ぶ
  108. 108. ・怠惰か ->「楽な方法があるよ」 「気持ちがスーっとするよ」などと 新しい技術を進めてみる 3.人を選ぶ
  109. 109. ・色んなタイプがいるが、自分にとって攻 略しやすい人を1人見つけてきっかけとす る ・どんなタイプに対しても 動機(モチベーション)を探して それに働きかける 3.人を選ぶ
  110. 110. 3.人を選ぶ プロジェクトとメンバーの利害を 上手く一致させる必要がある
  111. 111. ・色んなタイプの人がいる中で どう対話をするか考える ・重要なのは人間は Controllableではないということ 3.人を選ぶ
  112. 112. ・色んなタイプの人がいる中で どう対話をするか考える ・重要なのは人間は Controllableではないということ ・情報を自分で止めないこと 対話をやめないこと 3.人を選ぶ
  113. 113. 1.現場コードを診る 2.チームメンバーのコードを診る 3.人を選ぶ 4.口コミ的に伝える 5.JUnitで示す 6.実践 アジェンダ
  114. 114. ・例えばダイヤモンドオペレータを使え!と いうのではなく 「こんなんありますけど?」と伝えてみる 4.口コミ的に伝える
  115. 115. あ、ここのソースなんです けど
  116. 116. なんか、ダイヤモンドオペ レーターっていうのがある らしいですよ
  117. 117. えっ、何ですかそれ
  118. 118. 単純にジェネリクスが キュッとなってシンプルに なるんすよ
  119. 119. まぁ省略されるだけなんで どっちでも良いと言えば良 いんですけどねw
  120. 120. でも、シンプルな方が後々 楽ですよねー たぶん
  121. 121. そうっすねー 使ってみますよ
  122. 122. ・このぐらいのスタンス ・争わない。消耗して時間消費するのも精 神衛生と工数管理上良くない ・本質的に話し合わなければ いけない部分は議論する 4.口コミ的に伝える
  123. 123. ・かといって、実装者でバラバラにならない ように上手く誘導する必要があったり無 かったり ・チームとしての統一感は最低限必要 4.口コミ的に伝える
  124. 124. 1.現場コードを診る 2.チームメンバーのコードを診る 3.人を選ぶ 4.口コミ的に伝える 5.JUnitで示す 6.実践 アジェンダ
  125. 125. 伝える事 ・実装サンプル ・期待値(アサーション) ・実際にTestを走らせる ・オールグリーンを見せる 5.JUnitで示す
  126. 126. 口コミ戦法を踏まえて こんな感じで…
  127. 127. うーん、Listの絞り込みし たいんだけどfor文が複雑 になっちゃうなぁ
  128. 128. あー…。Stream APIって言 うの知ってますか?
  129. 129. ?? 聞いた事無いですねぇ。
  130. 130. なんかJavaのハチから 入ったらしいんですけど便 利っぽいですよー
  131. 131. 例えば、ここのロジックだっ たらこんな感じで…
  132. 132. @Test public void リストを偶数だけにする() { // 1〜100のデータ // setup(1〜100を持つリストを作る) List<Integer> result = create1To100(); 5.JUnitで示す
  133. 133. // exercise List<Integer> evenList = result.stream() .filter(n -> n % 2 == 0) // 偶数でフィルタ .collect(Collectors.toList()); // リスト化 5.JUnitで示す
  134. 134. // verify assertThat(evenList.size(), is(50)); assertThat(evenList.get(0), is(2)); assertThat(evenList.get(1), is(4)); assertThat(evenList.get(2), is(6)); assertThat(evenList.get(3), is(8)); assertThat(evenList.get(4), is(10)); 5.JUnitで示す
  135. 135. @Test public void リストを偶数だけにする() { List<Integer> result = create1To100(); // 1〜100のデータ List<Integer> evenList = result.stream() // .filter(n -> n % 2 == 0) // 偶数でフィルタ .collect(Collectors.toList()); // リスト化 assertThat(evenList.size(), is(50)); assertThat(evenList.get(0), is(2)); assertThat(evenList.get(1), is(4)); assertThat(evenList.get(2), is(6)); assertThat(evenList.get(3), is(8)); assertThat(evenList.get(4), is(10)); 5.JUnitで示す 実装サンプル
  136. 136. @Test public void リストを偶数だけにする() { List<Integer> result = create1To100(); // 1〜100のデータ List<Integer> evenList = result.stream() // .filter(n -> n % 2 == 0) // 偶数でフィルタ .collect(Collectors.toList()); // リスト化 assertThat(evenList.size(), is(50)); assertThat(evenList.get(0), is(2)); assertThat(evenList.get(1), is(4)); assertThat(evenList.get(2), is(6)); assertThat(evenList.get(3), is(8)); assertThat(evenList.get(4), is(10)); 5.JUnitで示す 期待値 (アサーション) ※分かりやすさ重視
  137. 137. @Test public void リストを偶数だけにする() { List<Integer> result = create1To100(); // 1〜100のデータ List<Integer> evenList = result.stream() // .filter(n -> n % 2 == 0) // 偶数でフィルタ .collect(Collectors.toList()); // リスト化 assertThat(evenList.size(), is(50)); assertThat(evenList.get(0), is(2)); assertThat(evenList.get(1), is(4)); assertThat(evenList.get(2), is(6)); assertThat(evenList.get(3), is(8)); assertThat(evenList.get(4), is(10)); 5.JUnitで示す このときに パフォーマンスも測定し て伝えると効果的
  138. 138. ッッッッターーーン! (Enterキー叩く音)
  139. 139. 4.JUnitで示す OK!!!!!
  140. 140. こんな感じでデモすれば こういう感じに
  141. 141. うまくいくはず!!
  142. 142. JUnit以外のオススメ ・JavaのREPL(jshell) https://jdk9.java.net/download/ 5.JUnitで示す
  143. 143. JUnit以外のオススメ ・JavaのREPL(jshell) https://jdk9.java.net/download/ デモやコミュニケーションは 瞬発力勝負。 軽い動作確認を円滑にしてくれる 5.JUnitで示す
  144. 144. 1.現場コードを診る 2.チームメンバーのコードを診る 3.人を選ぶ 4.口コミ的に伝える 5.JUnitで示す 6.実践 アジェンダ
  145. 145. ・1〜5を踏まえて実践していく マイグレーションの具体的内容は 次スライドから ※ズラーっとJavaコードを 羅列してます 6.実践
  146. 146. Thread VS Concurrency Utilities
  147. 147. Thread t = new Thread(new Runnable(){ public void run() { doSomething(); } }); t.start(); Thread VS Concurrency Utilities
  148. 148. ExecutorService service = Executors. newSingleThreadExecutor(); service.execute(new Runnable(){ public void run(){ doSomething(); } }); service.shutdown(); Thread VS Concurrency Utilities
  149. 149. ExecutorService service = Executors. newSingleThreadExecutor(); service.execute(() -> doSomething()); service.shutdown(); Java SE 8 ならこんな感じ Thread VS Concurrency Utilities
  150. 150. ・スレッド管理が簡単になった (※ここまでJava SE 6 で出来る) ・あと、色々もっと並列処理やろうとしたら色んなも のが選択肢にあがってくる…おそらく だけど、あえてバッサリカットします Thread VS Concurrency Utilities
  151. 151. ・業務での利用シーンは限られているし、 レイテンシを気にする人が自然に行き着くはず ・まずはThreadをnewしちゃうところから卒業を Thread VS Concurrency Utilities
  152. 152. 詳しくは ・Java並行処理プログラミング ―その「基盤」と「最新API」を究める ※ただし絶版 ・Java言語で学ぶデザインパターン入門 マルチスレッド編 Thread VS Concurrency Utilities
  153. 153. Thread VS Concurrency Utilities
  154. 154. ありがちなfinally句 VS try-with-resources
  155. 155. byte[] fileData = …. OutputStream os = null; try { os = new FileOutputStream(“hoge.txt”); os.write(fileData); } finally VS try-with-resources
  156. 156. catch(IOException e) { …. } finally { if(os != null) { try { os.close(); } catch(IOException ..) {...} ……. finally VS try-with-resources
  157. 157. finally VS try-with-resources byte[] fileData = …. OutputStream os = null; try { os = new FileOutputStream(new File(“hoge.txt”)); os.write(fileData); } catch(IOException e) { …. } finally { if(os != null) { try { os.close(); } catch(IOException ..) {...} ……. 長いわ!!!!
  158. 158. byte[] fileData = …. try(OutputStream os = Files.newOutputStream (Paths.get(“hoge.txt”))) { os.write(fileData); } catch(IOException e) { …. } finally VS try-with-resources
  159. 159. Old File Operation VS NIO2
  160. 160. ・実はさっきさりげなく使っていた Old File Operation VS NIO2
  161. 161. byte[] fileData = …. try(OutputStream os = Files.newOutputStream (Paths.get(“hoge.txt”))) { os.write(fileData); } catch(IOException e) { …. } Old File Operation VS NIO2
  162. 162. ・FilesとPaths使っておけばそれっぽくな る! ・今までFileクラスでファイルパス作った り、野暮ったかったのがシンプルに Old File Operation VS NIO2
  163. 163. ・ファイル操作とファイルパス操作が明確 に分離されるようになった ・ファイル操作が簡単になった copy、move、権限操作、zipなど Old File Operation VS NIO2
  164. 164. 古くさいGenerics VS Diamond Operator
  165. 165. List<String> stringList = new ArrayList<String>(); Old Generics VS Diamond
  166. 166. List<String> stringList = new ArrayList<>(); Old Generics VS Diamond
  167. 167. List<String> stringList = new ArrayList<>(); これは割とみんなすんなり受け入れてくれ る感じがしている Old Generics VS Diamond
  168. 168. 多すぎるcatch節 VS Multi Catch
  169. 169. too many catch VS multi catch try { …. } catch(IOException ioe) { throw HogeException(e); } catch(SQLException se) { throw HogeException(e); } catch(InterruptedException e) { throw HogeException(e);
  170. 170. too many catch VS multi catch try { …. } catch(IOException | SQLException | InterruptedException e) { throw HogeException(e); } これもすんなり受け入れてくれそう
  171. 171. リフレクション チェック例外地獄 VS ReflectiveOperation
  172. 172. Old Ex VS ReflectiveOperationEx try { Class clazz = Class.forName(“...”); clazz.newInstance(); } catch(ClassNotFoundException cex) { … } catch(InstatitationException iex) { … } catch(IllegalAccessException iaex) { … }
  173. 173. try { Class clazz = Class.forName(“...”); clazz.newInstance(); } catch(ReflectiveOperationException e) { …… } Old Ex VS ReflectiveOperationEx
  174. 174. 気ままなコレクション操作 VS Collections
  175. 175. Selfish Implement VS Collections return new ArrayList<>(); return new HashMap<>(); return new HashSet<>();
  176. 176. return Collections.emptyList(); return Collections.emptyMap(); return Collections.emptySet(); ※単に空のインスタンスを返したいときは 有効 J2SE 5.0 から使えます Selfish Implement VS Collections
  177. 177. List<String> list = new ArrayList<>(1); list.add(“hoge”); Set<String> set = new HashSet<>(1); set.add(“hoge”); Map<String, String> map = new HashMap<>(1); map.add(“hoge”, “hoge”); Selfish Implement VS Collections
  178. 178. Selfish Implement VS Collections Collections.singletonList(“hoge”); Collections.singleton(“hoge”); Collections.singletonMap(“hoge”, “hoge”); J2SE 1.3から使えます
  179. 179. Selfish Implement VS Collections 結論 CollectionsクラスはCollections.sortやるときだけ 利用するクラスではない
  180. 180. Selfish Implement VS Collections 結論 CollectionsクラスはCollections.sortやるときだけ 利用するクラスではない コレクションの操作を簡潔化し、オブジェクトの寿命 を明確にする 複雑な操作を簡易に行える
  181. 181. Selfish Implement VS Collections 結論 CollectionsクラスはCollections.sortやるときだけ 利用するクラスではない コレクションの操作を簡潔化し、オブジェクトの寿命 を明確にする 複雑な操作を簡易に行える ただし、全く同じ操作 (add、removeなど)が 出来るわけではない 用法用量を守って 正しくお使いください
  182. 182. オレオレUtil VS Objects
  183. 183. Selfish Implement VS Objects if(hoge == null) { throw new NullPointerException (“hoge is null”); }
  184. 184. Selfish Implement VS Objects Objects.requireNonNull(hoge, “hoge is null”);
  185. 185. Selfish Implement VS Objects if(hoge != null) { return hoge.toString(); } else { “”; }
  186. 186. Selfish Implement VS Objects Objects.toString(hoge, “”);
  187. 187. Selfish Implement VS Objects ・変なオレオレStringUtilとか作る前に Objectsを見てみよう ・しかしこの辺りはプロジェクト秘伝のUtil と対象領域が重なってしまう可能性が高く 難易度高い
  188. 188. ここまでは Java SE 7で 実現出来ます
  189. 189. ここから Java SE 8
  190. 190. 気ままなfor文実装 VS Stream API
  191. 191. for(Integer value : list) { if(value == ...) { continue; } if(value == ...) { continue; } return value; } return null; // guilty Selfish for-loop VS Stream
  192. 192. return list.stream() .filter(s -> isHoge(s)) .findFirst(); Selfish for-loop VS Stream
  193. 193. for(Fuga fuga : fugaList) { Hoge hoge = new Hoge(); hoge.setHoge(fuga.getFuga()); hogeList.add(hoge); } return hogeList; Selfish for-loop VS Stream
  194. 194. return fugaList.stream() .map(fuga -> convertToHoge(fuga)) .collect(Collectors.toList()); Selfish for-loop VS Stream
  195. 195. StringBuilder VS StringJoiner
  196. 196. StringBuilder sb = new StringBuilder(); sb.append(“[a”); sb.append(“,”); sb.append(“b”); sb.append(“,”); sb.append(“c]”); sb.toString(); // =>[a,b,c] StringBuilder VS StringJoiner
  197. 197. StringJoiner joiner = new StringJoiner(“,” “[”, “]”); joiner.add(“a”); joiner.add(“b”); joiner.add(“c”); joiner.toString(); // =>[a,b,c] StringBuilder VS StringJoiner
  198. 198. // String.joinも結構便利 String.join(“,”, “a”, “b”, “c”); //=> a, b, c StringBuilder VS StringJoiner
  199. 199. ・ただ、処理速度は StringBuilderの方が速いみたい きしださんのブログ http://d.hatena.ne. jp/nowokay/20140409 試しに動かしてみたがあまり当時と変わらず StringBuilder VS StringJoiner
  200. 200. IOException VS UncheckedIOException
  201. 201. IOE VS UncheckedIOE public hogehoge() throws IOException { InputStream is = …..; is.read(); そしてthrows….throws…..throws….
  202. 202. IOE VS UncheckedIOE try(InputStream is = …..){ is.read(); } catch(IOException e) { throw new UncheckedIOException(e); }
  203. 203. IOE VS UncheckedIOE try(InputStream is = …..){ is.read(); } catch(IOException e) { throw new UncheckedIOException(e); } ※エラーハンドリングは計画的に
  204. 204. 愚かなnull返し VS Optional
  205. 205. Stupid null return VS Optional public String findHoge() { for(Hoge hoge : hogeList ){ if(hoge.isFuga()) { return hoge.getAsString(); } } return null; }
  206. 206. Stupid null return VS Optional public Optional<String> findHoge() { for(Hoge hoge : hogeList ){ if(hoge.isFuga()) { return Optional.of(hoge.getAsString()); } } return Optional.empty(); }
  207. 207. Stupid null return VS Optional public Optional<String> findHoge() { return hogeList.stream() .filter(hoge -> hoge.isFuga()) .map(hoge -> hoge.getAsString()) .findFirst(); }
  208. 208. Stupid null return VS Optional // 安全にいろんな受け取り方が出来る Optional<String> hoge = findHoge(); hoge.ifPresent(hoge -> System.out.println(hoge. length)); String hogehoge = hoge.orElse(“値なし”); hoge.orElseThrow(() -> new RuntimeException(“値無いの許さん”));
  209. 209. Stupid null return VS Optional ・と言いつつ、Optionalは扱いが難しい ・安易にnull使うよりは良いが、むやみに使うと大 変 ・OptionalはSerializableではないし、 メンバ変数とかでいるような奴でもない ・「戻り値はOptionalにしましょう」 とかそういうところから
  210. 210. Date, Calendar VS Date and Time
  211. 211. Date,Calendar VS Date and Time // 一ヶ月後の日付取得 Date date = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.MONTH, 1); // yyyy-MM を出力 System.out.println(cal.get(Calendar.YEAR) + “-” + (cal.get(Calendar.MONTH) + 1));
  212. 212. // 一ヶ月後の日付取得 YearMonth nowYearMonth = YearMonth.now(); YearMonth nextYearMonth = nowYearMonth.plus(1, ChronoUnit.MONTHS); // yyyy-MM を出力 System.out.println(nextYearMonth.getYear() + “-” + nextYearMonth.getMonthValue()); Date,Calendar VS Date and Time
  213. 213. // 一ヶ月後の日付取得 YearMonth nowYearMonth = YearMonth.now(); YearMonth nextYearMonth = nowYearMonth.plus(1, ChronoUnit.MONTHS); // yyyy-MM を出力 System.out.println(nextYearMonth.getYear() + “-” + nextYearMonth.getMonthValue()); Date,Calendar VS Date and Time System.out.println(nextYearMonth); で良いんだけどね
  214. 214. Date,Calendar VS Date and Time // 文字列からDateを作る SimpleDateFormat sdf = new SimpleDateFormat(); sdf.applyPattern(“yyyy/MM/dd”); Date date = sdf.parse(“2015/11/28”);
  215. 215. // 文字列からDateを作る DateTimeFormatter formatter = DateTimeFormatter. ofPattern(“yyyy/MM/dd”); LocalDate date = LocalDate.parse(“2015/11/28”, formatter); ※といってもjava.util.DateとLocalDateは全く別もの。。。 Date,Calendar VS Date and Time
  216. 216. ・Optional同様、しっかり知識を持った上で広めなけ ればいけない ・IS0-8601 ・JDBCとの互換性 ・国際時間の問題(LocalDateTime, ZonedDateTime) ・DateやCalendarとの互換性の問題 Date,Calendar VS Date and Time
  217. 217. 詳細については ・櫻庭さん著「現場で使える[最新]Java SE 7/8速攻 入門」を買えば間違いなしです! (全力で他力本願) http://www.amazon.co.jp/dp/4774177385/
  218. 218. 詳細については ・あとJavaエンジニア養成読本読むと 良いです!! (全力で他力本願) http://gihyo.jp/book/2014/978-4-7741-6931-6
  219. 219. コードのマイグレーションのためには ・コードの健康チェック ・性格把握 ・コミュニケーション方法の検討 ・JUnitでのデモ、口コミ的な 情報提示 まとめ
  220. 220. ・一人で戦える範囲としては ボーイスカウトルールが限界 ・プロジェクト全体のコードマイグレーショ ンをはかるためには プログラマ一人一人の意識のマイグレー ションが必要 まとめ
  221. 221. ・自分なりに実践する中で、素振りの重要 性が分かってきた ※素振り(事前に知識をinputする、コード としてoutputする) ・基本相手を納得するには瞬発力が 必要。そのための素振り まとめ
  222. 222. ・Javaのコードは寛容です、色んな書き方が出来 る互換性を持っています ・プロジェクトの成功と並行してJavaコーディングの マイグレーションは少し優先順位が下がってしまい がちです ・しかしジワジワと効果が出てくる キャンペーンだと言えます まとめ
  223. 223. ・自分だけでなく、他の人が (例えば)Stream APIを普通に利用してい るのは嬉しい事ですし 布教活動のやりがいもあります まとめ
  224. 224. あなたから modern Java を始めましょう
  225. 225. ご静聴 ありがとうござい ました

×