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.

Example of exiting legacy system

1,837 views

Published on

新卒3年目が立ち向かった、お名前.comでの超巨大レガシーシステム脱却の事例

#jjug_ccc #ccc_a7
https://jjug-cfp.cfapps.io/submissions/9f18bae0-85ad-42e5-bd88-1c0c3ecf985a

Published in: Technology
  • Be the first to comment

Example of exiting legacy system

  1. 1. GMOインターネット株式会社 ⽥中 ⾼進 新卒3年⽬が⽴ち向かった お名前.comでの 超巨⼤レガシーシステム脱却の事例 JJUG CCC 2019 Fall #ccc_a6a
  2. 2. レガシーなシステムとは︖
  3. 3. 3 レガシーコードとは 意図した通りには動作するが、 内部のコードが複雑化し、 拡張や修正が必要な場合に 保守コストが⾼くなるコードです。 参考⽂献: https://www.oreilly.co.jp/books/9784873118864/ レガシーコードの定義 レガシーなシステムとは︖
  4. 4. 4 レガシーなシステムとは レガシーコードで出来ているシステム ・内部のコードが複雑化している ・拡張や修正時の保守コストが⾼い レガシーなシステムとは︖ レガシーなシステムの定義
  5. 5. このシステムを参考に開発お願いします
  6. 6. 確認します︕
  7. 7. ドキュメントが存在しない・・・ 独⾃実装でわかりづらい・・・ 単体テストがない。正しさが分からない︕ これがうわさのレガシーなシステム︖ ⾊々問題がありそう︕
  8. 8. レガシーなシステムから 脱却をしよう︕︕
  9. 9. 9 アジェンダ l お名前.comの紹介 l 今回のプロジェクトの概要と課題 l 問題点ごとの解決策(仕様・実装・テスト) l 結果どうなったのか
  10. 10. 10 アジェンダ l お名前.comの紹介 l 今回のプロジェクトの概要と課題 l 問題点ごとの解決策(仕様・実装・テスト) l 結果どうなったのか
  11. 11. 11 お名前.comの紹介 国内最⼤級のドメイン公式登録サービスです サービス開始から20年となります バックエンドは、Javaで動いています
  12. 12. 12 アジェンダ l お名前.comの紹介 l 今回のプロジェクトの概要と課題 l 問題点ごとの解決策(仕様・実装・テスト) l 結果どうなったのか
  13. 13. 13 今回のプロジェクト概要と課題 新卒3年⽬の⾃分に RDAPの開発を任されました
  14. 14. 14 RDAPとは︖ 今回のプロジェクト概要と課題 WHOIS RDAP後継プロトコル ドメイン 新規
  15. 15. 15 WHOISとRDAPの違い 今回のプロジェクト概要と課題 Ø ⼤きな違いとしては、データフォーマットが違う Ø RDAPでは、ユーザー⽬線となっている フォーマットの統⼀化 TEXT WHOIS JSON RDAP
  16. 16. 16 締切&仕様 ICANNの指⽰に従う必要がある 上位機関 レジストラ 締切と仕様は決められている 今回のプロジェクト概要と課題
  17. 17. 17 ドメインとは︖ ドメインとは 今回のプロジェクト概要と課題 インターネット上の住所 150.95.237.28 www.onamae.com
  18. 18. 18 WHOISとは︖ 今回のプロジェクト概要と課題 ドメインは誰が保有しているか公開しなければならない WHOIS ドメインの所有者は運⽤、管理などでトラブルが起きない ように情報を公開する義務がある
  19. 19. 19 ドメイン情報
  20. 20. 20 コンタクト情報
  21. 21. 21 WHOISとRDAP 今回のプロジェクト概要と課題 WHOIS RDAP後継プロトコル TEXTからJSONへ(RESTful) 問い合わせ結果フォーマットが統⼀
  22. 22. 22 RDAPサンプル 今回のプロジェクト概要と課題 https://rdap.gmo-onamae.com/rdap/v1/domain/onamae.com ブラウザなどで、下記のリンクにアクセス
  23. 23. 23
  24. 24. 24 今回のプロジェクト概要と課題 WHOISの実装を参考に RDAPを開発していく予定だった
  25. 25. 25 今回のプロジェクト概要と課題 しかし実装を確認すると レガシーな状態にあった
  26. 26. 26 アジェンダ l お名前.comの紹介 l 今回のプロジェクト概要と課題 l 問題点ごとの解決策(仕様・実装・テスト) l 結果どうなったのか
  27. 27. 27 問題点を確認してみた
  28. 28. 28 l 流⽤元の仕様に関するドキュメントなどがない l 複雑化している箇所があり、修正が困難 l 単体テストのテストコードが存在しない 現状の問題点 問題点ごとの解決策(仕様・実装・テスト)
  29. 29. 29 問題点ごとの解決策 (仕様編)
  30. 30. 30 Ø 流⽤元の仕様に関するドキュメントなどがない Ø ソースを⾒ても、意図がわからない Ø 微妙な実装があったとき、ソースが仕様通りな のか、バグなのか、わからない 問題点 問題点ごとの解決策(仕様)
  31. 31. 31 Ø 実装を始める前に Wikiにまとめて共有 問題点ごとの解決策(仕様) Wiki作成 共有
  32. 32. 32 GitLabでマージリクエスト時に コードの詳細な説明を加えている Gitに実装の詳細な情報を残す 問題点ごとの解決策(仕様) マージリクエストを送る リポジトリ
  33. 33. 33 問題点ごとの解決策 (実装編)
  34. 34. 34 実装を確認したところ 問題がありました 問題点ごとの解決策(実装)
  35. 35. 35 安易に修正ができなくなっている ピュアJava実装(フレームワーク未使⽤) 問題点ごとの解決策(実装)
  36. 36. 36 解決するために 問題点ごとの解決策(実装)
  37. 37. 37 採⽤アーキテクチャ選定 問題点ごとの解決策(実装)
  38. 38. 38 l JDKの選定 l フレームワークの選定 l Web API アーキテクチャの選定 採⽤アーキテクチャの選定 問題点ごとの解決策(実装)
  39. 39. 39 l JDKの選定 l フレームワークの選定 l Web API アーキテクチャの選定 JDKの選定 問題点ごとの解決策(実装)
  40. 40. 40 Ø JDKの選定基準 Ø LTSで最新versionな物 Ø AdoptOpenJDK LTS 11 Ø 選定理由 Ø 既存で動いているシステムで実績 JDKの選定 問題点ごとの解決策(実装)
  41. 41. 41 l JDKの選定 l フレームワークの選定 l Web API アーキテクチャの選定 フレームワークの選定 問題点ごとの解決策(実装)
  42. 42. 42 Ø フレームワークの選定 Ø 欲しい要件 Ø 組込Tomcat内蔵 & 標準的な実装にしたい Ø Play Framework OR Spring Boot フレームワークの選定 問題点ごとの解決策(実装)
  43. 43. 43 フレームワークの選定 問題点ごとの解決策(実装) ⾃社での導⼊実積があった事と フレームワークの ライブラリが充実していた為
  44. 44. 44 l JDKの選定 l フレームワークの選定 l Web API アーキテクチャの選定 Web API アーキテクチャの選定 問題点ごとの解決策(実装)
  45. 45. 45 Ø Web API アーキテクチャ Ø 選定要件 Ø 参考にできるガイドラインがあること Ø 疎結合な実装にできること Ø テストコードが書きやすいこと Web API アーキテクチャの選定 問題点ごとの解決策(実装)
  46. 46. 46 Ø 最終的に決まったのが Web API アーキテクチャの選定 問題点ごとの解決策(実装) 3層アーキテクチャ 参考:https://terasolunaorg.github.io/guideline/public_review/Overview/ApplicationLayering.html 参考:https://qiita.com/YutaKase6/items/7d88fa23f81366905270
  47. 47. 47 Ø 他のアーキテクチャは、検討しなかったのか Web API アーキテクチャの選定 問題点ごとの解決策(実装) ØMVC ØMVCより、強度なアーキテクチャにしたかったため ØClean Architecture Ø学習コストが⾼いので、⼯数の関係上断念
  48. 48. 48 Application Layer • Controller • Resource Infrastructure Layer • Repository Impl • Entity (JPA) Domain Layer • Domain Object • Service • Repository Interface 3層アーキテクチャ ビジネスロジック です 問題点ごとの解決策(実装) Web API アーキテクチャの選定
  49. 49. 49 Application Layer • Controller • Resource Infrastructure Layer • Repository Impl • Entity (JPA) Domain Layer • Domain Object • Service • Repository Interface 3層アーキテクチャ 依存依存 Web APIのアーキテクチャの選定 問題点ごとの解決策(実装) Web API アーキテクチャの選定
  50. 50. 50 Application Layer • Controller • Resource Infrastructure Layer • Repository Impl • Entity (JPA) Domain Layer • Domain Object • Service • Repository Interface 3層アーキテクチャ 依存しない 問題点ごとの解決策(実装) Web API アーキテクチャの選定 依存しない
  51. 51. 51 Application Layer • Controller • Resource Infrastructure Layer • Repository Impl • Entity (JPA) Domain Layer • Domain Object • Service • Repository Interface 3層アーキテクチャ 各レイヤーごとに処理が分かれている Web API アーキテクチャの選定 問題点ごとの解決策(実装)
  52. 52. 52 Ø 疎結合な実装になること OK Ø テストが書きやすいこと OK Web API アーキテクチャの選定 問題点ごとの解決策(実装)
  53. 53. 53 問題点ごとの解決策(実装) 個別の実装上の問題点
  54. 54. 54 問題点ごとの解決策(実装) l 意図が分かり難い実装 l ⽣のクエリが定義 l 設定情報が⼀部、ベタ書き l クラスの責任
  55. 55. 55 問題点ごとの解決策(実装) l 意図が分かり難い実装 l ⽣のクエリが定義 l 設定情報が⼀部、ベタ書き l クラスの責任
  56. 56. 56 意図が分かり難い実装 問題点ごとの解決策(実装) 意図が分かり難い実装 多重継承 class HogeA extends BaseA implements IBaseA abstract class BaseA extends BaseB implements Ifb abstract class BaseB { //なにもしない } BaseB baseB = (BaseB) hogeA if(baseB instancOf BaseA){ } 意味がわからない
  57. 57. 57 if(str.equals("success")){ //なにかの処理 if(name != null){ for(条件A && 条件B){ // なにかの処理 if(条件A || (条件B && 条件C)){ }else if(条件(B) && 条件(B)){ } else { } } } } 意図が分かり難い実装深いネスト 問題点ごとの解決策(実装) 意図が分かり難い実装 読みづらい
  58. 58. 58 Ø フレームワークに従った標準的な実装 Ø コードレビューの実施による属⼈化防⽌ Ø コード品質向上 意図が分かり難い実装(解決策) 問題点ごとの解決策(実装) 意図が分かり難い実装 解決策
  59. 59. 59 問題点ごとの解決策(実装) l 意図が分かり難い実装 l ⽣のクエリが定義 l 設定情報が⼀部、ベタ書き l クラスの責任
  60. 60. 60 ⽣のクエリが定義 問題点ごとの解決策(実装) // EXAMPLEテーブルのIDで検索 String EXAMPLE_SERCHID_QUERY = “SELECT * FROM EXAMPLE WHERE 〜“; ⽣のクエリが書かれている
  61. 61. 61 O/Rマッピングフレームワークの導⼊ 問題点ごとの解決策(実装) ⽣のクエリが定義(解決策)
  62. 62. 62 問題点ごとの解決策(実装) l 意図が分かり難い実装 l ⽣のクエリが定義 l 設定情報が⼀部、ベタ書き l クラスの責任
  63. 63. 63 設定情報が⼀部、ベタ書き 問題点ごとの解決策(実装) ENV_JA = “値1” ENV_US = “値2” 設定情報がプログラムにベタ書き、 外部ファイル化できていない
  64. 64. 64 設定情報が⼀部、ベタ書き(解決策) YAML 設定情報は、YAMLに統⼀ 問題点ごとの解決策(実装)
  65. 65. 65 問題点ごとの解決策(実装) l 意図が分かり難い実装 l ⽣のクエリが定義 l 設定情報が⼀部、ベタ書き l クラスの責任
  66. 66. 67 クラス 給料計算 レポート作成 所定労働時間 問題点ごとの解決策(実装) クラスの責任
  67. 67. 68 クラス 給料計算 レポート作成 所定労働時間 問題点ごとの解決策(実装) クラスの責任 修正
  68. 68. 69 クラス 給料計算 レポート作成 所定労働時間 問題点ごとの解決策(実装) クラスの責任 修正 バグ
  69. 69. 70 クラス 給料計算 レポート作成 所定労働時間 問題点ごとの解決策(実装) クラスの責任 修正 バグ ⼀つのメソッドを 修正すると 他にも影響する
  70. 70. 71 各レイヤー毎に 責任を明確化し他モジュールに 影響しない作りにしました 問題点ごとの解決策(実装) クラスの責任(解決策)
  71. 71. 72 クラス 給料計算 レポート作成 社員Data 問題点ごとの解決策(実装) クラスの責任(解決策) データ情報
  72. 72. 73 問題点ごとの解決策 (テスト編)
  73. 73. 74 Ø 修正を⾏っても、何を持って正しいとするのか分 からない Ø デグレ確認がすぐにできない 問題点 問題点ごとの解決策(テスト) 単体テストがなく、正しい結果が分らない
  74. 74. 75 Ø 今回使⽤したのは Ø Junit Ø Mockito 解決策 問題点ごとの解決策(テスト)
  75. 75. 76 アジェンダ l お名前.comの紹介 l 流⽤元として渡されたシステムがレガシーだった l 問題点ごとの解決策(仕様・実装・テスト) l 結果どうなったのか
  76. 76. 77 結果どうなったのか l 仕様(ドキュメント化) l 実装(アーキテクチャの採⽤) l テスト(単体テストの改善)
  77. 77. 78 結果どうなったのか l 仕様(ドキュメント化) l 実装(アーキテクチャの採⽤) l テスト(単体テストの改善)
  78. 78. 79 Ø ドキュメント化 Ø Wikiにドキュメント Ø 仕様が変更になったらUpdateする 仕様(ドキュメント化) 結果どうなったのか • チームで仕様を把握できるようになった • Wikiもメンテナンスが必要である
  79. 79. 80 結果どうなったのか l 仕様(ドキュメント化) l 実装(アーキテクチャの採⽤) l テスト(単体テストの改善)
  80. 80. 81 Ø 三層アーキテクチャ Ø 実装の修正をルール明確化 実装(アーキテクチャの採⽤) 結果どうなったのか 独⾃実装になりにくい
  81. 81. 82 Ø 三層アーキテクチャ Ø ⼀番は、テストが書きやすいこと 実装(アーキテクチャの採⽤) 結果どうなったのか テスタブルな実装になる
  82. 82. 83 結果どうなったのか l 仕様(ドキュメント化) l 実装(アーキテクチャの採⽤) l テスト(単体テストの改善)
  83. 83. 84 テスト(単体テストの改善) 結果どうなったのか • 開発に集中でき、テスト時間を削減 • 誰が実⾏しても、同じ粒度で検証可能 同じ粒度のテストを 実施できるのか︖ 時間が掛かる︕ 単体テストを書いたら
  84. 84. 85 テスト(単体テストの改善) 結果どうなったのか テストは、 どこまでできたのか︖
  85. 85. 86 Ø実際にテストできたのは Ø Controller & Service Ø Repository & Entity テスト(単体テストの改善) 結果どうなったのか ⼯数の関係上、 ⼆つのテストしか書けなかった。 残りは結合テストで確認。
  86. 86. 87
  87. 87. 88 しかし・・・
  88. 88. 89 Øルールの遵守やメンテナンスをしないと Øレガシー化してしまいます ルールの遵守や定期的な メンテナンスを していくことが⼤切 今後に向けて 結果どうなったのか
  89. 89. 90 今後もレガシーなコードを ⽣まないようにします︕
  90. 90. 92 [12/11(⽔)19時]渋⾕フクラス開業記念 GMO Developers Night Date: 12/11(wed) 19:30-22:00 URL: https://gmo.connpass.com/event/156321/
  91. 91. Takamichi Tanaka FaceBook https://www.facebook.com/takamichita Twitter @ttakamichi1

×